1173362Sbenjsc/*	$FreeBSD$	*/
2173362Sbenjsc
3173362Sbenjsc/*-
4173362Sbenjsc * Copyright (c) 2006,2007
5173362Sbenjsc *	Damien Bergamini <damien.bergamini@free.fr>
6173362Sbenjsc *
7173362Sbenjsc * Permission to use, copy, modify, and distribute this software for any
8173362Sbenjsc * purpose with or without fee is hereby granted, provided that the above
9173362Sbenjsc * copyright notice and this permission notice appear in all copies.
10173362Sbenjsc *
11173362Sbenjsc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12173362Sbenjsc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13173362Sbenjsc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14173362Sbenjsc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15173362Sbenjsc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16173362Sbenjsc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17173362Sbenjsc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18173362Sbenjsc */
19173362Sbenjsc#include <net80211/ieee80211_amrr.h>
20173362Sbenjsc
21173362Sbenjscstruct wpi_rx_radiotap_header {
22173362Sbenjsc	struct ieee80211_radiotap_header wr_ihdr;
23173362Sbenjsc	uint64_t	wr_tsft;
24173362Sbenjsc	uint8_t		wr_flags;
25173362Sbenjsc	uint8_t		wr_rate;
26173362Sbenjsc	uint16_t	wr_chan_freq;
27173362Sbenjsc	uint16_t	wr_chan_flags;
28173362Sbenjsc	int8_t		wr_dbm_antsignal;
29173362Sbenjsc	int8_t		wr_dbm_antnoise;
30173362Sbenjsc	uint8_t		wr_antenna;
31173362Sbenjsc};
32173362Sbenjsc
33173362Sbenjsc#define WPI_RX_RADIOTAP_PRESENT						\
34173362Sbenjsc	((1 << IEEE80211_RADIOTAP_TSFT) |				\
35173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
36173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_RATE) |				\
37173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
38173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |			\
39173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |			\
40173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_ANTENNA))
41173362Sbenjsc
42173362Sbenjscstruct wpi_tx_radiotap_header {
43173362Sbenjsc	struct ieee80211_radiotap_header wt_ihdr;
44173362Sbenjsc	uint8_t		wt_flags;
45173362Sbenjsc	uint8_t		wt_rate;
46173362Sbenjsc	uint16_t	wt_chan_freq;
47173362Sbenjsc	uint16_t	wt_chan_flags;
48173362Sbenjsc	uint8_t		wt_hwqueue;
49173362Sbenjsc};
50173362Sbenjsc
51173362Sbenjsc#define WPI_TX_RADIOTAP_PRESENT						\
52173362Sbenjsc	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
53173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_RATE) |				\
54173362Sbenjsc	 (1 << IEEE80211_RADIOTAP_CHANNEL))
55173362Sbenjsc
56173362Sbenjscstruct wpi_dma_info {
57173362Sbenjsc	bus_dma_tag_t		tag;
58173362Sbenjsc	bus_dmamap_t            map;
59177043Sthompsa	bus_addr_t		paddr;	      /* aligned p address */
60177043Sthompsa	bus_addr_t		paddr_start;  /* possibly unaligned p start*/
61177043Sthompsa	caddr_t			vaddr;	      /* aligned v address */
62177043Sthompsa	caddr_t			vaddr_start;  /* possibly unaligned v start */
63173362Sbenjsc	bus_size_t		size;
64173362Sbenjsc};
65173362Sbenjsc
66173362Sbenjscstruct wpi_tx_data {
67173362Sbenjsc	bus_dmamap_t		map;
68173362Sbenjsc	struct mbuf		*m;
69173362Sbenjsc	struct ieee80211_node	*ni;
70173362Sbenjsc};
71173362Sbenjsc
72173362Sbenjscstruct wpi_tx_ring {
73173362Sbenjsc	struct wpi_dma_info	desc_dma;
74173362Sbenjsc	struct wpi_dma_info	cmd_dma;
75173362Sbenjsc	struct wpi_tx_desc	*desc;
76173362Sbenjsc	struct wpi_tx_cmd	*cmd;
77173362Sbenjsc	struct wpi_tx_data	*data;
78173362Sbenjsc	bus_dma_tag_t		data_dmat;
79173362Sbenjsc	int			qid;
80173362Sbenjsc	int			count;
81173362Sbenjsc	int			queued;
82173362Sbenjsc	int			cur;
83173362Sbenjsc};
84173362Sbenjsc
85173362Sbenjsc#define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 )
86173362Sbenjsc
87173362Sbenjscstruct wpi_rx_data {
88177043Sthompsa	bus_dmamap_t		map;
89177043Sthompsa	struct mbuf		*m;
90173362Sbenjsc};
91173362Sbenjsc
92173362Sbenjscstruct wpi_rx_ring {
93173362Sbenjsc	struct wpi_dma_info	desc_dma;
94173362Sbenjsc	uint32_t		*desc;
95173362Sbenjsc	struct wpi_rx_data	data[WPI_RX_RING_COUNT];
96177043Sthompsa	bus_dma_tag_t		data_dmat;
97173362Sbenjsc	int			cur;
98173362Sbenjsc};
99173362Sbenjsc
100173362Sbenjscstruct wpi_amrr {
101173362Sbenjsc	struct	ieee80211_node ni;	/* must be the first */
102173362Sbenjsc	int	txcnt;
103173362Sbenjsc	int	retrycnt;
104173362Sbenjsc	int	success;
105173362Sbenjsc	int	success_threshold;
106173362Sbenjsc	int	recovery;
107173362Sbenjsc};
108173362Sbenjsc
109173362Sbenjscstruct wpi_power_sample {
110173362Sbenjsc	uint8_t	index;
111173362Sbenjsc	int8_t	power;
112173362Sbenjsc};
113173362Sbenjsc
114173362Sbenjscstruct wpi_power_group {
115173362Sbenjsc#define WPI_SAMPLES_COUNT	5
116178354Ssam	struct wpi_power_sample samples[WPI_SAMPLES_COUNT];
117178354Ssam	uint8_t	chan;
118178354Ssam	int8_t	maxpwr;
119178354Ssam	int16_t	temp;
120173362Sbenjsc};
121173362Sbenjsc
122178354Ssamstruct wpi_vap {
123178354Ssam	struct ieee80211vap	vap;
124178354Ssam
125178354Ssam	int			(*newstate)(struct ieee80211vap *,
126178354Ssam				    enum ieee80211_state, int);
127178354Ssam};
128178354Ssam#define	WPI_VAP(vap)	((struct wpi_vap *)(vap))
129178354Ssam
130173362Sbenjscstruct wpi_softc {
131173362Sbenjsc	device_t		sc_dev;
132173362Sbenjsc	struct ifnet		*sc_ifp;
133173362Sbenjsc	struct mtx		sc_mtx;
134173362Sbenjsc
135173362Sbenjsc	/* Flags indicating the current state the driver
136173362Sbenjsc	 * expects the hardware to be in
137173362Sbenjsc	 */
138173362Sbenjsc	uint32_t		flags;
139173362Sbenjsc#define WPI_FLAG_HW_RADIO_OFF	(1 << 0)
140191746Sthompsa#define WPI_FLAG_BUSY		(1 << 1)
141191746Sthompsa#define WPI_FLAG_AUTH		(1 << 2)
142173362Sbenjsc
143173362Sbenjsc	/* shared area */
144173362Sbenjsc	struct wpi_dma_info	shared_dma;
145173362Sbenjsc	struct wpi_shared	*shared;
146173362Sbenjsc
147173362Sbenjsc	struct wpi_tx_ring	txq[WME_NUM_AC];
148173362Sbenjsc	struct wpi_tx_ring	cmdq;
149173362Sbenjsc	struct wpi_rx_ring	rxq;
150173362Sbenjsc
151173362Sbenjsc	/* TX Thermal Callibration */
152173362Sbenjsc	struct callout		calib_to;
153173362Sbenjsc	int			calib_cnt;
154173362Sbenjsc
155173362Sbenjsc	/* Watch dog timer */
156173362Sbenjsc	struct callout		watchdog_to;
157177043Sthompsa	/* Hardware switch polling timer */
158177043Sthompsa	struct callout		hwswitch_to;
159173362Sbenjsc
160173362Sbenjsc	struct resource		*irq;
161173362Sbenjsc	struct resource		*mem;
162173362Sbenjsc	bus_space_tag_t		sc_st;
163173362Sbenjsc	bus_space_handle_t	sc_sh;
164173362Sbenjsc	void			*sc_ih;
165173362Sbenjsc
166173362Sbenjsc	struct wpi_config	config;
167173362Sbenjsc	int			temp;
168173362Sbenjsc
169173362Sbenjsc
170173362Sbenjsc	int			sc_tx_timer;
171177043Sthompsa	int			sc_scan_timer;
172173362Sbenjsc
173173362Sbenjsc	struct bpf_if		*sc_drvbpf;
174173362Sbenjsc
175173362Sbenjsc	struct wpi_rx_radiotap_header sc_rxtap;
176173362Sbenjsc	struct wpi_tx_radiotap_header sc_txtap;
177173362Sbenjsc
178173362Sbenjsc	/* firmware image */
179173362Sbenjsc	const struct firmware	*fw_fp;
180173362Sbenjsc
181173362Sbenjsc	/* firmware DMA transfer */
182173362Sbenjsc	struct wpi_dma_info	fw_dma;
183173362Sbenjsc
184178354Ssam	/* Tasks used by the driver */
185178354Ssam	struct task		sc_restarttask;	/* reset firmware task */
186191746Sthompsa	struct task		sc_radiotask;	/* reset rf task */
187173362Sbenjsc
188173362Sbenjsc       /* Eeprom info */
189173362Sbenjsc	uint8_t			cap;
190173362Sbenjsc	uint16_t		rev;
191173362Sbenjsc	uint8_t			type;
192173362Sbenjsc	struct wpi_power_group	groups[WPI_POWER_GROUPS_COUNT];
193173362Sbenjsc	int8_t			maxpwr[IEEE80211_CHAN_MAX];
194178354Ssam	char			domain[4];	/*reglatory domain XXX */
195173362Sbenjsc};
196173362Sbenjsc#define WPI_LOCK_INIT(_sc) \
197173362Sbenjsc	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
198173362Sbenjsc            MTX_NETWORK_LOCK, MTX_DEF)
199177043Sthompsa#define WPI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
200177043Sthompsa#define WPI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
201177043Sthompsa#define WPI_LOCK_ASSERT(sc)     mtx_assert(&(sc)->sc_mtx, MA_OWNED)
202177043Sthompsa#define WPI_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
203