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
20173362Sbenjsc#define WPI_TX_RING_COUNT	256
21173362Sbenjsc#define WPI_CMD_RING_COUNT	256
22173362Sbenjsc#define WPI_RX_RING_COUNT	64
23173362Sbenjsc
24173362Sbenjsc/*
25173362Sbenjsc * Rings must be aligned on a 16K boundary.
26173362Sbenjsc */
27173362Sbenjsc#define WPI_RING_DMA_ALIGN	0x4000
28173362Sbenjsc
29173362Sbenjsc/* maximum scatter/gather */
30173362Sbenjsc#define WPI_MAX_SCATTER	4
31173362Sbenjsc
32173362Sbenjsc/* maximum Rx buffer size */
33173362Sbenjsc#define WPI_RBUF_SIZE ( 3 * 1024 ) /* XXX 3000 but must be aligned */
34173362Sbenjsc
35173362Sbenjsc/*
36173362Sbenjsc * Control and status registers.
37173362Sbenjsc */
38173362Sbenjsc#define WPI_HWCONFIG		0x000
39173362Sbenjsc#define WPI_INTR		0x008
40173362Sbenjsc#define WPI_MASK		0x00c
41173362Sbenjsc#define WPI_INTR_STATUS		0x010
42173362Sbenjsc#define WPI_GPIO_STATUS		0x018
43173362Sbenjsc#define WPI_RESET		0x020
44173362Sbenjsc#define WPI_GPIO_CTL		0x024
45173362Sbenjsc#define WPI_EEPROM_CTL		0x02c
46173362Sbenjsc#define WPI_EEPROM_STATUS	0x030
47177043Sthompsa#define WPI_UCODE_SET		0x058
48173362Sbenjsc#define WPI_UCODE_CLR		0x05c
49173362Sbenjsc#define WPI_TEMPERATURE		0x060
50173362Sbenjsc#define WPI_CHICKEN		0x100
51173362Sbenjsc#define WPI_PLL_CTL		0x20c
52173362Sbenjsc#define WPI_WRITE_MEM_ADDR	0x444
53173362Sbenjsc#define WPI_READ_MEM_ADDR	0x448
54173362Sbenjsc#define WPI_WRITE_MEM_DATA	0x44c
55173362Sbenjsc#define WPI_READ_MEM_DATA	0x450
56173362Sbenjsc#define WPI_TX_WIDX		0x460
57173362Sbenjsc#define WPI_TX_CTL(qid)		(0x940 + (qid) * 8)
58173362Sbenjsc#define WPI_TX_BASE(qid)	(0x944 + (qid) * 8)
59173362Sbenjsc#define WPI_TX_DESC(qid)	(0x980 + (qid) * 80)
60173362Sbenjsc#define WPI_RX_CONFIG		0xc00
61173362Sbenjsc#define WPI_RX_BASE		0xc04
62173362Sbenjsc#define WPI_RX_WIDX		0xc20
63173362Sbenjsc#define WPI_RX_RIDX_PTR		0xc24
64173362Sbenjsc#define WPI_RX_CTL		0xcc0
65173362Sbenjsc#define WPI_RX_STATUS		0xcc4
66173362Sbenjsc#define WPI_TX_CONFIG(qid)	(0xd00 + (qid) * 32)
67173362Sbenjsc#define WPI_TX_CREDIT(qid)	(0xd04 + (qid) * 32)
68173362Sbenjsc#define WPI_TX_STATE(qid)	(0xd08 + (qid) * 32)
69173362Sbenjsc#define WPI_TX_BASE_PTR		0xe80
70173362Sbenjsc#define WPI_MSG_CONFIG		0xe88
71173362Sbenjsc#define WPI_TX_STATUS		0xe90
72173362Sbenjsc
73173362Sbenjsc
74173362Sbenjsc/*
75173362Sbenjsc * NIC internal memory offsets.
76173362Sbenjsc */
77173362Sbenjsc#define WPI_MEM_MODE		0x2e00
78173362Sbenjsc#define WPI_MEM_RA		0x2e04
79173362Sbenjsc#define WPI_MEM_TXCFG		0x2e10
80173362Sbenjsc#define WPI_MEM_MAGIC4		0x2e14
81173362Sbenjsc#define WPI_MEM_MAGIC5		0x2e20
82173362Sbenjsc#define WPI_MEM_BYPASS1		0x2e2c
83173362Sbenjsc#define WPI_MEM_BYPASS2		0x2e30
84173362Sbenjsc#define WPI_MEM_CLOCK1		0x3004
85173362Sbenjsc#define WPI_MEM_CLOCK2		0x3008
86173362Sbenjsc#define WPI_MEM_POWER		0x300c
87173362Sbenjsc#define WPI_MEM_PCIDEV		0x3010
88173362Sbenjsc#define WPI_MEM_HW_RADIO_OFF	0x3014
89173362Sbenjsc#define WPI_MEM_UCODE_CTL	0x3400
90173362Sbenjsc#define WPI_MEM_UCODE_SRC	0x3404
91173362Sbenjsc#define WPI_MEM_UCODE_DST	0x3408
92173362Sbenjsc#define WPI_MEM_UCODE_SIZE	0x340c
93173362Sbenjsc#define WPI_MEM_UCODE_BASE	0x3800
94173362Sbenjsc
95173362Sbenjsc#define WPI_MEM_TEXT_BASE	0x3490
96173362Sbenjsc#define WPI_MEM_TEXT_SIZE	0x3494
97173362Sbenjsc#define WPI_MEM_DATA_BASE	0x3498
98173362Sbenjsc#define WPI_MEM_DATA_SIZE	0x349c
99173362Sbenjsc
100173362Sbenjsc
101173362Sbenjsc/* possible flags for register WPI_HWCONFIG */
102173362Sbenjsc#define WPI_HW_ALM_MB	(1 << 8)
103173362Sbenjsc#define WPI_HW_ALM_MM	(1 << 9)
104173362Sbenjsc#define WPI_HW_SKU_MRC	(1 << 10)
105173362Sbenjsc#define WPI_HW_REV_D	(1 << 11)
106173362Sbenjsc#define WPI_HW_TYPE_B	(1 << 12)
107173362Sbenjsc
108173362Sbenjsc/* possible flags for registers WPI_READ_MEM_ADDR/WPI_WRITE_MEM_ADDR */
109173362Sbenjsc#define WPI_MEM_4	((sizeof (uint32_t) - 1) << 24)
110173362Sbenjsc
111173362Sbenjsc/* possible values for WPI_MEM_UCODE_DST */
112173362Sbenjsc#define WPI_FW_TEXT	0x00000000
113173362Sbenjsc
114173362Sbenjsc/* possible flags for WPI_GPIO_STATUS */
115173362Sbenjsc#define WPI_POWERED		(1 << 9)
116173362Sbenjsc
117173362Sbenjsc/* possible flags for register WPI_RESET */
118173362Sbenjsc#define WPI_NEVO_RESET		(1 << 0)
119173362Sbenjsc#define WPI_SW_RESET		(1 << 7)
120173362Sbenjsc#define WPI_MASTER_DISABLED	(1 << 8)
121173362Sbenjsc#define WPI_STOP_MASTER		(1 << 9)
122173362Sbenjsc
123173362Sbenjsc/* possible flags for register WPI_GPIO_CTL */
124173362Sbenjsc#define WPI_GPIO_CLOCK		(1 << 0)
125173362Sbenjsc#define WPI_GPIO_INIT		(1 << 2)
126173362Sbenjsc#define WPI_GPIO_MAC		(1 << 3)
127173362Sbenjsc#define WPI_GPIO_SLEEP		(1 << 4)
128173362Sbenjsc#define WPI_GPIO_PWR_STATUS	0x07000000
129173362Sbenjsc#define WPI_GPIO_PWR_SLEEP	(4 << 24)
130173362Sbenjsc
131173362Sbenjsc/* possible flags for register WPI_CHICKEN */
132173362Sbenjsc#define WPI_CHICKEN_RXNOLOS	(1 << 23)
133173362Sbenjsc
134173362Sbenjsc/* possible flags for register WPI_PLL_CTL */
135173362Sbenjsc#define WPI_PLL_INIT		(1 << 24)
136173362Sbenjsc
137173362Sbenjsc/* possible flags for register WPI_UCODE_CLR */
138173362Sbenjsc#define WPI_RADIO_OFF		(1 << 1)
139173362Sbenjsc#define WPI_DISABLE_CMD		(1 << 2)
140173362Sbenjsc
141173362Sbenjsc/* possible flags for WPI_RX_STATUS */
142173362Sbenjsc#define	WPI_RX_IDLE	(1 << 24)
143173362Sbenjsc
144173362Sbenjsc/* possible flags for register WPI_UC_CTL */
145173362Sbenjsc#define WPI_UC_ENABLE	(1 << 30)
146261455Seadler#define WPI_UC_RUN	(1U << 31)
147173362Sbenjsc
148173362Sbenjsc/* possible flags for register WPI_INTR_CSR */
149173362Sbenjsc#define WPI_ALIVE_INTR	(1 << 0)
150173362Sbenjsc#define WPI_WAKEUP_INTR	(1 << 1)
151173362Sbenjsc#define WPI_SW_ERROR	(1 << 25)
152173362Sbenjsc#define WPI_TX_INTR	(1 << 27)
153173362Sbenjsc#define WPI_HW_ERROR	(1 << 29)
154261455Seadler#define WPI_RX_INTR	(1U << 31)
155173362Sbenjsc
156173362Sbenjsc#define WPI_INTR_MASK							\
157173362Sbenjsc	(WPI_SW_ERROR | WPI_HW_ERROR | WPI_TX_INTR | WPI_RX_INTR |	\
158173362Sbenjsc	 WPI_ALIVE_INTR | WPI_WAKEUP_INTR)
159173362Sbenjsc
160173362Sbenjsc/* possible flags for register WPI_TX_STATUS */
161173362Sbenjsc#define WPI_TX_IDLE(qid)	(1 << ((qid) + 24) | 1 << ((qid) + 16))
162173362Sbenjsc
163173362Sbenjsc/* possible flags for register WPI_EEPROM_CTL */
164173362Sbenjsc#define WPI_EEPROM_READY	(1 << 0)
165173362Sbenjsc
166173362Sbenjsc/* possible flags for register WPI_EEPROM_STATUS */
167173362Sbenjsc#define WPI_EEPROM_VERSION	0x00000007
168173362Sbenjsc#define WPI_EEPROM_LOCKED	0x00000180
169173362Sbenjsc
170173362Sbenjsc
171173362Sbenjscstruct wpi_shared {
172173362Sbenjsc	uint32_t	txbase[8];
173173362Sbenjsc	uint32_t	next;
174173362Sbenjsc	uint32_t	reserved[2];
175173362Sbenjsc} __packed;
176173362Sbenjsc
177173362Sbenjsc#define WPI_MAX_SEG_LEN	65520
178173362Sbenjscstruct wpi_tx_desc {
179173362Sbenjsc	uint32_t	flags;
180173362Sbenjsc#define WPI_PAD32(x)	(roundup2(x, 4) - (x))
181173362Sbenjsc
182173362Sbenjsc	struct {
183173362Sbenjsc		uint32_t	addr;
184173362Sbenjsc		uint32_t	len;
185173362Sbenjsc	} __attribute__((__packed__))	segs[WPI_MAX_SCATTER];
186173362Sbenjsc	uint8_t		reserved[28];
187173362Sbenjsc} __packed;
188173362Sbenjsc
189173362Sbenjscstruct wpi_tx_stat {
190173362Sbenjsc	uint8_t		nrts;
191173362Sbenjsc	uint8_t		ntries;
192173362Sbenjsc	uint8_t		nkill;
193173362Sbenjsc	uint8_t		rate;
194173362Sbenjsc	uint32_t	duration;
195173362Sbenjsc	uint32_t	status;
196173362Sbenjsc} __packed;
197173362Sbenjsc
198173362Sbenjscstruct wpi_rx_desc {
199173362Sbenjsc	uint32_t	len;
200173362Sbenjsc	uint8_t		type;
201173362Sbenjsc#define WPI_UC_READY		  1
202173362Sbenjsc#define WPI_RX_DONE		 27
203173362Sbenjsc#define WPI_TX_DONE		 28
204173362Sbenjsc#define WPI_START_SCAN		130
205177043Sthompsa#define WPI_SCAN_RESULTS	131
206173362Sbenjsc#define WPI_STOP_SCAN		132
207173362Sbenjsc#define WPI_STATE_CHANGED	161
208173976Sbenjsc#define WPI_MISSED_BEACON	162
209173362Sbenjsc
210173362Sbenjsc	uint8_t		flags;
211173362Sbenjsc	uint8_t		idx;
212173362Sbenjsc	uint8_t		qid;
213173362Sbenjsc} __packed;
214173362Sbenjsc
215173362Sbenjscstruct wpi_rx_stat {
216173362Sbenjsc	uint8_t		len;
217173362Sbenjsc#define WPI_STAT_MAXLEN	20
218173362Sbenjsc
219173362Sbenjsc	uint8_t		id;
220173362Sbenjsc	uint8_t		rssi;	/* received signal strength */
221173362Sbenjsc#define WPI_RSSI_OFFSET	95
222173362Sbenjsc
223173362Sbenjsc	uint8_t		agc;	/* access gain control */
224173362Sbenjsc	uint16_t	signal;
225173362Sbenjsc	uint16_t	noise;
226173362Sbenjsc} __packed;
227173362Sbenjsc
228173362Sbenjscstruct wpi_rx_head {
229173362Sbenjsc	uint16_t	chan;
230173362Sbenjsc	uint16_t	flags;
231173362Sbenjsc	uint8_t		reserved;
232173362Sbenjsc	uint8_t		rate;
233173362Sbenjsc	uint16_t	len;
234173362Sbenjsc} __packed;
235173362Sbenjsc
236173362Sbenjscstruct wpi_rx_tail {
237173362Sbenjsc	uint32_t	flags;
238173362Sbenjsc#define WPI_RX_NO_CRC_ERR	(1 << 0)
239173362Sbenjsc#define WPI_RX_NO_OVFL_ERR	(1 << 1)
240173362Sbenjsc/* shortcut for the above */
241173362Sbenjsc#define WPI_RX_NOERROR		(WPI_RX_NO_CRC_ERR | WPI_RX_NO_OVFL_ERR)
242173362Sbenjsc	uint64_t	tstamp;
243173362Sbenjsc	uint32_t	tbeacon;
244173362Sbenjsc} __packed;
245173362Sbenjsc
246173362Sbenjscstruct wpi_tx_cmd {
247173362Sbenjsc	uint8_t	code;
248173362Sbenjsc#define WPI_CMD_CONFIGURE	 16
249173362Sbenjsc#define WPI_CMD_ASSOCIATE	 17
250173362Sbenjsc#define WPI_CMD_SET_WME          19
251173362Sbenjsc#define WPI_CMD_TSF		 20
252173362Sbenjsc#define WPI_CMD_ADD_NODE	 24
253173362Sbenjsc#define WPI_CMD_TX_DATA		 28
254173362Sbenjsc#define WPI_CMD_MRR_SETUP	 71
255173362Sbenjsc#define WPI_CMD_SET_LED		 72
256173362Sbenjsc#define WPI_CMD_SET_POWER_MODE	119
257173362Sbenjsc#define WPI_CMD_SCAN		128
258173362Sbenjsc#define WPI_CMD_SET_BEACON	145
259173362Sbenjsc#define WPI_CMD_TXPOWER		151
260173362Sbenjsc#define WPI_CMD_BLUETOOTH	155
261173362Sbenjsc
262173362Sbenjsc	uint8_t	flags;
263173362Sbenjsc	uint8_t	idx;
264173362Sbenjsc	uint8_t	qid;
265173362Sbenjsc	uint8_t	data[360];
266173362Sbenjsc} __packed;
267173362Sbenjsc
268173362Sbenjsc/* structure for WPI_CMD_CONFIGURE */
269173362Sbenjscstruct wpi_config {
270173362Sbenjsc	uint8_t		myaddr[IEEE80211_ADDR_LEN];
271173362Sbenjsc	uint16_t	reserved1;
272173362Sbenjsc	uint8_t		bssid[IEEE80211_ADDR_LEN];
273173362Sbenjsc	uint16_t	reserved2;
274173362Sbenjsc	uint8_t		wlap_bssid_addr[6];
275173362Sbenjsc	uint16_t	reserved3;
276173362Sbenjsc	uint8_t		mode;
277173362Sbenjsc#define WPI_MODE_HOSTAP		1
278173362Sbenjsc#define WPI_MODE_STA		3
279173362Sbenjsc#define WPI_MODE_IBSS		4
280173362Sbenjsc#define WPI_MODE_MONITOR	6
281173362Sbenjsc
282173362Sbenjsc	uint8_t		air_propogation;
283173362Sbenjsc	uint16_t	reserved4;
284173362Sbenjsc	uint8_t		ofdm_mask;
285173362Sbenjsc	uint8_t		cck_mask;
286173362Sbenjsc	uint16_t	associd;
287173362Sbenjsc	uint32_t	flags;
288173362Sbenjsc#define WPI_CONFIG_24GHZ	(1 << 0)
289173362Sbenjsc#define WPI_CONFIG_CCK		(1 << 1)
290173362Sbenjsc#define WPI_CONFIG_AUTO		(1 << 2)
291173362Sbenjsc#define WPI_CONFIG_SHSLOT	(1 << 4)
292173362Sbenjsc#define WPI_CONFIG_SHPREAMBLE	(1 << 5)
293173362Sbenjsc#define WPI_CONFIG_NODIVERSITY	(1 << 7)
294173362Sbenjsc#define WPI_CONFIG_ANTENNA_A	(1 << 8)
295173362Sbenjsc#define WPI_CONFIG_ANTENNA_B	(1 << 9)
296173362Sbenjsc#define WPI_CONFIG_TSF		(1 << 15)
297173362Sbenjsc
298173362Sbenjsc	uint32_t	filter;
299173362Sbenjsc#define WPI_FILTER_PROMISC	(1 << 0)
300173362Sbenjsc#define WPI_FILTER_CTL		(1 << 1)
301173362Sbenjsc#define WPI_FILTER_MULTICAST	(1 << 2)
302173362Sbenjsc#define WPI_FILTER_NODECRYPT	(1 << 3)
303173362Sbenjsc#define WPI_FILTER_BSS		(1 << 5)
304173362Sbenjsc#define WPI_FILTER_BEACON	(1 << 6)
305173362Sbenjsc
306173362Sbenjsc	uint8_t		chan;
307173362Sbenjsc	uint16_t	reserved6;
308173362Sbenjsc} __packed;
309173362Sbenjsc
310173362Sbenjsc/* structure for command WPI_CMD_ASSOCIATE */
311173362Sbenjscstruct wpi_assoc {
312173362Sbenjsc	uint32_t	flags;
313173362Sbenjsc	uint32_t	filter;
314173362Sbenjsc	uint8_t		ofdm_mask;
315173362Sbenjsc	uint8_t		cck_mask;
316173362Sbenjsc	uint16_t	reserved;
317173362Sbenjsc} __packed;
318173362Sbenjsc
319173362Sbenjsc/* structure for command WPI_CMD_SET_WME */
320173362Sbenjscstruct wpi_wme_setup {
321173362Sbenjsc	uint32_t	flags;
322173362Sbenjsc	struct {
323173362Sbenjsc		uint16_t	cwmin;
324173362Sbenjsc		uint16_t	cwmax;
325173362Sbenjsc		uint8_t		aifsn;
326173362Sbenjsc		uint8_t		reserved;
327173362Sbenjsc		uint16_t	txop;
328173362Sbenjsc	} __packed	ac[WME_NUM_AC];
329173362Sbenjsc} __packed;
330173362Sbenjsc
331173362Sbenjsc/* structure for command WPI_CMD_TSF */
332173362Sbenjscstruct wpi_cmd_tsf {
333173362Sbenjsc	uint64_t	tstamp;
334173362Sbenjsc	uint16_t	bintval;
335173362Sbenjsc	uint16_t	atim;
336173362Sbenjsc	uint32_t	binitval;
337173362Sbenjsc	uint16_t	lintval;
338173362Sbenjsc	uint16_t	reserved;
339173362Sbenjsc} __packed;
340173362Sbenjsc
341173362Sbenjsc/* structure for WPI_CMD_ADD_NODE */
342173362Sbenjscstruct wpi_node_info {
343173362Sbenjsc	uint8_t		control;
344173362Sbenjsc#define WPI_NODE_UPDATE	(1 << 0)
345173362Sbenjsc
346173362Sbenjsc	uint8_t		reserved1[3];
347173362Sbenjsc	uint8_t		bssid[IEEE80211_ADDR_LEN];
348173362Sbenjsc	uint16_t	reserved2;
349173362Sbenjsc	uint8_t		id;
350173362Sbenjsc#define WPI_ID_BSS		0
351173362Sbenjsc#define WPI_ID_BROADCAST	24
352173362Sbenjsc
353173362Sbenjsc	uint8_t		flags;
354173362Sbenjsc	uint16_t	reserved3;
355173362Sbenjsc	uint16_t	key_flags;
356173362Sbenjsc	uint8_t		tkip;
357173362Sbenjsc	uint8_t		reserved4;
358173362Sbenjsc	uint16_t	ttak[5];
359173362Sbenjsc	uint16_t	reserved5;
360173362Sbenjsc	uint8_t		key[IEEE80211_KEYBUF_SIZE];
361173362Sbenjsc	uint32_t	action;
362173362Sbenjsc#define WPI_ACTION_SET_RATE	4
363173362Sbenjsc	uint32_t	mask;
364173362Sbenjsc	uint16_t	tid;
365173362Sbenjsc	uint8_t		rate;
366173362Sbenjsc	uint8_t		antenna;
367173362Sbenjsc#define WPI_ANTENNA_A	(1<<6)
368173362Sbenjsc#define WPI_ANTENNA_B	(1<<7)
369173362Sbenjsc#define WPI_ANTENNA_BOTH	(WPI_ANTENNA_A|WPI_ANTENNA_B)
370173362Sbenjsc	uint8_t		add_imm;
371173362Sbenjsc	uint8_t		del_imm;
372173362Sbenjsc	uint16_t	add_imm_start;
373173362Sbenjsc} __packed;
374173362Sbenjsc
375173362Sbenjsc/* structure for command WPI_CMD_TX_DATA */
376173362Sbenjscstruct wpi_cmd_data {
377173362Sbenjsc	uint16_t	len;
378173362Sbenjsc	uint16_t	lnext;
379173362Sbenjsc	uint32_t	flags;
380173362Sbenjsc#define WPI_TX_NEED_RTS		(1 <<  1)
381173362Sbenjsc#define WPI_TX_NEED_CTS         (1 <<  2)
382173362Sbenjsc#define WPI_TX_NEED_ACK		(1 <<  3)
383173362Sbenjsc#define WPI_TX_FULL_TXOP	(1 <<  7)
384173362Sbenjsc#define WPI_TX_BT_DISABLE	(1 << 12) /* bluetooth coexistence */
385173362Sbenjsc#define WPI_TX_AUTO_SEQ		(1 << 13)
386173362Sbenjsc#define WPI_TX_INSERT_TSTAMP	(1 << 16)
387173362Sbenjsc
388173362Sbenjsc	uint8_t		rate;
389173362Sbenjsc	uint8_t		id;
390173362Sbenjsc	uint8_t		tid;
391173362Sbenjsc	uint8_t		security;
392173362Sbenjsc	uint8_t		key[IEEE80211_KEYBUF_SIZE];
393173362Sbenjsc	uint8_t		tkip[IEEE80211_WEP_MICLEN];
394173362Sbenjsc	uint32_t	fnext;
395173362Sbenjsc	uint32_t	lifetime;
396173362Sbenjsc#define WPI_LIFETIME_INFINITE	0xffffffff
397173362Sbenjsc	uint8_t		ofdm_mask;
398173362Sbenjsc	uint8_t		cck_mask;
399173362Sbenjsc	uint8_t		rts_ntries;
400173362Sbenjsc	uint8_t		data_ntries;
401173362Sbenjsc	uint16_t	timeout;
402173362Sbenjsc	uint16_t	txop;
403173362Sbenjsc	struct          ieee80211_frame wh;
404173362Sbenjsc} __packed;
405173362Sbenjsc
406173362Sbenjsc/* structure for command WPI_CMD_SET_BEACON */
407173362Sbenjscstruct wpi_cmd_beacon {
408173362Sbenjsc	uint16_t	len;
409173362Sbenjsc	uint16_t	reserved1;
410173362Sbenjsc	uint32_t	flags;	/* same as wpi_cmd_data */
411173362Sbenjsc	uint8_t		rate;
412173362Sbenjsc	uint8_t		id;
413173362Sbenjsc	uint8_t		reserved2[30];
414173362Sbenjsc	uint32_t	lifetime;
415173362Sbenjsc	uint8_t		ofdm_mask;
416173362Sbenjsc	uint8_t		cck_mask;
417173362Sbenjsc	uint16_t	reserved3[3];
418173362Sbenjsc	uint16_t	tim;
419173362Sbenjsc	uint8_t		timsz;
420173362Sbenjsc	uint8_t		reserved4;
421173362Sbenjsc	struct		ieee80211_frame wh;
422173362Sbenjsc} __packed;
423173362Sbenjsc
424173976Sbenjsc/* structure for notification WPI_MISSED_BEACON */
425173976Sbenjscstruct wpi_missed_beacon {
426173976Sbenjsc    uint32_t consecutive;
427173976Sbenjsc    uint32_t total;
428173976Sbenjsc    uint32_t expected;
429173976Sbenjsc    uint32_t received;
430173976Sbenjsc} __packed;
431173976Sbenjsc
432173976Sbenjsc
433173362Sbenjsc/* structure for WPI_CMD_MRR_SETUP */
434173362Sbenjscstruct wpi_mrr_setup {
435173362Sbenjsc	uint8_t	which;
436173362Sbenjsc#define WPI_MRR_CTL	0
437173362Sbenjsc#define WPI_MRR_DATA	1
438173362Sbenjsc
439173362Sbenjsc	uint8_t		reserved[3];
440173362Sbenjsc
441173362Sbenjsc	struct {
442173362Sbenjsc		uint8_t	signal;
443173362Sbenjsc		uint8_t	flags;
444173362Sbenjsc		uint8_t	ntries;
445173362Sbenjsc		uint8_t	next;
446173362Sbenjsc#define WPI_OFDM6	0
447173362Sbenjsc#define WPI_OFDM54	7
448173362Sbenjsc#define WPI_CCK1	8
449173362Sbenjsc#define WPI_CCK2	9
450173362Sbenjsc#define WPI_CCK11	11
451173362Sbenjsc
452173362Sbenjsc	} __attribute__((__packed__))	rates[WPI_CCK11 + 1];
453173362Sbenjsc} __packed;
454173362Sbenjsc
455173362Sbenjsc/* structure for WPI_CMD_SET_LED */
456173362Sbenjscstruct wpi_cmd_led {
457173362Sbenjsc	uint32_t	unit;	/* multiplier (in usecs) */
458173362Sbenjsc	uint8_t		which;
459173362Sbenjsc#define WPI_LED_ACTIVITY	1
460173362Sbenjsc#define WPI_LED_LINK		2
461173362Sbenjsc
462173362Sbenjsc	uint8_t		off;
463173362Sbenjsc	uint8_t		on;
464173362Sbenjsc	uint8_t		reserved;
465173362Sbenjsc} __packed;
466173362Sbenjsc
467173362Sbenjsc/* structure for WPI_CMD_SET_POWER_MODE */
468173362Sbenjscstruct wpi_power {
469173362Sbenjsc	uint32_t	flags;
470173362Sbenjsc#define WPI_POWER_CAM	0	/* constantly awake mode */
471173362Sbenjsc	uint32_t	rx_timeout;
472173362Sbenjsc	uint32_t	tx_timeout;
473173362Sbenjsc	uint32_t	sleep[5];
474173362Sbenjsc} __packed;
475173362Sbenjsc
476173362Sbenjsc/* structure for command WPI_CMD_SCAN */
477173362Sbenjscstruct wpi_scan_hdr {
478173362Sbenjsc	uint16_t	len;
479173362Sbenjsc	uint8_t		reserved1;
480173362Sbenjsc	uint8_t		nchan;
481173362Sbenjsc	uint16_t	quiet;
482173362Sbenjsc	uint16_t	threshold;
483173362Sbenjsc	uint16_t	promotion;
484173362Sbenjsc	uint16_t	reserved2;
485173362Sbenjsc	uint32_t	maxtimeout;
486173362Sbenjsc	uint32_t	suspend;
487173362Sbenjsc	uint32_t	flags;
488173362Sbenjsc	uint32_t	filter;
489173362Sbenjsc
490173362Sbenjscstruct {
491173362Sbenjsc	uint16_t	len;
492173362Sbenjsc	uint16_t	lnext;
493173362Sbenjsc	uint32_t	flags;
494173362Sbenjsc	uint8_t		rate;
495173362Sbenjsc	uint8_t		id;
496173362Sbenjsc	uint8_t		tid;
497173362Sbenjsc	uint8_t		security;
498173362Sbenjsc	uint8_t		key[IEEE80211_KEYBUF_SIZE];
499173362Sbenjsc	uint8_t		tkip[IEEE80211_WEP_MICLEN];
500173362Sbenjsc	uint32_t	fnext;
501173362Sbenjsc	uint32_t	lifetime;
502173362Sbenjsc	uint8_t		ofdm_mask;
503173362Sbenjsc	uint8_t		cck_mask;
504173362Sbenjsc	uint8_t		rts_ntries;
505173362Sbenjsc	uint8_t		data_ntries;
506173362Sbenjsc	uint16_t	timeout;
507173362Sbenjsc	uint16_t	txop;
508173362Sbenjsc}	tx __attribute__((__packed__));
509173362Sbenjsc
510173362Sbenjsc#define WPI_SCAN_MAX_ESSIDS	4
511173362Sbenjsc	struct {
512173362Sbenjsc	    uint8_t		id;
513173362Sbenjsc	    uint8_t		esslen;
514173362Sbenjsc	    uint8_t		essid[32];
515173362Sbenjsc	}scan_essids[WPI_SCAN_MAX_ESSIDS];
516173362Sbenjsc	/* followed by probe request body */
517173362Sbenjsc	/* followed by nchan x wpi_scan_chan */
518173362Sbenjsc} __packed;
519173362Sbenjsc
520173362Sbenjscstruct wpi_scan_chan {
521173362Sbenjsc	uint8_t		flags;
522173362Sbenjsc	uint8_t		chan;
523173362Sbenjsc#define WPI_CHAN_ACTIVE	(1 << 0)
524173362Sbenjsc#define WPI_CHAN_DIRECT (1 << 1)
525173362Sbenjsc	uint8_t		gain_radio;
526173362Sbenjsc	uint8_t		gain_dsp;
527173362Sbenjsc	uint16_t	active;		/* msecs */
528173362Sbenjsc	uint16_t	passive;	/* msecs */
529173362Sbenjsc} __packed;
530173362Sbenjsc
531173362Sbenjsc/* structure for WPI_CMD_BLUETOOTH */
532173362Sbenjscstruct wpi_bluetooth {
533173362Sbenjsc	uint8_t		flags;
534173362Sbenjsc	uint8_t		lead;
535173362Sbenjsc	uint8_t		kill;
536173362Sbenjsc	uint8_t		reserved;
537173362Sbenjsc	uint32_t	ack;
538173362Sbenjsc	uint32_t	cts;
539173362Sbenjsc} __packed;
540173362Sbenjsc
541173362Sbenjsc/* structure for command WPI_CMD_TXPOWER */
542173362Sbenjscstruct wpi_cmd_txpower {
543173362Sbenjsc
544173362Sbenjsc	uint8_t		band;
545173362Sbenjsc#define WPI_RATE_5GHZ	0
546173362Sbenjsc#define WPI_RATE_2GHZ	1
547173362Sbenjsc	uint8_t		reserved;
548173362Sbenjsc	uint16_t	channel;
549173362Sbenjsc
550173362Sbenjsc#define WPI_RATE_MAPPING_COUNT 12
551173362Sbenjsc	struct {
552173362Sbenjsc	    uint8_t	rate;
553173362Sbenjsc	    uint8_t	gain_radio;
554173362Sbenjsc	    uint8_t	gain_dsp;
555173362Sbenjsc	    uint8_t	reserved;
556173362Sbenjsc	} __packed rates [WPI_RATE_MAPPING_COUNT];
557173362Sbenjsc
558173362Sbenjsc} __packed;
559173362Sbenjsc
560173362Sbenjsc
561173362Sbenjsc
562173362Sbenjsc#define WPI_FW_MAIN_TEXT_MAXSZ (80 * 1024 )
563173362Sbenjsc#define WPI_FW_MAIN_DATA_MAXSZ (32 * 1024 )
564173362Sbenjsc#define WPI_FW_INIT_TEXT_MAXSZ (80 * 1024 )
565173362Sbenjsc#define WPI_FW_INIT_DATA_MAXSZ (32 * 1024 )
566173362Sbenjsc#define WPI_FW_BOOT_TEXT_MAXSZ 1024
567173362Sbenjsc
568173362Sbenjsc#define WPI_FW_UPDATED	(1 << 31 )
569173362Sbenjsc
570173362Sbenjsc/* firmware image header */
571173362Sbenjscstruct wpi_firmware_hdr {
572173362Sbenjsc
573173362Sbenjsc#define WPI_FW_MINVERSION 2144
574173362Sbenjsc
575173362Sbenjsc	uint32_t	version;
576173362Sbenjsc	uint32_t	rtextsz;
577173362Sbenjsc	uint32_t	rdatasz;
578173362Sbenjsc	uint32_t	itextsz;
579173362Sbenjsc	uint32_t	idatasz;
580173362Sbenjsc	uint32_t	btextsz;
581173362Sbenjsc} __packed;
582173362Sbenjsc
583173362Sbenjsc/* structure for WPI_UC_READY notification */
584173362Sbenjscstruct wpi_ucode_info {
585173362Sbenjsc	uint32_t	version;
586173362Sbenjsc	uint8_t		revision[8];
587173362Sbenjsc	uint8_t		type;
588173362Sbenjsc	uint8_t		subtype;
589173362Sbenjsc	uint16_t	reserved;
590173362Sbenjsc	uint32_t	logptr;
591173362Sbenjsc	uint32_t	errorptr;
592173362Sbenjsc	uint32_t	timestamp;
593173362Sbenjsc	uint32_t	valid;
594173362Sbenjsc} __packed;
595173362Sbenjsc
596173362Sbenjsc/* structure for WPI_START_SCAN notification */
597173362Sbenjscstruct wpi_start_scan {
598173362Sbenjsc	uint64_t	tstamp;
599173362Sbenjsc	uint32_t	tbeacon;
600173362Sbenjsc	uint8_t		chan;
601173362Sbenjsc	uint8_t		band;
602173362Sbenjsc	uint16_t	reserved;
603173362Sbenjsc	uint32_t	status;
604173362Sbenjsc} __packed;
605173362Sbenjsc
606173362Sbenjsc/* structure for WPI_STOP_SCAN notification */
607173362Sbenjscstruct wpi_stop_scan {
608173362Sbenjsc	uint8_t		nchan;
609173362Sbenjsc	uint8_t		status;
610173362Sbenjsc	uint8_t		reserved;
611173362Sbenjsc	uint8_t		chan;
612173362Sbenjsc	uint64_t	tsf;
613173362Sbenjsc} __packed;
614173362Sbenjsc
615173362Sbenjsc#define WPI_EEPROM_MAC		0x015
616173362Sbenjsc#define WPI_EEPROM_REVISION	0x035
617173362Sbenjsc#define WPI_EEPROM_CAPABILITIES	0x045
618173362Sbenjsc#define WPI_EEPROM_TYPE		0x04a
619173362Sbenjsc#define WPI_EEPROM_DOMAIN	0x060
620173362Sbenjsc#define WPI_EEPROM_BAND1	0x063
621173362Sbenjsc#define WPI_EEPROM_BAND2	0x072
622173362Sbenjsc#define WPI_EEPROM_BAND3	0x080
623173362Sbenjsc#define WPI_EEPROM_BAND4	0x08d
624173362Sbenjsc#define WPI_EEPROM_BAND5	0x099
625173362Sbenjsc#define WPI_EEPROM_POWER_GRP	0x100
626173362Sbenjsc
627173362Sbenjscstruct wpi_eeprom_chan {
628173362Sbenjsc	uint8_t	flags;
629173362Sbenjsc#define WPI_EEPROM_CHAN_VALID	(1<<0)
630173362Sbenjsc#define	WPI_EEPROM_CHAN_IBSS	(1<<1)
631173362Sbenjsc#define WPI_EEPROM_CHAN_ACTIVE	(1<<3)
632173362Sbenjsc#define WPI_EEPROM_CHAN_RADAR	(1<<4)
633173362Sbenjsc
634173362Sbenjsc	int8_t	maxpwr;
635173362Sbenjsc} __packed;
636173362Sbenjsc
637173362Sbenjscstruct wpi_eeprom_sample {
638173362Sbenjsc    uint8_t	index;
639173362Sbenjsc    int8_t	power;
640173362Sbenjsc    uint16_t	volt;
641173362Sbenjsc};
642173362Sbenjsc
643173362Sbenjsc#define WPI_POWER_GROUPS_COUNT	5
644173362Sbenjsc
645173362Sbenjscstruct wpi_eeprom_group {
646173362Sbenjsc    struct	wpi_eeprom_sample samples[5];
647173362Sbenjsc    int32_t	coef[5];
648173362Sbenjsc    int32_t	corr[5];
649173362Sbenjsc    int8_t	maxpwr;
650173362Sbenjsc    uint8_t	chan;
651173362Sbenjsc    int16_t	temp;
652173362Sbenjsc} __packed;
653173362Sbenjsc
654173362Sbenjsc#define WPI_CHAN_BANDS_COUNT	5
655173362Sbenjsc#define WPI_MAX_CHAN_PER_BAND	14
656173362Sbenjsc
657173362Sbenjscstatic const struct wpi_chan_band {
658173362Sbenjsc    uint32_t	addr;	/* offset in EEPROM */
659173362Sbenjsc    uint8_t	nchan;
660173362Sbenjsc    uint8_t	chan[WPI_MAX_CHAN_PER_BAND];
661173362Sbenjsc} wpi_bands[5] = {
662173362Sbenjsc    { WPI_EEPROM_BAND1, 14,
663173362Sbenjsc	{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }},
664173362Sbenjsc    { WPI_EEPROM_BAND2, 13,
665173362Sbenjsc	{ 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 }},
666173362Sbenjsc    { WPI_EEPROM_BAND3, 12,
667173362Sbenjsc	{ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 }},
668173362Sbenjsc    { WPI_EEPROM_BAND4, 11,
669173362Sbenjsc	{ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }},
670173362Sbenjsc    { WPI_EEPROM_BAND5, 6,
671173362Sbenjsc	{ 145, 149, 153, 157, 161, 165 }}
672173362Sbenjsc};
673173362Sbenjsc
674173362Sbenjsc#define WPI_MAX_PWR_INDEX	77
675173362Sbenjsc
676173362Sbenjsc/*
677173362Sbenjsc * RF Tx gain values from highest to lowest power (values obtained from
678173362Sbenjsc * the reference driver.)
679173362Sbenjsc */
680173362Sbenjscstatic const uint8_t wpi_rf_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = {
681173362Sbenjsc    0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xbb, 0xbb, 0xbb,
682173362Sbenjsc    0xbb, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xd3, 0xd3, 0xb3, 0xb3, 0xb3,
683173362Sbenjsc    0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x73, 0xeb, 0xeb, 0xeb,
684173362Sbenjsc    0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xab, 0xab, 0xab, 0x8b,
685173362Sbenjsc    0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xa3,
686173362Sbenjsc    0xa3, 0xa3, 0xa3, 0x83, 0x83, 0x83, 0x83, 0x63, 0x63, 0x63, 0x63,
687173362Sbenjsc    0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23, 0x03, 0x03, 0x03,
688173362Sbenjsc    0x03
689173362Sbenjsc};
690173362Sbenjsc
691173362Sbenjscstatic const uint8_t wpi_rf_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = {
692173362Sbenjsc    0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xbb, 0xbb, 0x9b, 0x9b, 0x7b, 0x7b,
693173362Sbenjsc    0x7b, 0x7b, 0x5b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1b, 0x1b,
694173362Sbenjsc    0x1b, 0x73, 0x73, 0x73, 0x53, 0x53, 0x53, 0x53, 0x53, 0x33, 0x33,
695173362Sbenjsc    0x33, 0x33, 0x13, 0x13, 0x13, 0x13, 0x13, 0xab, 0xab, 0xab, 0x8b,
696173362Sbenjsc    0x8b, 0x8b, 0x8b, 0x6b, 0x6b, 0x6b, 0x6b, 0x4b, 0x4b, 0x4b, 0x4b,
697173362Sbenjsc    0x2b, 0x2b, 0x2b, 0x2b, 0x0b, 0x0b, 0x0b, 0x0b, 0x83, 0x83, 0x63,
698173362Sbenjsc    0x63, 0x63, 0x63, 0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23,
699173362Sbenjsc    0x03
700173362Sbenjsc};
701173362Sbenjsc
702173362Sbenjsc/*
703173362Sbenjsc * DSP pre-DAC gain values from highest to lowest power (values obtained
704173362Sbenjsc * from the reference driver.)
705173362Sbenjsc */
706173362Sbenjscstatic const uint8_t wpi_dsp_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = {
707173362Sbenjsc    0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x6e, 0x69, 0x62, 0x7d, 0x73, 0x6c,
708173362Sbenjsc    0x63, 0x77, 0x6f, 0x69, 0x61, 0x5c, 0x6a, 0x64, 0x78, 0x71, 0x6b,
709173362Sbenjsc    0x7d, 0x77, 0x70, 0x6a, 0x65, 0x61, 0x5b, 0x6b, 0x79, 0x73, 0x6d,
710173362Sbenjsc    0x7f, 0x79, 0x73, 0x6c, 0x66, 0x60, 0x5c, 0x6e, 0x68, 0x62, 0x74,
711173362Sbenjsc    0x7d, 0x77, 0x71, 0x6b, 0x65, 0x60, 0x71, 0x6a, 0x66, 0x5f, 0x71,
712173362Sbenjsc    0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f,
713173362Sbenjsc    0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66,
714173362Sbenjsc    0x5f
715173362Sbenjsc};
716173362Sbenjsc
717173362Sbenjscstatic const uint8_t wpi_dsp_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = {
718173362Sbenjsc    0x7f, 0x78, 0x72, 0x77, 0x65, 0x71, 0x66, 0x72, 0x67, 0x75, 0x6b,
719173362Sbenjsc    0x63, 0x5c, 0x6c, 0x7d, 0x76, 0x6d, 0x66, 0x60, 0x5a, 0x68, 0x62,
720173362Sbenjsc    0x5c, 0x76, 0x6f, 0x68, 0x7e, 0x79, 0x71, 0x69, 0x63, 0x76, 0x6f,
721173362Sbenjsc    0x68, 0x62, 0x74, 0x6d, 0x66, 0x62, 0x5d, 0x71, 0x6b, 0x63, 0x78,
722173362Sbenjsc    0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63,
723173362Sbenjsc    0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x6b, 0x63, 0x78,
724173362Sbenjsc    0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63,
725173362Sbenjsc    0x78
726173362Sbenjsc};
727173362Sbenjsc
728173362Sbenjsc
729173362Sbenjsc#define WPI_READ(sc, reg)						\
730173362Sbenjsc    bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
731173362Sbenjsc
732173362Sbenjsc#define WPI_WRITE(sc, reg, val)						\
733173362Sbenjsc    bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
734173362Sbenjsc
735173362Sbenjsc#define WPI_WRITE_REGION_4(sc, offset, datap, count)			\
736173362Sbenjsc    bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
737173362Sbenjsc			     (datap), (count))
738