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