xref: /netbsd-src/sys/dev/pci/if_iwnreg.h (revision 7c3f385475147b6e1c4753f2bee961630e2dfc40)
1 /*	$NetBSD: if_iwnreg.h,v 1.3 2008/02/09 19:14:53 skrll 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	(4 * 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_SET_BEACON		145
263 #define IWN_CMD_TXPOWER			151
264 #define IWN_CMD_BLUETOOTH		155
265 #define IWN_CMD_GET_STATISTICS		156
266 #define IWN_CMD_SET_CRITICAL_TEMP	164
267 #define IWN_SENSITIVITY			168
268 #define IWN_PHY_CALIB			176
269 
270 	uint8_t	flags;
271 	uint8_t	idx;
272 	uint8_t	qid;
273 	uint8_t	data[136];
274 } __packed;
275 
276 /* structure for command IWN_CMD_CONFIGURE */
277 struct iwn_config {
278 	uint8_t		myaddr[IEEE80211_ADDR_LEN];
279 	uint16_t	reserved1;
280 	uint8_t		bssid[IEEE80211_ADDR_LEN];
281 	uint16_t	reserved2;
282 	uint8_t		wlap[IEEE80211_ADDR_LEN];
283 	uint16_t	reserved3;
284 	uint8_t		mode;
285 #define IWN_MODE_HOSTAP		1
286 #define IWN_MODE_STA		3
287 #define IWN_MODE_IBSS		4
288 #define IWN_MODE_MONITOR	6
289 
290 	uint8_t		reserved4;
291 	uint16_t	rxchain;
292 #define IWN_RXCHAIN_ANTMSK_SHIFT	1
293 #define IWN_RXCHAIN_FORCE_MIMO		(1 << 14)
294 
295 	uint8_t		ofdm_mask;
296 	uint8_t		cck_mask;
297 	uint16_t	associd;
298 	uint32_t	flags;
299 #define IWN_CONFIG_24GHZ	(1 <<  0)
300 #define IWN_CONFIG_CCK		(1 <<  1)
301 #define IWN_CONFIG_AUTO		(1 <<  2)
302 #define IWN_CONFIG_SHSLOT	(1 <<  4)
303 #define IWN_CONFIG_SHPREAMBLE	(1 <<  5)
304 #define IWN_CONFIG_NODIVERSITY	(1 <<  7)
305 #define IWN_CONFIG_ANTENNA_A	(1 <<  8)
306 #define IWN_CONFIG_ANTENNA_B	(1 <<  9)
307 #define IWN_CONFIG_TSF		(1 << 15)
308 
309 	uint32_t	filter;
310 #define IWN_FILTER_PROMISC	(1 << 0)
311 #define IWN_FILTER_CTL		(1 << 1)
312 #define IWN_FILTER_MULTICAST	(1 << 2)
313 #define IWN_FILTER_NODECRYPT	(1 << 3)
314 #define IWN_FILTER_BSS		(1 << 5)
315 
316 	uint8_t		chan;
317 	uint8_t		reserved5;
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		rate;
447 	uint8_t		id;
448 	uint8_t		reserved2[30];
449 	uint32_t	lifetime;
450 	uint8_t		ofdm_mask;
451 	uint8_t		cck_mask;
452 	uint16_t	reserved3[3];
453 	uint16_t	tim;
454 	uint8_t		timsz;
455 	uint8_t		reserved4;
456 	struct		ieee80211_frame wh;
457 } __packed;
458 
459 /* structure for command IWN_CMD_MRR_NODE_SETUP */
460 #define IWN_MAX_TX_RETRIES	16
461 struct iwn_cmd_mrr {
462 	uint8_t		id;
463 	uint8_t		reserved1;
464 	uint16_t	ctl;
465 	uint8_t		flags;
466 	uint8_t		mimo;
467 	uint8_t		ssmask;
468 	uint8_t		dsmask;
469 	uint8_t		ridx[WME_NUM_AC];
470 	uint16_t	ampdu_limit;
471 	uint8_t		ampdu_disable;
472 	uint8_t		ampdu_max;
473 	uint32_t	reserved2;
474 	struct {
475 		uint8_t		rate;
476 #define IWN_CCK1	 0
477 #define IWN_CCK11	 3
478 #define IWN_OFDM6	 4
479 #define IWN_OFDM54	11
480 
481 		uint8_t		rflags;
482 		uint16_t	xrflags;
483 	}		table[IWN_MAX_TX_RETRIES];
484 	uint32_t	reserved3;
485 } __packed;
486 
487 /* structure for command IWN_CMD_SET_LED */
488 struct iwn_cmd_led {
489 	uint32_t	unit;	/* multiplier (in usecs) */
490 	uint8_t		which;
491 #define IWN_LED_ACTIVITY	1
492 #define IWN_LED_LINK		2
493 
494 	uint8_t		off;
495 	uint8_t		on;
496 	uint8_t		reserved;
497 } __packed;
498 
499 /* structure for command IWN_CMD_SET_POWER_MODE */
500 struct iwn_power {
501 	uint16_t	flags;
502 #define IWN_POWER_CAM	0	/* constantly awake mode */
503 
504 	uint8_t		alive;
505 	uint8_t		debug;
506 	uint32_t	rx_timeout;
507 	uint32_t	tx_timeout;
508 	uint32_t	sleep[5];
509 	uint32_t	beacons;
510 } __packed;
511 
512 /* structures for command IWN_CMD_SCAN */
513 struct iwn_scan_essid {
514 	uint8_t	id;
515 	uint8_t	len;
516 	uint8_t	data[IEEE80211_NWID_LEN];
517 } __packed;
518 
519 struct iwn_scan_hdr {
520 	uint16_t	len;
521 	uint8_t		reserved1;
522 	uint8_t		nchan;
523 	uint16_t	quiet;
524 	uint16_t	plcp_threshold;
525 	uint16_t	crc_threshold;
526 	uint16_t	rxchain;
527 	uint32_t	max_svc;	/* background scans */
528 	uint32_t	pause_svc;	/* background scans */
529 	uint32_t	flags;
530 	uint32_t	filter;
531 
532 	/* followed by a struct iwn_cmd_data */
533 	/* followed by an array of 4x struct iwn_scan_essid */
534 	/* followed by probe request body */
535 	/* followed by nchan x struct iwn_scan_chan */
536 } __packed;
537 
538 struct iwn_scan_chan {
539 	uint8_t		flags;
540 #define IWN_CHAN_ACTIVE	(1 << 0)
541 #define IWN_CHAN_DIRECT	(1 << 1)
542 
543 	uint8_t		chan;
544 	uint8_t		rf_gain;
545 	uint8_t		dsp_gain;
546 	uint16_t	active;		/* msecs */
547 	uint16_t	passive;	/* msecs */
548 } __packed;
549 
550 /* structure for command IWN_CMD_TXPOWER */
551 #define IWN_RIDX_MAX	32
552 struct iwn_cmd_txpower {
553 	uint8_t	band;
554 	uint8_t	reserved1;
555 	uint8_t	chan;
556 	uint8_t	reserved2;
557 	struct {
558 		uint8_t	rf_gain[IWN_NTXCHAINS];
559 		uint8_t	dsp_gain[IWN_NTXCHAINS];
560 	}	power[IWN_RIDX_MAX + 1];
561 } __packed;
562 
563 /* structure for command IWN_CMD_BLUETOOTH */
564 struct iwn_bluetooth {
565 	uint8_t		flags;
566 	uint8_t		lead;
567 	uint8_t		kill;
568 	uint8_t		reserved;
569 	uint32_t	ack;
570 	uint32_t	cts;
571 } __packed;
572 
573 /* structure for command IWN_CMD_SET_CRITICAL_TEMP */
574 struct iwn_critical_temp {
575 	uint32_t	reserved;
576 	uint32_t	tempM;
577 	uint32_t	tempR;
578 /* degK <-> degC conversion macros */
579 #define IWN_CTOK(c)	((c) + 273)
580 #define IWN_KTOC(k)	((k) - 273)
581 #define IWN_CTOMUK(c)	(((c) * 1000000) + 273150000)
582 } __packed;
583 
584 /* structure for command IWN_SENSITIVITY */
585 struct iwn_sensitivity_cmd {
586 	uint16_t	which;
587 #define IWN_SENSITIVITY_DEFAULTTBL	0
588 #define IWN_SENSITIVITY_WORKTBL		1
589 
590 	uint16_t	energy_cck;
591 	uint16_t	energy_ofdm;
592 	uint16_t	corr_ofdm_x1;
593 	uint16_t	corr_ofdm_mrc_x1;
594 	uint16_t	corr_cck_mrc_x4;
595 	uint16_t	corr_ofdm_x4;
596 	uint16_t	corr_ofdm_mrc_x4;
597 	uint16_t	corr_barker;
598 	uint16_t	corr_barker_mrc;
599 	uint16_t	corr_cck_x4;
600 	uint16_t	energy_ofdm_th;
601 } __packed;
602 
603 /* structure for command IWN_PHY_CALIB */
604 struct iwn_phy_calib_cmd {
605 	uint8_t		code;
606 #define IWN_SET_DIFF_GAIN	7
607 
608 	uint8_t		flags;
609 	uint16_t	reserved1;
610 	int8_t		gain[3];
611 #define IWN_GAIN_SET	(1 << 2)
612 
613 	uint8_t		reserved2;
614 } __packed;
615 
616 
617 /* structure for IWN_UC_READY notification */
618 #define IWN_NATTEN_GROUPS	5
619 struct iwn_ucode_info {
620 	uint8_t		minor;
621 	uint8_t		major;
622 	uint16_t	reserved1;
623 	uint8_t		revision[8];
624 	uint8_t		type;
625 	uint8_t		subtype;
626 #define IWN_UCODE_RUNTIME	0
627 #define IWN_UCODE_INIT		9
628 
629 	uint16_t	reserved2;
630 	uint32_t	logptr;
631 	uint32_t	errorptr;
632 	uint32_t	tstamp;
633 	uint32_t	valid;
634 
635 	/* the following fields are for UCODE_INIT only */
636 	int32_t		volt;
637 	struct {
638 		int32_t	chan20MHz;
639 		int32_t	chan40MHz;
640 	} __packed	temp[4];
641 	int32_t		atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS];
642 } __packed;
643 
644 /* structure for IWN_TX_DONE notification */
645 struct iwn_tx_stat {
646 	uint8_t		nframes;
647 	uint8_t		nkill;
648 	uint8_t		nrts;
649 	uint8_t		ntries;
650 	uint8_t		rate;
651 	uint8_t		rflags;
652 	uint16_t	xrflags;
653 	uint16_t	duration;
654 	uint16_t	reserved;
655 	uint32_t	power[2];
656 	uint32_t	status;
657 } __packed;
658 
659 /* structure for IWN_BEACON_MISSED notification */
660 struct iwn_beacon_missed {
661 	uint32_t	consecutive;
662 	uint32_t	total;
663 	uint32_t	expected;
664 	uint32_t	received;
665 } __packed;
666 
667 /* structure for IWN_AMPDU_RX_DONE notification */
668 struct iwn_rx_ampdu {
669 	uint16_t	len;
670 	uint16_t	reserved;
671 } __packed;
672 
673 /* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */
674 struct iwn_rx_stat {
675 	uint8_t		phy_len;
676 	uint8_t		cfg_phy_len;
677 #define IWN_STAT_MAXLEN	20
678 
679 	uint8_t		id;
680 	uint8_t		reserved1;
681 	uint64_t	tstamp;
682 	uint32_t	beacon;
683 	uint16_t	flags;
684 	uint16_t	chan;
685 	uint16_t	antenna;
686 	uint16_t	agc;
687 	uint8_t		rssi[6];
688 #define IWN_RSSI_TO_DBM	44
689 
690 	uint8_t		reserved2[22];
691 	uint8_t		rate;
692 	uint8_t		rflags;
693 	uint16_t	xrflags;
694 	uint16_t	len;
695 	uint16_t	reserve3;
696 } __packed;
697 
698 /* structure for IWN_START_SCAN notification */
699 struct iwn_start_scan {
700 	uint64_t	tstamp;
701 	uint32_t	tbeacon;
702 	uint8_t		chan;
703 	uint8_t		band;
704 	uint16_t	reserved;
705 	uint32_t	status;
706 } __packed;
707 
708 /* structure for IWN_STOP_SCAN notification */
709 struct iwn_stop_scan {
710 	uint8_t		nchan;
711 	uint8_t		status;
712 	uint8_t		reserved;
713 	uint8_t		chan;
714 	uint64_t	tsf;
715 } __packed;
716 
717 /* structure for IWN_{RX,BEACON}_STATISTICS notification */
718 struct iwn_rx_phy_stats {
719 	uint32_t	ina;
720 	uint32_t	fina;
721 	uint32_t	bad_plcp;
722 	uint32_t	bad_crc32;
723 	uint32_t	overrun;
724 	uint32_t	eoverrun;
725 	uint32_t	good_crc32;
726 	uint32_t	fa;
727 	uint32_t	bad_fina_sync;
728 	uint32_t	sfd_timeout;
729 	uint32_t	fina_timeout;
730 	uint32_t	no_rts_ack;
731 	uint32_t	rxe_limit;
732 	uint32_t	ack;
733 	uint32_t	cts;
734 	uint32_t	ba_resp;
735 	uint32_t	dsp_kill;
736 	uint32_t	bad_mh;
737 	uint32_t	rssi_sum;
738 	uint32_t	reserved;
739 } __packed;
740 
741 struct iwn_rx_general_stats {
742 	uint32_t	bad_cts;
743 	uint32_t	bad_ack;
744 	uint32_t	not_bss;
745 	uint32_t	filtered;
746 	uint32_t	bad_chan;
747 	uint32_t	beacons;
748 	uint32_t	missed_beacons;
749 	uint32_t	adc_saturated;	/* time in 0.8us */
750 	uint32_t	ina_searched;	/* time in 0.8us */
751 	uint32_t	noise[3];
752 	uint32_t	flags;
753 	uint32_t	load;
754 	uint32_t	fa;
755 	uint32_t	rssi[3];
756 	uint32_t	energy[3];
757 } __packed;
758 
759 struct iwn_rx_ht_phy_stats {
760 	uint32_t	bad_plcp;
761 	uint32_t	overrun;
762 	uint32_t	eoverrun;
763 	uint32_t	good_crc32;
764 	uint32_t	bad_crc32;
765 	uint32_t	bad_mh;
766 	uint32_t	good_ampdu_crc32;
767 	uint32_t	ampdu;
768 	uint32_t	fragment;
769 	uint32_t	reserved;
770 } __packed;
771 
772 struct iwn_rx_stats {
773 	struct iwn_rx_phy_stats		ofdm;
774 	struct iwn_rx_phy_stats		cck;
775 	struct iwn_rx_general_stats	general;
776 	struct iwn_rx_ht_phy_stats	ht;
777 } __packed;
778 
779 struct iwn_tx_stats {
780 	uint32_t	preamble;
781 	uint32_t	rx_detected;
782 	uint32_t	bt_defer;
783 	uint32_t	bt_kill;
784 	uint32_t	short_len;
785 	uint32_t	cts_timeout;
786 	uint32_t	ack_timeout;
787 	uint32_t	exp_ack;
788 	uint32_t	ack;
789 	uint32_t	msdu;
790 	uint32_t	busrt_err1;
791 	uint32_t	burst_err2;
792 	uint32_t	cts_collision;
793 	uint32_t	ack_collision;
794 	uint32_t	ba_timeout;
795 	uint32_t	ba_resched;
796 	uint32_t	query_ampdu;
797 	uint32_t	query;
798 	uint32_t	query_ampdu_frag;
799 	uint32_t	query_mismatch;
800 	uint32_t	not_ready;
801 	uint32_t	underrun;
802 	uint32_t	bt_ht_kill;
803 	uint32_t	rx_ba_resp;
804 	uint32_t	reserved[2];
805 } __packed;
806 
807 struct iwn_general_stats {
808 	uint32_t	temp;
809 	uint32_t	temp_m;
810 	uint32_t	burst_check;
811 	uint32_t	burst;
812 	uint32_t	reserved1[4];
813 	uint32_t	sleep;
814 	uint32_t	slot_out;
815 	uint32_t	slot_idle;
816 	uint32_t	ttl_tstamp;
817 	uint32_t	tx_ant_a;
818 	uint32_t	tx_ant_b;
819 	uint32_t	exec;
820 	uint32_t	probe;
821 	uint32_t	reserved2[2];
822 	uint32_t	rx_enabled;
823 	uint32_t	reserved3[3];
824 } __packed;
825 
826 struct iwn_stats {
827 	uint32_t			flags;
828 	struct iwn_rx_stats		rx;
829 	struct iwn_tx_stats		tx;
830 	struct iwn_general_stats	general;
831 } __packed;
832 
833 
834 /* firmware image header */
835 struct iwn_firmware_hdr {
836 	uint32_t	version;
837 	uint32_t	main_textsz;
838 	uint32_t	main_datasz;
839 	uint32_t	init_textsz;
840 	uint32_t	init_datasz;
841 	uint32_t	boot_textsz;
842 } __packed;
843 
844 #define IWN_FW_MAIN_TEXT_MAXSZ	(96 * 1024)
845 #define IWN_FW_MAIN_DATA_MAXSZ	(40 * 1024)
846 #define IWN_FW_INIT_TEXT_MAXSZ	(96 * 1024)
847 #define IWN_FW_INIT_DATA_MAXSZ	(40 * 1024)
848 #define IWN_FW_BOOT_TEXT_MAXSZ	1024
849 
850 
851 /*
852  * Offsets into EEPROM.
853  */
854 #define IWN_EEPROM_MAC		0x015
855 #define IWN_EEPROM_DOMAIN	0x060
856 #define IWN_EEPROM_BAND1	0x063
857 #define IWN_EEPROM_BAND2	0x072
858 #define IWN_EEPROM_BAND3	0x080
859 #define IWN_EEPROM_BAND4	0x08d
860 #define IWN_EEPROM_BAND5	0x099
861 #define IWN_EEPROM_BAND6	0x0a0
862 #define IWN_EEPROM_BAND7	0x0a8
863 #define IWN_EEPROM_MAXPOW	0x0e8
864 #define IWN_EEPROM_VOLTAGE	0x0e9
865 #define IWN_EEPROM_BANDS	0x0ea
866 
867 struct iwn_eeprom_chan {
868 	uint8_t	flags;
869 #define IWN_EEPROM_CHAN_VALID	(1 << 0)
870 #define IWN_EEPROM_CHAN_IBSS	(1 << 1)
871 #define IWN_EEPROM_CHAN_ACTIVE	(1 << 3)
872 #define IWN_EEPROM_CHAN_RADAR	(1 << 4)
873 
874 	int8_t	maxpwr;
875 } __packed;
876 
877 #define IWN_NSAMPLES	3
878 struct iwn_eeprom_chan_samples {
879 	uint8_t	num;
880 	struct {
881 		uint8_t temp;
882 		uint8_t	gain;
883 		uint8_t	power;
884 		int8_t	pa_det;
885 	}	samples[IWN_NTXCHAINS][IWN_NSAMPLES];
886 } __packed;
887 
888 #define IWN_NBANDS	8
889 struct iwn_eeprom_band {
890 	uint8_t	lo;	/* low channel number */
891 	uint8_t	hi;	/* high channel number */
892 	struct	iwn_eeprom_chan_samples chans[2];
893 } __packed;
894 
895 #define IWN_CHAN_BANDS_COUNT	 7
896 #define IWN_MAX_CHAN_PER_BAND	14
897 static const struct iwn_chan_band {
898 	uint32_t	addr;	/* offset in EEPROM */
899 	uint8_t		nchan;
900 	uint8_t		chan[IWN_MAX_CHAN_PER_BAND];
901 } iwn_bands[] = {
902 	{ IWN_EEPROM_BAND1, 14,
903 	  { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
904 	{ IWN_EEPROM_BAND2, 13,
905 	  { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
906 	{ IWN_EEPROM_BAND3, 12,
907 	  { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
908 	{ IWN_EEPROM_BAND4, 11,
909 	  { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
910 	{ IWN_EEPROM_BAND5, 6,
911 	  { 145, 149, 153, 157, 161, 165 } },
912 	{ IWN_EEPROM_BAND6, 7,
913 	  { 1, 2, 3, 4, 5, 6, 7 } },
914 	{ IWN_EEPROM_BAND7, 11,
915 	  { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
916 };
917 
918 static const uint8_t iwn_ridx_to_plcp[] = {
919 	10, 20, 55, 110, /* CCK */
920 		0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
921 };
922 
923 /* allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
924 static const uint8_t iwn_prev_ridx[] = {
925 	0, 0, 1, 5, /* CCK */
926 		2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
927 };
928 
929 #define IWN_MAX_PWR_INDEX	107
930 
931 /*
932  * RF Tx gain values from highest to lowest power (values obtained from
933  * the reference driver.)
934  */
935 static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
936 	0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
937 		0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38,
938 		0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
939 		0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31,
940 		0x31, 0x30, 0x30, 0x30, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04,
941 		0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
942 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
946 };
947 
948 static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
949 	0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d,
950 		0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39,
951 		0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35,
952 		0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32,
953 		0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x25, 0x25, 0x25, 0x24, 0x24,
954 		0x24, 0x23, 0x23, 0x23, 0x22, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16,
955 		0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13,
956 		0x12, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x05, 0x05,
957 		0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01,
958 		0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
959 };
960 
961 /*
962  * DSP pre-DAC gain values from highest to lowest power (values obtained
963  * from the reference driver.)
964  */
965 static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = {
966 	0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
967 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
968 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
969 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
970 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
971 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
972 		0x6e, 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a,
973 		0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f,
974 		0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44,
975 		0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b
976 };
977 
978 static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = {
979 	0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
980 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
981 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
982 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
983 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
984 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
985 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
986 		0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
987 		0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
988 		0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e
989 };
990 
991 #define IWN_READ(sc, reg)						\
992 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
993 
994 #define IWN_WRITE(sc, reg, val)						\
995 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
996 
997 #define IWN_WRITE_REGION_4(sc, offset, datap, count)			\
998 	bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
999 	    (datap), (count))
1000