xref: /netbsd-src/sys/dev/pci/if_iwnreg.h (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: if_iwnreg.h,v 1.5 2008/11/13 12:04:09 blymn Exp $	*/
2 /*	OpenBSD: if_iwnreg.h,v 1.9 2007/11/27 20:59:40 damien Exp	*/
3 
4 /*-
5  * Copyright (c) 2007
6  *	Damien Bergamini <damien.bergamini@free.fr>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #define IWN_TX_RING_COUNT	256
22 #define IWN_RX_RING_COUNT	64
23 
24 #define IWN_NTXQUEUES		16
25 #define IWN_NTXCHAINS		2
26 
27 #define	IWN_BUF_ALIGN		4096
28 
29 /*
30  * Rings must be aligned on a 256-byte boundary.
31  */
32 #define IWN_RING_DMA_ALIGN	256
33 
34 /* maximum scatter/gather */
35 #define IWN_MAX_SCATTER	20
36 
37 /* Rx buffers must be large enough to hold a full 4K A-MPDU */
38 #define IWN_RBUF_SIZE	(8 * 1024)
39 
40 /*
41  * Control and status registers.
42  */
43 #define IWN_HWCONFIG		0x000
44 #define IWN_INTR_MIT		0x004
45 #define IWN_INTR		0x008
46 #define IWN_MASK		0x00c
47 #define IWN_INTR_STATUS		0x010
48 #define IWN_RESET		0x020
49 #define IWN_GPIO_CTL		0x024
50 #define IWN_EEPROM_CTL		0x02c
51 #define IWN_UCODE_CLR		0x05c
52 #define IWN_CHICKEN		0x100
53 #define IWN_QUEUE_OFFSET(qid)	(0x380 + (qid) * 8)
54 #define IWN_MEM_WADDR		0x410
55 #define IWN_MEM_WDATA		0x418
56 #define IWN_WRITE_MEM_ADDR  	0x444
57 #define IWN_READ_MEM_ADDR   	0x448
58 #define IWN_WRITE_MEM_DATA  	0x44c
59 #define IWN_READ_MEM_DATA   	0x450
60 #define IWN_TX_WIDX		0x460
61 
62 #define IWN_KW_BASE		0x197c
63 #define IWN_TX_BASE(qid)	(0x19d0 + (qid) * 4)
64 #define IWN_RW_WIDX_PTR		0x1bc0
65 #define IWN_RX_BASE		0x1bc4
66 #define IWN_RX_WIDX		0x1bc8
67 #define IWN_RX_CONFIG		0x1c00
68 #define IWN_RX_STATUS		0x1c44
69 #define IWN_TX_CONFIG(qid)	(0x1d00 + (qid) * 32)
70 #define IWN_TX_STATUS		0x1eb0
71 
72 #define IWN_SRAM_BASE		0xa02c00
73 #define IWN_TX_ACTIVE		(IWN_SRAM_BASE + 0x01c)
74 #define IWN_QUEUE_RIDX(qid)	(IWN_SRAM_BASE + 0x064 + (qid) * 4)
75 #define IWN_SELECT_QCHAIN	(IWN_SRAM_BASE + 0x0d0)
76 #define IWN_QUEUE_INTR_MASK	(IWN_SRAM_BASE + 0x0e4)
77 #define IWN_TXQ_STATUS(qid)	(IWN_SRAM_BASE + 0x104 + (qid) * 4)
78 
79 /*
80  * NIC internal memory offsets.
81  */
82 #define IWN_CLOCK_CTL		0x3000
83 #define IWN_MEM_CLOCK2		0x3008
84 #define IWN_MEM_POWER		0x300c
85 #define IWN_MEM_PCIDEV		0x3010
86 #define IWN_MEM_UCODE_CTL	0x3400
87 #define IWN_MEM_UCODE_SRC	0x3404
88 #define IWN_MEM_UCODE_DST	0x3408
89 #define IWN_MEM_UCODE_SIZE	0x340c
90 #define IWN_MEM_TEXT_BASE	0x3490
91 #define IWN_MEM_TEXT_SIZE	0x3494
92 #define IWN_MEM_DATA_BASE	0x3498
93 #define IWN_MEM_DATA_SIZE	0x349c
94 #define IWN_MEM_UCODE_BASE	0x3800
95 
96 
97 /* possible flags for register IWN_HWCONFIG */
98 #define IWN_HW_EEPROM_LOCKED	(1 << 21)
99 
100 /* possible flags for registers IWN_READ_MEM_ADDR/IWN_WRITE_MEM_ADDR */
101 #define IWN_MEM_4	((sizeof (uint32_t) - 1) << 24)
102 
103 /* possible values for IWN_MEM_UCODE_DST */
104 #define IWN_FW_TEXT	0x00000000
105 
106 /* possible flags for register IWN_RESET */
107 #define IWN_NEVO_RESET		(1 << 0)
108 #define IWN_SW_RESET		(1 << 7)
109 #define IWN_MASTER_DISABLED	(1 << 8)
110 #define IWN_STOP_MASTER		(1 << 9)
111 
112 /* possible flags for register IWN_GPIO_CTL */
113 #define IWN_GPIO_CLOCK		(1 << 0)
114 #define IWN_GPIO_INIT		(1 << 2)
115 #define IWN_GPIO_MAC		(1 << 3)
116 #define IWN_GPIO_SLEEP		(1 << 4)
117 #define IWN_GPIO_PWR_STATUS	0x07000000
118 #define IWN_GPIO_PWR_SLEEP	(4 << 24)
119 #define IWN_GPIO_RF_ENABLED	(1 << 27)
120 
121 /* possible flags for register IWN_CHICKEN */
122 #define IWN_CHICKEN_DISLOS	(1 << 29)
123 
124 /* possible flags for register IWN_UCODE_CLR */
125 #define IWN_RADIO_OFF		(1 << 1)
126 #define IWN_DISABLE_CMD		(1 << 2)
127 #define IWN_CTEMP_STOP_RF	(1 << 3)
128 
129 /* possible flags for IWN_RX_STATUS */
130 #define	IWN_RX_IDLE	(1 << 24)
131 
132 /* possible flags for register IWN_UC_CTL */
133 #define IWN_UC_ENABLE	(1 << 30)
134 #define IWN_UC_RUN	(1 << 31)
135 
136 /* possible flags for register IWN_INTR */
137 #define IWN_ALIVE_INTR	(1 <<  0)
138 #define IWN_WAKEUP_INTR	(1 <<  1)
139 #define IWN_SW_RX_INTR	(1 <<  3)
140 #define IWN_CT_REACHED	(1 <<  6)
141 #define IWN_RF_TOGGLED	(1 <<  7)
142 #define IWN_SW_ERROR	(1 << 25)
143 #define IWN_TX_INTR	(1 << 27)
144 #define IWN_HW_ERROR	(1 << 29)
145 #define IWN_RX_INTR	(1 << 31)
146 
147 #define IWN_INTR_MASK							\
148 	(IWN_SW_ERROR | IWN_HW_ERROR | IWN_TX_INTR | IWN_RX_INTR |	\
149 	    IWN_ALIVE_INTR | IWN_WAKEUP_INTR | IWN_SW_RX_INTR |		\
150 	    IWN_CT_REACHED | IWN_RF_TOGGLED)
151 
152 /* possible flags for register IWN_INTR_STATUS */
153 #define IWN_STATUS_TXQ(x)	(1 << (x))
154 #define IWN_STATUS_RXQ(x)	(1 << ((x) + 16))
155 #define IWN_STATUS_PRI		(1 << 30)
156 /* shortcuts for the above */
157 #define IWN_TX_STATUS_INTR						\
158 	(IWN_STATUS_TXQ(0) | IWN_STATUS_TXQ(1) | IWN_STATUS_TXQ(6))
159 #define IWN_RX_STATUS_INTR						\
160 	(IWN_STATUS_RXQ(0) | IWN_STATUS_RXQ(1) | IWN_STATUS_RXQ(2) |	\
161 	    IWN_STATUS_PRI)
162 
163 /* possible flags for register IWN_TX_STATUS */
164 #define IWN_TX_IDLE(qid)	(1 << ((qid) + 24) | 1 << ((qid) + 16))
165 
166 /* possible flags for register IWN_EEPROM_CTL */
167 #define IWN_EEPROM_READY	(1 << 0)
168 #define IWN_EEPROM_CMD		(1 << 1)
169 
170 /* possible flags for register IWN_TXQ_STATUS */
171 #define IWN_TXQ_STATUS_ACTIVE	0x0007fc01
172 
173 /* possible flags for register IWN_MEM_POWER */
174 #define IWN_POWER_RESET	(1 << 26)
175 
176 /* possible flags for register IWN_MEM_TEXT_SIZE */
177 #define IWN_FW_UPDATED	(1 << 31)
178 
179 /* possible flags for device-specific PCI register 0xe8 */
180 #define IWN_DIS_NOSNOOP	(1 << 11)
181 
182 /* possible flags for device-specific PCI register 0xf0 */
183 #define IWN_ENA_L1	(1 << 1)
184 
185 
186 #define IWN_TX_WINDOW	64
187 struct iwn_shared {
188 	uint16_t	len[IWN_NTXQUEUES][512];	/* 16KB total */
189 	uint16_t	closed_count;
190 	uint16_t	closed_rx_count;
191 	uint16_t	finished_count;
192 	uint16_t	finished_rx_count;
193 	uint32_t	reserved[2];
194 } __packed;
195 
196 struct iwn_tx_desc {
197 	uint32_t	flags;
198 	struct {
199 		uint32_t	w1;
200 		uint32_t	w2;
201 		uint32_t	w3;
202 	} __packed	segs[IWN_MAX_SCATTER / 2];
203 	/* pad to 128 bytes */
204 	uint32_t	reserved;
205 } __packed;
206 
207 #define IWN_SET_DESC_NSEGS(d, x)					\
208 	(d)->flags = htole32(((x) & 0x1f) << 24)
209 
210 /* set a segment physical address and length in a Tx descriptor */
211 #define IWN_SET_DESC_SEG(d, n, addr, size) do {				\
212 		if ((n) & 1) {						\
213 			(d)->segs[(n) / 2].w2 |=			\
214 			    htole32(((addr) & 0xffff) << 16);		\
215 			(d)->segs[(n) / 2].w3 =				\
216 			    htole32((((addr) >> 16) & 0xffff) | (size) << 20); \
217 		} else {						\
218 			(d)->segs[(n) / 2].w1 = htole32(addr);		\
219 			(d)->segs[(n) / 2].w2 = htole32((size) << 4);	\
220 		}							\
221 	} while (0)
222 
223 struct iwn_rx_desc {
224 	uint32_t	len;
225 	uint8_t		type;
226 #define IWN_UC_READY		  1
227 #define IWN_ADD_NODE_DONE	 24
228 #define IWN_TX_DONE		 28
229 #define IWN_START_SCAN		130
230 #define IWN_STOP_SCAN		132
231 #define IWN_RX_STATISTICS	156
232 #define IWN_BEACON_STATISTICS	157
233 #define IWN_STATE_CHANGED	161
234 #define IWN_BEACON_MISSED	162
235 #define IWN_AMPDU_RX_START	192
236 #define IWN_AMPDU_RX_DONE	193
237 #define IWN_RX_DONE		195
238 
239 	uint8_t		flags;
240 	uint8_t		idx;
241 	uint8_t		qid;
242 } __packed;
243 
244 /* possible Rx status flags */
245 #define IWN_RX_NO_CRC_ERR	(1 << 0)
246 #define IWN_RX_NO_OVFL_ERR	(1 << 1)
247 /* shortcut for the above */
248 #define IWN_RX_NOERROR	(IWN_RX_NO_CRC_ERR | IWN_RX_NO_OVFL_ERR)
249 
250 struct iwn_tx_cmd {
251 	uint8_t	code;
252 #define IWN_CMD_CONFIGURE		 16
253 #define IWN_CMD_ASSOCIATE		 17
254 #define IWN_CMD_SET_WME          19
255 #define IWN_CMD_TSF			 20
256 #define IWN_CMD_ADD_NODE		 24
257 #define IWN_CMD_TX_DATA			 28
258 #define IWN_CMD_NODE_MRR_SETUP		 78
259 #define IWN_CMD_SET_LED			 72
260 #define IWN_CMD_SET_POWER_MODE		119
261 #define IWN_CMD_SCAN			128
262 #define IWN_CMD_SCAN_ABORT		129
263 #define IWN_CMD_SET_BEACON		145
264 #define IWN_CMD_TXPOWER			151
265 #define IWN_CMD_BLUETOOTH		155
266 #define IWN_CMD_GET_STATISTICS		156
267 #define IWN_CMD_SET_CRITICAL_TEMP	164
268 #define IWN_SENSITIVITY			168
269 #define IWN_PHY_CALIB			176
270 
271 	uint8_t	flags;
272 	uint8_t	idx;
273 	uint8_t	qid;
274 	uint8_t	data[136];
275 } __packed;
276 
277 /* structure for command IWN_CMD_CONFIGURE */
278 struct iwn_config {
279 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
280 	uint16_t	reserved1;
281 	uint8_t		bssid[IEEE80211_ADDR_LEN];
282 	uint16_t	reserved2;
283 	uint8_t		wlap[IEEE80211_ADDR_LEN];
284 	uint16_t	reserved3;
285 	uint8_t		mode;
286 #define IWN_MODE_HOSTAP		1
287 #define IWN_MODE_STA		3
288 #define IWN_MODE_IBSS		4
289 #define IWN_MODE_MONITOR	6
290 
291 	uint8_t		reserved4;
292 	uint16_t	rxchain;
293 #define IWN_RXCHAIN_ANTMSK_SHIFT	1
294 #define IWN_RXCHAIN_FORCE_MIMO		(1 << 14)
295 
296 	uint8_t		ofdm_mask;
297 	uint8_t		cck_mask;
298 	uint16_t	associd;
299 	uint32_t	flags;
300 #define IWN_CONFIG_24GHZ	(1 <<  0)
301 #define IWN_CONFIG_CCK		(1 <<  1)
302 #define IWN_CONFIG_AUTO		(1 <<  2)
303 #define IWN_CONFIG_SHSLOT	(1 <<  4)
304 #define IWN_CONFIG_SHPREAMBLE	(1 <<  5)
305 #define IWN_CONFIG_NODIVERSITY	(1 <<  7)
306 #define IWN_CONFIG_ANTENNA_A	(1 <<  8)
307 #define IWN_CONFIG_ANTENNA_B	(1 <<  9)
308 #define IWN_CONFIG_TSF		(1 << 15)
309 
310 	uint32_t	filter;
311 #define IWN_FILTER_PROMISC	(1 << 0)
312 #define IWN_FILTER_CTL		(1 << 1)
313 #define IWN_FILTER_MULTICAST	(1 << 2)
314 #define IWN_FILTER_NODECRYPT	(1 << 3)
315 #define IWN_FILTER_BSS		(1 << 5)
316 
317 	uint16_t	chan;
318 	uint8_t		ht_single_mask;
319 	uint8_t		ht_dual_mask;
320 } __packed;
321 
322 /* structure for command IWN_CMD_ASSOCIATE */
323 struct iwn_assoc {
324 	uint32_t	flags;
325 	uint32_t	filter;
326 	uint8_t		ofdm_mask;
327 	uint8_t		cck_mask;
328 	uint16_t	reserved;
329 } __packed;
330 
331 /* structure for command IWN_CMD_SET_WME */
332 struct iwn_wme_setup {
333 	uint32_t	flags;
334 #define IWN_EDCA_UPDATE	(1 << 0)
335 #define IWN_EDCA_TXOP	(1 << 4)
336 
337 	struct {
338 		uint16_t	cwmin;
339 		uint16_t	cwmax;
340 		uint8_t		aifsn;
341 		uint8_t		reserved;
342 		uint16_t	txop;
343 	} __packed	ac[WME_NUM_AC];
344 } __packed;
345 
346 /* structure for command IWN_CMD_TSF */
347 struct iwn_cmd_tsf {
348 	uint64_t	tstamp;
349 	uint16_t	bintval;
350 	uint16_t	atim;
351 	uint32_t	binitval;
352 	uint16_t	lintval;
353 	uint16_t	reserved;
354 } __packed;
355 
356 /* structure for command IWN_CMD_ADD_NODE */
357 struct iwn_node_info {
358 	uint8_t		control;
359 #define IWN_NODE_UPDATE		(1 << 0)
360 
361 	uint8_t		reserved1[3];
362 	uint8_t		macaddr[IEEE80211_ADDR_LEN];
363 	uint16_t	reserved2;
364 	uint8_t		id;
365 #define IWN_ID_BSS		 0
366 #define IWN_ID_BROADCAST	31
367 
368 	uint8_t		flags;
369 #define IWN_FLAG_SET_KEY	(1 << 0)
370 
371 	uint16_t	reserved3;
372 	uint16_t	security;
373 	uint8_t		tsc2;	/* TKIP TSC2 */
374 	uint8_t		reserved4;
375 	uint16_t	ttak[5];
376 	uint16_t	reserved5;
377 	uint8_t		key[IEEE80211_KEYBUF_SIZE];
378 	uint32_t	htflags;
379 #define IWN_AMDPU_SIZE_FACTOR_SHIFT	19
380 #define IWN_AMDPU_DENSITY_SHIFT		23
381 
382 	uint32_t	mask;
383 	uint16_t	tid;
384 	uint8_t		rate;
385 	uint8_t		rflags;
386 #define IWN_RFLAG_CCK	(1 << 1)
387 #define IWN_RFLAG_ANT_A	(1 << 6)
388 #define IWN_RFLAG_ANT_B	(1 << 7)
389 
390 	uint8_t		add_imm;
391 	uint8_t		del_imm;
392 	uint16_t	add_imm_start;
393 	uint32_t	reserved6;
394 } __packed;
395 
396 /* structure for command IWN_CMD_TX_DATA */
397 struct iwn_cmd_data {
398 	uint16_t	len;
399 	uint16_t	lnext;
400 	uint32_t	flags;
401 #define IWN_TX_NEED_RTS		(1 <<  1)
402 #define IWN_TX_NEED_CTS		(1 <<  2)
403 #define IWN_TX_NEED_ACK		(1 <<  3)
404 #define IWN_TX_USE_NODE_RATE	(1 <<  4)
405 #define IWN_TX_FULL_TXOP	(1 <<  7)
406 #define IWN_TX_BT_DISABLE	(1 << 12)	/* bluetooth coexistence */
407 #define IWN_TX_AUTO_SEQ		(1 << 13)
408 #define IWN_TX_INSERT_TSTAMP	(1 << 16)
409 #define IWN_TX_NEED_PADDING	(1 << 20)
410 
411 	uint8_t		ntries;
412 	uint8_t		bluetooth;
413 	uint16_t	reserved1;
414 	uint8_t		rate;
415 	uint8_t		rflags;
416 	uint16_t	xrflags;
417 	uint8_t		id;
418 	uint8_t		security;
419 #define IWN_CIPHER_WEP40	1
420 #define IWN_CIPHER_CCMP		2
421 #define IWN_CIPHER_TKIP		3
422 #define IWN_CIPHER_WEP104	9
423 
424 	uint8_t		ridx;
425 	uint8_t		reserved2;
426 	uint8_t		key[IEEE80211_KEYBUF_SIZE];
427 	uint16_t	fnext;
428 	uint16_t	reserved3;
429 	uint32_t	lifetime;
430 #define IWN_LIFETIME_INFINITE	0xffffffff
431 
432 	uint32_t	loaddr;
433 	uint8_t		hiaddr;
434 	uint8_t		rts_ntries;
435 	uint8_t		data_ntries;
436 	uint8_t		tid;
437 	uint16_t	timeout;
438 	uint16_t	txop;
439 } __packed;
440 
441 /* structure for command IWN_CMD_SET_BEACON */
442 struct iwn_cmd_beacon {
443 	uint16_t	len;
444 	uint16_t	reserved1;
445 	uint32_t	flags;	/* same as iwn_cmd_data */
446 	uint8_t		try_cnt;
447 	uint8_t		kill_cnt;
448 	uint16_t	reserved2;
449 	uint8_t		rate;
450 	uint8_t		flags2;
451 	uint16_t	ext_flags;
452 	uint8_t		id;
453 	uint8_t		reserved3[23];
454 	uint32_t	lifetime;
455 	uint32_t	reserved4;
456 	uint8_t		reserved5;
457 	uint8_t		reserved6;
458 	uint8_t		reserved7;
459 	uint16_t	reserved8[9];
460 	uint16_t	tim;
461 	uint8_t		timsz;
462 	uint8_t		reserved9;
463 	struct		ieee80211_frame wh;
464 } __packed;
465 
466 /* structure for command IWN_CMD_MRR_NODE_SETUP */
467 #define IWN_MAX_TX_RETRIES	16
468 struct iwn_cmd_mrr {
469 	uint8_t		id;
470 	uint8_t		reserved1;
471 	uint16_t	ctl;
472 	uint8_t		flags;
473 	uint8_t		mimo;
474 	uint8_t		ssmask;
475 	uint8_t		dsmask;
476 	uint8_t		ridx[WME_NUM_AC];
477 	uint16_t	ampdu_limit;
478 	uint8_t		ampdu_disable;
479 	uint8_t		ampdu_max;
480 	uint32_t	reserved2;
481 	struct {
482 		uint8_t		rate;
483 #define IWN_CCK1	 0
484 #define IWN_CCK11	 3
485 #define IWN_OFDM6	 4
486 #define IWN_OFDM54	11
487 
488 		uint8_t		rflags;
489 		uint16_t	xrflags;
490 	}		table[IWN_MAX_TX_RETRIES];
491 	uint32_t	reserved3;
492 } __packed;
493 
494 /* structure for command IWN_CMD_SET_LED */
495 struct iwn_cmd_led {
496 	uint32_t	unit;	/* multiplier (in usecs) */
497 	uint8_t		which;
498 #define IWN_LED_ACTIVITY	1
499 #define IWN_LED_LINK		2
500 
501 	uint8_t		off;
502 	uint8_t		on;
503 	uint8_t		reserved;
504 } __packed;
505 
506 /* structure for command IWN_CMD_SET_POWER_MODE */
507 struct iwn_power {
508 	uint16_t	flags;
509 #define IWN_POWER_CAM	0	/* constantly awake mode */
510 
511 	uint8_t		alive;
512 	uint8_t		debug;
513 	uint32_t	rx_timeout;
514 	uint32_t	tx_timeout;
515 	uint32_t	sleep[5];
516 	uint32_t	beacons;
517 } __packed;
518 
519 /* structures for command IWN_CMD_SCAN */
520 struct iwn_scan_essid {
521 	uint8_t	id;
522 	uint8_t	len;
523 	uint8_t	data[IEEE80211_NWID_LEN];
524 } __packed;
525 
526 #define IWN_MAX_PROBES	4
527 
528 struct iwn_scan_hdr {
529 	uint16_t		len;
530 	uint8_t			reserved1;
531 	uint8_t			nchan;
532 	uint16_t		quiet;
533 	uint16_t		plcp_threshold;
534 	uint16_t		crc_threshold;
535 	uint16_t		rxchain;
536 	uint32_t		max_svc;	/* background scans */
537 	uint32_t		pause_svc;	/* background scans */
538 	uint32_t		flags;
539 	uint32_t		filter;
540 	struct iwn_cmd_data	tx_cmd;
541 	struct iwn_scan_essid	scan_essid[IWN_MAX_PROBES];
542 	struct ieee80211_frame	wh;
543 	uint8_t			data[0];    /* nchan x struct iwn_scan_chan */
544 } __packed;
545 
546 struct iwn_scan_chan {
547 	uint8_t		flags;
548 #define IWN_CHAN_ACTIVE	(1 << 0)
549 #define IWN_CHAN_DIRECT	(1 << 1)
550 
551 	uint8_t		chan;
552 	uint8_t		rf_gain;
553 	uint8_t		dsp_gain;
554 	uint16_t	active;		/* msecs */
555 	uint16_t	passive;	/* msecs */
556 } __packed;
557 
558 /* structure for command IWN_CMD_TXPOWER */
559 #define IWN_RIDX_MAX	32
560 struct iwn_cmd_txpower {
561 	uint8_t	band;
562 	uint8_t	reserved1;
563 	uint8_t	chan;
564 	uint8_t	reserved2;
565 	struct {
566 		uint8_t	rf_gain[IWN_NTXCHAINS];
567 		uint8_t	dsp_gain[IWN_NTXCHAINS];
568 	}	power[IWN_RIDX_MAX + 1];
569 } __packed;
570 
571 /* structure for command IWN_CMD_BLUETOOTH */
572 struct iwn_bluetooth {
573 	uint8_t		flags;
574 	uint8_t		lead;
575 	uint8_t		kill;
576 	uint8_t		reserved;
577 	uint32_t	ack;
578 	uint32_t	cts;
579 } __packed;
580 
581 /* structure for command IWN_CMD_SET_CRITICAL_TEMP */
582 struct iwn_critical_temp {
583 	uint32_t	reserved;
584 	uint32_t	tempM;
585 	uint32_t	tempR;
586 /* degK <-> degC conversion macros */
587 #define IWN_CTOK(c)	((c) + 273)
588 #define IWN_KTOC(k)	((k) - 273)
589 #define IWN_CTOMUK(c)	(((c) * 1000000) + 273150000)
590 } __packed;
591 
592 /* structure for command IWN_SENSITIVITY */
593 struct iwn_sensitivity_cmd {
594 	uint16_t	which;
595 #define IWN_SENSITIVITY_DEFAULTTBL	0
596 #define IWN_SENSITIVITY_WORKTBL		1
597 
598 	uint16_t	energy_cck;
599 	uint16_t	energy_ofdm;
600 	uint16_t	corr_ofdm_x1;
601 	uint16_t	corr_ofdm_mrc_x1;
602 	uint16_t	corr_cck_mrc_x4;
603 	uint16_t	corr_ofdm_x4;
604 	uint16_t	corr_ofdm_mrc_x4;
605 	uint16_t	corr_barker;
606 	uint16_t	corr_barker_mrc;
607 	uint16_t	corr_cck_x4;
608 	uint16_t	energy_ofdm_th;
609 } __packed;
610 
611 /* structure for command IWN_PHY_CALIB */
612 struct iwn_phy_calib_cmd {
613 	uint8_t		code;
614 #define IWN_SET_DIFF_GAIN	7
615 
616 	uint8_t		flags;
617 	uint16_t	reserved1;
618 	int8_t		gain[3];
619 #define IWN_GAIN_SET	(1 << 2)
620 
621 	uint8_t		reserved2;
622 } __packed;
623 
624 
625 /* structure for IWN_UC_READY notification */
626 #define IWN_NATTEN_GROUPS	5
627 struct iwn_ucode_info {
628 	uint8_t		minor;
629 	uint8_t		major;
630 	uint16_t	reserved1;
631 	uint8_t		revision[8];
632 	uint8_t		type;
633 	uint8_t		subtype;
634 #define IWN_UCODE_RUNTIME	0
635 #define IWN_UCODE_INIT		9
636 
637 	uint16_t	reserved2;
638 	uint32_t	logptr;
639 	uint32_t	errorptr;
640 	uint32_t	tstamp;
641 	uint32_t	valid;
642 
643 	/* the following fields are for UCODE_INIT only */
644 	int32_t		volt;
645 	struct {
646 		int32_t	chan20MHz;
647 		int32_t	chan40MHz;
648 	} __packed	temp[4];
649 	int32_t		atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS];
650 } __packed;
651 
652 /* structure for IWN_TX_DONE notification */
653 struct iwn_tx_stat {
654 	uint8_t		nframes;
655 	uint8_t		nkill;
656 	uint8_t		nrts;
657 	uint8_t		ntries;
658 	uint8_t		rate;
659 	uint8_t		rflags;
660 	uint16_t	xrflags;
661 	uint16_t	duration;
662 	uint16_t	reserved;
663 	uint32_t	power[2];
664 	uint32_t	status;
665 	/* from FreeBSD driver... XXX */
666 #define IWN_TX_SUCCESS                  0x00
667 #define IWN_TX_FAIL                     0x80    /* all failures have 0x80 set */
668 #define IWN_TX_FAIL_SHORT_LIMIT         0x82    /* too many RTS retries */
669 #define IWN_TX_FAIL_LONG_LIMIT          0x83    /* too many retries */
670 #define IWN_TX_FAIL_FIFO_UNDERRRUN      0x84    /* tx fifo not kept running */
671 #define IWN_TX_FAIL_DEST_IN_PS          0x88    /* sta found in power save */
672 #define IWN_TX_FAIL_TX_LOCKED           0x90    /* waiting to see traffic */
673 } __packed;
674 
675 /* structure for IWN_BEACON_MISSED notification */
676 struct iwn_beacon_missed {
677 	uint32_t	consecutive;
678 	uint32_t	total;
679 	uint32_t	expected;
680 	uint32_t	received;
681 } __packed;
682 
683 /* structure for IWN_AMPDU_RX_DONE notification */
684 struct iwn_rx_ampdu {
685 	uint16_t	len;
686 	uint16_t	reserved;
687 } __packed;
688 
689 /* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */
690 struct iwn_rx_stat {
691 	uint8_t		phy_len;
692 	uint8_t		cfg_phy_len;
693 #define IWN_STAT_MAXLEN	20
694 
695 	uint8_t		id;
696 	uint8_t		reserved1;
697 	uint64_t	tstamp;
698 	uint32_t	beacon;
699 	uint16_t	flags;
700 	uint16_t	chan;
701 	uint16_t	antenna;
702 	uint16_t	agc;
703 	uint8_t		rssi[6];
704 #define IWN_RSSI_TO_DBM	44
705 
706 	uint8_t		reserved2[22];
707 	uint8_t		rate;
708 	uint8_t		rflags;
709 	uint16_t	xrflags;
710 	uint16_t	len;
711 	uint16_t	reserve3;
712 } __packed;
713 
714 /* structure for IWN_START_SCAN notification */
715 struct iwn_start_scan {
716 	uint64_t	tstamp;
717 	uint32_t	tbeacon;
718 	uint8_t		chan;
719 	uint8_t		band;
720 	uint16_t	reserved;
721 	uint32_t	status;
722 } __packed;
723 
724 /* structure for IWN_STOP_SCAN notification */
725 struct iwn_stop_scan {
726 	uint8_t		nchan;
727 	uint8_t		status;
728 	uint8_t		reserved;
729 	uint8_t		chan;
730 	uint64_t	tsf;
731 } __packed;
732 
733 /* structure for IWN_{RX,BEACON}_STATISTICS notification */
734 struct iwn_rx_phy_stats {
735 	uint32_t	ina;
736 	uint32_t	fina;
737 	uint32_t	bad_plcp;
738 	uint32_t	bad_crc32;
739 	uint32_t	overrun;
740 	uint32_t	eoverrun;
741 	uint32_t	good_crc32;
742 	uint32_t	fa;
743 	uint32_t	bad_fina_sync;
744 	uint32_t	sfd_timeout;
745 	uint32_t	fina_timeout;
746 	uint32_t	no_rts_ack;
747 	uint32_t	rxe_limit;
748 	uint32_t	ack;
749 	uint32_t	cts;
750 	uint32_t	ba_resp;
751 	uint32_t	dsp_kill;
752 	uint32_t	bad_mh;
753 	uint32_t	rssi_sum;
754 	uint32_t	reserved;
755 } __packed;
756 
757 struct iwn_rx_general_stats {
758 	uint32_t	bad_cts;
759 	uint32_t	bad_ack;
760 	uint32_t	not_bss;
761 	uint32_t	filtered;
762 	uint32_t	bad_chan;
763 	uint32_t	beacons;
764 	uint32_t	missed_beacons;
765 	uint32_t	adc_saturated;	/* time in 0.8us */
766 	uint32_t	ina_searched;	/* time in 0.8us */
767 	uint32_t	noise[3];
768 	uint32_t	flags;
769 	uint32_t	load;
770 	uint32_t	fa;
771 	uint32_t	rssi[3];
772 	uint32_t	energy[3];
773 } __packed;
774 
775 struct iwn_rx_ht_phy_stats {
776 	uint32_t	bad_plcp;
777 	uint32_t	overrun;
778 	uint32_t	eoverrun;
779 	uint32_t	good_crc32;
780 	uint32_t	bad_crc32;
781 	uint32_t	bad_mh;
782 	uint32_t	good_ampdu_crc32;
783 	uint32_t	ampdu;
784 	uint32_t	fragment;
785 	uint32_t	reserved;
786 } __packed;
787 
788 struct iwn_rx_stats {
789 	struct iwn_rx_phy_stats		ofdm;
790 	struct iwn_rx_phy_stats		cck;
791 	struct iwn_rx_general_stats	general;
792 	struct iwn_rx_ht_phy_stats	ht;
793 } __packed;
794 
795 struct iwn_tx_stats {
796 	uint32_t	preamble;
797 	uint32_t	rx_detected;
798 	uint32_t	bt_defer;
799 	uint32_t	bt_kill;
800 	uint32_t	short_len;
801 	uint32_t	cts_timeout;
802 	uint32_t	ack_timeout;
803 	uint32_t	exp_ack;
804 	uint32_t	ack;
805 	uint32_t	msdu;
806 	uint32_t	busrt_err1;
807 	uint32_t	burst_err2;
808 	uint32_t	cts_collision;
809 	uint32_t	ack_collision;
810 	uint32_t	ba_timeout;
811 	uint32_t	ba_resched;
812 	uint32_t	query_ampdu;
813 	uint32_t	query;
814 	uint32_t	query_ampdu_frag;
815 	uint32_t	query_mismatch;
816 	uint32_t	not_ready;
817 	uint32_t	underrun;
818 	uint32_t	bt_ht_kill;
819 	uint32_t	rx_ba_resp;
820 	uint32_t	reserved[2];
821 } __packed;
822 
823 struct iwn_general_stats {
824 	uint32_t	temp;
825 	uint32_t	temp_m;
826 	uint32_t	burst_check;
827 	uint32_t	burst;
828 	uint32_t	reserved1[4];
829 	uint32_t	sleep;
830 	uint32_t	slot_out;
831 	uint32_t	slot_idle;
832 	uint32_t	ttl_tstamp;
833 	uint32_t	tx_ant_a;
834 	uint32_t	tx_ant_b;
835 	uint32_t	exec;
836 	uint32_t	probe;
837 	uint32_t	reserved2[2];
838 	uint32_t	rx_enabled;
839 	uint32_t	reserved3[3];
840 } __packed;
841 
842 struct iwn_stats {
843 	uint32_t			flags;
844 	struct iwn_rx_stats		rx;
845 	struct iwn_tx_stats		tx;
846 	struct iwn_general_stats	general;
847 } __packed;
848 
849 
850 /* firmware image header */
851 struct iwn_firmware_hdr {
852 	uint32_t	version;
853 	uint32_t	main_textsz;
854 	uint32_t	main_datasz;
855 	uint32_t	init_textsz;
856 	uint32_t	init_datasz;
857 	uint32_t	boot_textsz;
858 } __packed;
859 
860 #define IWN_FW_MAIN_TEXT_MAXSZ	(96 * 1024)
861 #define IWN_FW_MAIN_DATA_MAXSZ	(40 * 1024)
862 #define IWN_FW_INIT_TEXT_MAXSZ	(96 * 1024)
863 #define IWN_FW_INIT_DATA_MAXSZ	(40 * 1024)
864 #define IWN_FW_BOOT_TEXT_MAXSZ	1024
865 
866 
867 /*
868  * Offsets into EEPROM.
869  */
870 #define IWN_EEPROM_MAC		0x015
871 #define IWN_EEPROM_DOMAIN	0x060
872 #define IWN_EEPROM_BAND1	0x063
873 #define IWN_EEPROM_BAND2	0x072
874 #define IWN_EEPROM_BAND3	0x080
875 #define IWN_EEPROM_BAND4	0x08d
876 #define IWN_EEPROM_BAND5	0x099
877 #define IWN_EEPROM_BAND6	0x0a0
878 #define IWN_EEPROM_BAND7	0x0a8
879 #define IWN_EEPROM_MAXPOW	0x0e8
880 #define IWN_EEPROM_VOLTAGE	0x0e9
881 #define IWN_EEPROM_BANDS	0x0ea
882 
883 struct iwn_eeprom_chan {
884 	uint8_t	flags;
885 #define IWN_EEPROM_CHAN_VALID	(1 << 0)
886 #define IWN_EEPROM_CHAN_IBSS	(1 << 1)
887 #define IWN_EEPROM_CHAN_ACTIVE	(1 << 3)
888 #define IWN_EEPROM_CHAN_RADAR	(1 << 4)
889 
890 	int8_t	maxpwr;
891 } __packed;
892 
893 #define IWN_NSAMPLES	3
894 struct iwn_eeprom_chan_samples {
895 	uint8_t	num;
896 	struct {
897 		uint8_t temp;
898 		uint8_t	gain;
899 		uint8_t	power;
900 		int8_t	pa_det;
901 	}	samples[IWN_NTXCHAINS][IWN_NSAMPLES];
902 } __packed;
903 
904 #define IWN_NBANDS	8
905 struct iwn_eeprom_band {
906 	uint8_t	lo;	/* low channel number */
907 	uint8_t	hi;	/* high channel number */
908 	struct	iwn_eeprom_chan_samples chans[2];
909 } __packed;
910 
911 #define IWN_CHAN_BANDS_COUNT	 7
912 #define IWN_MAX_CHAN_PER_BAND	14
913 static const struct iwn_chan_band {
914 	uint32_t	addr;	/* offset in EEPROM */
915 	uint8_t		nchan;
916 	uint8_t		chan[IWN_MAX_CHAN_PER_BAND];
917 } iwn_bands[] = {
918 	{ IWN_EEPROM_BAND1, 14,
919 	  { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
920 	{ IWN_EEPROM_BAND2, 13,
921 	  { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
922 	{ IWN_EEPROM_BAND3, 12,
923 	  { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
924 	{ IWN_EEPROM_BAND4, 11,
925 	  { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
926 	{ IWN_EEPROM_BAND5, 6,
927 	  { 145, 149, 153, 157, 161, 165 } },
928 	{ IWN_EEPROM_BAND6, 7,
929 	  { 1, 2, 3, 4, 5, 6, 7 } },
930 	{ IWN_EEPROM_BAND7, 11,
931 	  { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
932 };
933 
934 static const uint8_t iwn_ridx_to_plcp[] = {
935 	10, 20, 55, 110, /* CCK */
936 		0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
937 };
938 
939 /* allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
940 static const uint8_t iwn_prev_ridx[] = {
941 	0, 0, 1, 5, /* CCK */
942 		2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
943 };
944 
945 #define IWN_MAX_PWR_INDEX	107
946 
947 /*
948  * RF Tx gain values from highest to lowest power (values obtained from
949  * the reference driver.)
950  */
951 static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
952 	0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
953 		0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38,
954 		0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
955 		0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31,
956 		0x31, 0x30, 0x30, 0x30, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04,
957 		0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
958 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
960 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
961 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
962 };
963 
964 static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
965 	0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d,
966 		0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39,
967 		0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35,
968 		0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32,
969 		0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x25, 0x25, 0x25, 0x24, 0x24,
970 		0x24, 0x23, 0x23, 0x23, 0x22, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16,
971 		0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13,
972 		0x12, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x05, 0x05,
973 		0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01,
974 		0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
975 };
976 
977 /*
978  * DSP pre-DAC gain values from highest to lowest power (values obtained
979  * from the reference driver.)
980  */
981 static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
982 	0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
983 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
984 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
985 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
986 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
987 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
988 		0x6e, 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a,
989 		0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f,
990 		0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44,
991 		0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b
992 };
993 
994 static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
995 	0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
996 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
997 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
998 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
999 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
1000 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
1001 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
1002 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
1003 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
1004 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e
1005 };
1006 
1007 #define IWN_READ(sc, reg)						\
1008 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
1009 
1010 #define IWN_WRITE(sc, reg, val)						\
1011 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
1012 
1013 #define IWN_WRITE_REGION_4(sc, offset, datap, count)			\
1014 	bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
1015 	    (datap), (count))
1016