1 /* $FreeBSD$ */ 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 EDCA_NUM_AC 4 22 23 #define IWN_TX_RING_COUNT 256 24 #define IWN_RX_RING_COUNT 64 25 26 #define IWN_NTXQUEUES 16 27 #define IWN_NTXCHAINS 2 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_BITS "\20\1ALIVE\2WAKEUP\3SW_RX\6CT_REACHED\7RF_TOGGLED" \ 148 "\32SW_ERROR\34TX_INTR\36HW_ERROR\40RX_INTR" 149 150 #define IWN_INTR_MASK \ 151 (IWN_SW_ERROR | IWN_HW_ERROR | IWN_TX_INTR | IWN_RX_INTR | \ 152 IWN_ALIVE_INTR | IWN_WAKEUP_INTR | IWN_SW_RX_INTR | \ 153 IWN_CT_REACHED | IWN_RF_TOGGLED) 154 155 /* possible flags for register IWN_INTR_STATUS */ 156 #define IWN_STATUS_TXQ(x) (1 << (x)) 157 #define IWN_STATUS_RXQ(x) (1 << ((x) + 16)) 158 #define IWN_STATUS_PRI (1 << 30) 159 /* shortcuts for the above */ 160 #define IWN_TX_STATUS_INTR \ 161 (IWN_STATUS_TXQ(0) | IWN_STATUS_TXQ(1) | IWN_STATUS_TXQ(6)) 162 #define IWN_RX_STATUS_INTR \ 163 (IWN_STATUS_RXQ(0) | IWN_STATUS_RXQ(1) | IWN_STATUS_RXQ(2) | \ 164 IWN_STATUS_PRI) 165 166 /* possible flags for register IWN_TX_STATUS */ 167 #define IWN_TX_IDLE(qid) (1 << ((qid) + 24) | 1 << ((qid) + 16)) 168 169 /* possible flags/masks for register IWN_EEPROM_CTL */ 170 #define IWN_EEPROM_READY (1 << 0) 171 #define IWN_EEPROM_MSK (1 << 1) 172 173 /* possible flags for register IWN_TXQ_STATUS */ 174 #define IWN_TXQ_STATUS_ACTIVE 0x0007fc01 175 176 /* possible flags for register IWN_MEM_POWER */ 177 #define IWN_POWER_RESET (1 << 26) 178 179 /* possible flags for register IWN_MEM_TEXT_SIZE */ 180 #define IWN_FW_UPDATED (1 << 31) 181 182 /* possible flags for device-specific PCI register 0xe8 */ 183 #define IWN_DIS_NOSNOOP (1 << 11) 184 185 /* possible flags for device-specific PCI register 0xf0 */ 186 #define IWN_ENA_L1 (1 << 1) 187 188 189 #define IWN_TX_WINDOW 64 190 struct iwn_shared { 191 uint16_t len[IWN_NTXQUEUES][512]; /* 16KB total */ 192 uint16_t closed_count; 193 uint16_t closed_rx_count; 194 uint16_t finished_count; 195 uint16_t finished_rx_count; 196 uint32_t reserved[2]; 197 } __packed; 198 199 struct iwn_tx_desc { 200 uint32_t flags; 201 struct { 202 uint32_t w1; 203 uint32_t w2; 204 uint32_t w3; 205 } __packed segs[IWN_MAX_SCATTER / 2]; 206 /* pad to 128 bytes */ 207 uint32_t reserved; 208 } __packed; 209 210 #define IWN_SET_DESC_NSEGS(d, x) \ 211 (d)->flags = htole32(((x) & 0x1f) << 24) 212 213 /* set a segment physical address and length in a Tx descriptor */ 214 #define IWN_SET_DESC_SEG(d, n, addr, size) do { \ 215 if ((n) & 1) { \ 216 (d)->segs[(n) / 2].w2 |= \ 217 htole32(((addr) & 0xffff) << 16); \ 218 (d)->segs[(n) / 2].w3 = \ 219 htole32((((addr) >> 16) & 0xffff) | (size) << 20); \ 220 } else { \ 221 (d)->segs[(n) / 2].w1 = htole32(addr); \ 222 (d)->segs[(n) / 2].w2 = htole32((size) << 4); \ 223 } \ 224 } while (0) 225 226 struct iwn_rx_desc { 227 uint32_t len; 228 uint8_t type; 229 #define IWN_UC_READY 1 230 #define IWN_ADD_NODE_DONE 24 231 #define IWN_TX_DONE 28 232 #define IWN_START_SCAN 130 233 #define IWN_STOP_SCAN 132 234 #define IWN_RX_STATISTICS 156 235 #define IWN_BEACON_STATISTICS 157 236 #define IWN_STATE_CHANGED 161 237 #define IWN_BEACON_MISSED 162 238 #define IWN_AMPDU_RX_START 192 239 #define IWN_AMPDU_RX_DONE 193 240 #define IWN_RX_DONE 195 241 242 uint8_t flags; 243 uint8_t idx; 244 uint8_t qid; 245 } __packed; 246 247 /* possible Rx status flags */ 248 #define IWN_RX_NO_CRC_ERR (1 << 0) 249 #define IWN_RX_NO_OVFL_ERR (1 << 1) 250 /* shortcut for the above */ 251 #define IWN_RX_NOERROR (IWN_RX_NO_CRC_ERR | IWN_RX_NO_OVFL_ERR) 252 253 struct iwn_tx_cmd { 254 uint8_t code; 255 #define IWN_CMD_CONFIGURE 0x10 /* REPLY_RXON */ 256 #define IWN_CMD_ASSOCIATE 0x11 /* REPLY_RXON_ASSOC */ 257 #define IWN_CMD_EDCA_PARAMS 0x13 /* REPLY_QOS_PARAM */ 258 #define IWN_CMD_TSF 0x14 /* REPLY_RXON_TIMING */ 259 #define IWN_CMD_ADD_NODE 0x18 /* REPLY_ADD_STA */ 260 #define IWN_CMD_TX_DATA 0x1c /* REPLY_TX */ 261 #define IWN_CMD_TX_LINK_QUALITY 0x4e /* REPLY_TX_LINK_QUALITY_CMD */ 262 #define IWN_CMD_SET_LED 0x48 /* REPLY_LEDS_CMD */ 263 #define IWN_CMD_SET_POWER_MODE 0x77 /* POWER_TABLE_CMD */ 264 #define IWN_CMD_SCAN 0x80 /* REPLY_SCAN_CMD */ 265 #define IWN_CMD_TXPOWER 0x97 /* REPLY_TX_PWR_TABLE_CMD */ 266 #define IWN_CMD_BLUETOOTH 0x9b /* REPLY_BT_CONFIG */ 267 #define IWN_CMD_GET_STATISTICS 0x9c /* REPLY_STATISTICS_CMD */ 268 #define IWN_CMD_SET_CRITICAL_TEMP 0xa4 /* REPLY_CT_KILL_CONFIG_CMD */ 269 #define IWN_SENSITIVITY 0xa8 /* SENSITIVITY_CMD */ 270 #define IWN_PHY_CALIB 0xb0 /* REPLY_PHY_CALIBRATION_CMD */ 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 (aka RXON) */ 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 uint8_t unused4; /* air propagation */ 291 uint16_t rxchain; 292 #define IWN_RXCHAIN_VALID 0x000e /* which antennae are valid */ 293 #define IWN_RXCHAIN_VALID_S 1 294 #define IWN_RXCHAIN_FORCE 0x0070 295 #define IWN_RXCHAIN_FORCE_S 4 296 #define IWN_RXCHAIN_FORCE_MIMO 0x0380 297 #define IWN_RXCHAIN_FORCE_MIMO_S 7 298 #define IWN_RXCHAIN_CNT 0x0c00 299 #define IWN_RXCHAIN_CNT_S 10 300 #define IWN_RXCHAIN_MIMO_CNT 0x3000 301 #define IWN_RXCHAIN_MIMO_CNT_S 12 302 #define IWN_RXCHAIN_MIMO_FORCE 0x4000 303 #define IWN_RXCHAIN_MIMO_FORCE_S 14 304 uint8_t ofdm_mask; /* basic rates */ 305 uint8_t cck_mask; /* basic rates */ 306 uint16_t associd; 307 uint32_t flags; 308 #define IWN_CONFIG_24GHZ 0x00000001 /* band */ 309 #define IWN_CONFIG_CCK 0x00000002 /* modulation */ 310 #define IWN_CONFIG_AUTO 0x00000004 /* 2.4-only auto-detect */ 311 #define IWN_CONFIG_HTPROT 0x00000008 /* xmit with HT protection */ 312 #define IWN_CONFIG_SHSLOT 0x00000010 /* short slot time */ 313 #define IWN_CONFIG_SHPREAMBLE 0x00000020 /* short premable */ 314 #define IWN_CONFIG_NODIVERSITY 0x00000080 /* disable antenna diversity */ 315 #define IWN_CONFIG_ANTENNA_A 0x00000100 316 #define IWN_CONFIG_ANTENNA_B 0x00000200 317 #define IWN_CONFIG_RADAR 0x00001000 /* enable radar detect */ 318 #define IWN_CONFIG_NARROW 0x00002000 /* MKK narrow band select */ 319 #define IWN_CONFIG_TSF 0x00008000 320 #define IWN_CONFIG_HT 0x06400000 321 #define IWN_CONFIG_HT20 0x02000000 322 #define IWN_CONFIG_HT40U 0x04000000 323 #define IWN_CONFIG_HT40D 0x04400000 324 uint32_t filter; 325 #define IWN_FILTER_PROMISC (1 << 0) /* pass all data frames */ 326 #define IWN_FILTER_CTL (1 << 1) /* pass ctl+mgt frames */ 327 #define IWN_FILTER_MULTICAST (1 << 2) /* pass multi-cast frames */ 328 #define IWN_FILTER_NODECRYPT (1 << 3) /* pass unicast undecrypted */ 329 #define IWN_FILTER_BSS (1 << 5) /* station is associated */ 330 #define IWN_FILTER_ALLBEACONS (1 << 6) /* pass overlapping bss beacons 331 (must be associated) */ 332 uint16_t chan; /* IEEE channel # of control/primary */ 333 uint8_t ht_single_mask; /* single-stream basic rates */ 334 uint8_t ht_dual_mask; /* dual-stream basic rates */ 335 } __packed; 336 337 /* structure for command IWN_CMD_ASSOCIATE */ 338 struct iwn_assoc { 339 uint32_t flags; 340 uint32_t filter; 341 uint8_t ofdm_mask; 342 uint8_t cck_mask; 343 uint16_t reserved; 344 } __packed; 345 346 /* structure for command IWN_CMD_EDCA_PARAMS */ 347 struct iwn_edca_params { 348 uint32_t flags; 349 #define IWN_EDCA_UPDATE (1 << 0) 350 #define IWN_EDCA_TXOP (1 << 4) 351 352 struct { 353 uint16_t cwmin; 354 uint16_t cwmax; 355 uint8_t aifsn; 356 uint8_t reserved; 357 uint16_t txoplimit; 358 } __packed ac[EDCA_NUM_AC]; 359 } __packed; 360 361 /* structure for command IWN_CMD_TSF */ 362 struct iwn_cmd_tsf { 363 uint64_t tstamp; 364 uint16_t bintval; 365 uint16_t atim; 366 uint32_t binitval; 367 uint16_t lintval; 368 uint16_t reserved; 369 } __packed; 370 371 /* structure for command IWN_CMD_ADD_NODE */ 372 struct iwn_node_info { 373 uint8_t control; 374 #define IWN_NODE_UPDATE (1 << 0) 375 uint8_t reserved1[3]; 376 uint8_t macaddr[IEEE80211_ADDR_LEN]; 377 uint16_t reserved2; 378 uint8_t id; 379 #define IWN_ID_BSS 0 380 #define IWN_ID_BROADCAST 31 381 uint8_t flags; 382 #define IWN_FLAG_SET_KEY (1 << 0) 383 uint16_t reserved3; 384 uint16_t security; 385 uint8_t tsc2; /* TKIP TSC2 */ 386 uint8_t reserved4; 387 uint16_t ttak[5]; 388 uint16_t reserved5; 389 uint8_t key[IEEE80211_KEYBUF_SIZE]; 390 uint32_t htflags; 391 #define IWN_MAXRXAMPDU_S 19 392 #define IWN_MPDUDENSITY_S 23 393 uint32_t mask; 394 uint16_t tid; 395 uint8_t rate; /* legacy rate/MCS */ 396 #define IWN_RATE_MCS 0x08 /* or'd to indicate MCS */ 397 uint8_t rflags; 398 #define IWN_RFLAG_HT (1 << 0) /* use HT modulation */ 399 #define IWN_RFLAG_CCK (1 << 1) /* use CCK modulation */ 400 #define IWN_RFLAG_HT40 (1 << 3) /* use dual-stream */ 401 #define IWN_RFLAG_SGI (1 << 5) /* use short GI */ 402 #define IWN_RFLAG_ANT_A (1 << 6) /* start on antenna port A */ 403 #define IWN_RFLAG_ANT_B (1 << 7) /* start on antenna port B */ 404 uint8_t add_imm; 405 uint8_t del_imm; 406 uint16_t add_imm_start; 407 uint32_t reserved6; 408 } __packed; 409 410 /* structure for command IWN_CMD_TX_DATA */ 411 struct iwn_cmd_data { 412 uint16_t len; 413 uint16_t lnext; 414 uint32_t flags; 415 #define IWN_TX_NEED_RTS (1 << 1) 416 #define IWN_TX_NEED_CTS (1 << 2) 417 #define IWN_TX_NEED_ACK (1 << 3) 418 #define IWN_TX_USE_NODE_RATE (1 << 4) 419 #define IWN_TX_FULL_TXOP (1 << 7) 420 #define IWN_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */ 421 #define IWN_TX_AUTO_SEQ (1 << 13) 422 #define IWN_TX_INSERT_TSTAMP (1 << 16) 423 #define IWN_TX_NEED_PADDING (1 << 20) 424 425 uint8_t ntries; 426 uint8_t bluetooth; 427 uint16_t reserved1; 428 uint8_t rate; 429 uint8_t rflags; 430 uint16_t xrflags; 431 uint8_t id; 432 uint8_t security; 433 #define IWN_CIPHER_WEP40 1 434 #define IWN_CIPHER_CCMP 2 435 #define IWN_CIPHER_TKIP 3 436 #define IWN_CIPHER_WEP104 9 437 438 uint8_t ridx; 439 uint8_t reserved2; 440 uint8_t key[IEEE80211_KEYBUF_SIZE]; 441 uint16_t fnext; 442 uint16_t reserved3; 443 uint32_t lifetime; 444 #define IWN_LIFETIME_INFINITE 0xffffffff 445 446 uint32_t loaddr; 447 uint8_t hiaddr; 448 uint8_t rts_ntries; 449 uint8_t data_ntries; 450 uint8_t tid; 451 uint16_t timeout; 452 uint16_t txop; 453 } __packed; 454 455 /* structure for command IWN_CMD_TX_LINK_QUALITY */ 456 #define IWN_MAX_TX_RETRIES 16 457 struct iwn_cmd_link_quality { 458 uint8_t id; 459 uint8_t reserved1; 460 uint16_t ctl; 461 uint8_t flags; 462 uint8_t mimo; /* MIMO delimiter */ 463 uint8_t ssmask; /* single stream antenna mask */ 464 uint8_t dsmask; /* dual stream antenna mask */ 465 uint8_t ridx[EDCA_NUM_AC];/* starting rate index */ 466 uint16_t ampdu_limit; /* tx aggregation time limit */ 467 uint8_t ampdu_disable; 468 uint8_t ampdu_max; /* frame count limit */ 469 uint32_t reserved2; 470 struct { 471 uint8_t rate; 472 #define IWN_RATE_CCK1 0 473 #define IWN_RATE_CCK11 3 474 #define IWN_RATE_OFDM6 4 475 #define IWN_RATE_OFDM54 11 476 uint8_t rflags; 477 uint16_t xrflags; 478 } table[IWN_MAX_TX_RETRIES]; 479 uint32_t reserved3; 480 } __packed; 481 482 /* structure for command IWN_CMD_SET_LED */ 483 struct iwn_cmd_led { 484 uint32_t unit; /* multiplier (in usecs) */ 485 uint8_t which; 486 #define IWN_LED_ACTIVITY 1 487 #define IWN_LED_LINK 2 488 489 uint8_t off; 490 uint8_t on; 491 uint8_t reserved; 492 } __packed; 493 494 /* structure for command IWN_CMD_SET_POWER_MODE */ 495 struct iwn_power { 496 uint16_t flags; 497 #define IWN_POWER_CAM 0 /* constantly awake mode */ 498 499 uint8_t alive; 500 uint8_t debug; 501 uint32_t rx_timeout; 502 uint32_t tx_timeout; 503 uint32_t sleep[5]; 504 uint32_t beacons; 505 } __packed; 506 507 /* structures for command IWN_CMD_SCAN */ 508 struct iwn_scan_essid { 509 uint8_t id; 510 uint8_t len; 511 uint8_t data[IEEE80211_NWID_LEN]; 512 } __packed; 513 514 struct iwn_scan_hdr { 515 uint16_t len; 516 uint8_t reserved1; 517 uint8_t nchan; 518 uint16_t quiet; 519 uint16_t plcp_threshold; 520 uint16_t crc_threshold; 521 uint16_t rxchain; 522 uint32_t max_svc; /* background scans */ 523 uint32_t pause_svc; /* background scans */ 524 uint32_t flags; 525 uint32_t filter; 526 527 /* followed by a struct iwn_cmd_data */ 528 /* followed by an array of 4x struct iwn_scan_essid */ 529 /* followed by probe request body */ 530 /* followed by nchan x struct iwn_scan_chan */ 531 } __packed; 532 533 struct iwn_scan_chan { 534 uint8_t flags; 535 #define IWN_CHAN_ACTIVE (1 << 0) 536 #define IWN_CHAN_DIRECT (1 << 1) 537 538 uint8_t chan; 539 uint8_t rf_gain; 540 uint8_t dsp_gain; 541 uint16_t active; /* msecs */ 542 uint16_t passive; /* msecs */ 543 } __packed; 544 545 /* structure for command IWN_CMD_TXPOWER */ 546 #define IWN_RIDX_MAX 32 547 struct iwn_cmd_txpower { 548 uint8_t band; 549 uint8_t reserved1; 550 uint8_t chan; 551 uint8_t reserved2; 552 struct { 553 uint8_t rf_gain[IWN_NTXCHAINS]; 554 uint8_t dsp_gain[IWN_NTXCHAINS]; 555 } power[IWN_RIDX_MAX + 1]; 556 } __packed; 557 558 /* structure for command IWN_CMD_BLUETOOTH */ 559 struct iwn_bluetooth { 560 uint8_t flags; 561 uint8_t lead; 562 uint8_t kill; 563 uint8_t reserved; 564 uint32_t ack; 565 uint32_t cts; 566 } __packed; 567 568 /* structure for command IWN_CMD_SET_CRITICAL_TEMP */ 569 struct iwn_critical_temp { 570 uint32_t reserved; 571 uint32_t tempM; 572 uint32_t tempR; 573 /* degK <-> degC conversion macros */ 574 #define IWN_CTOK(c) ((c) + 273) 575 #define IWN_KTOC(k) ((k) - 273) 576 #define IWN_CTOMUK(c) (((c) * 1000000) + 273150000) 577 } __packed; 578 579 /* structure for command IWN_SENSITIVITY */ 580 struct iwn_sensitivity_cmd { 581 uint16_t which; 582 #define IWN_SENSITIVITY_DEFAULTTBL 0 583 #define IWN_SENSITIVITY_WORKTBL 1 584 585 uint16_t energy_cck; 586 uint16_t energy_ofdm; 587 uint16_t corr_ofdm_x1; 588 uint16_t corr_ofdm_mrc_x1; 589 uint16_t corr_cck_mrc_x4; 590 uint16_t corr_ofdm_x4; 591 uint16_t corr_ofdm_mrc_x4; 592 uint16_t corr_barker; 593 uint16_t corr_barker_mrc; 594 uint16_t corr_cck_x4; 595 uint16_t energy_ofdm_th; 596 } __packed; 597 598 /* structure for command IWN_PHY_CALIB */ 599 struct iwn_phy_calib_cmd { 600 uint8_t code; 601 #define IWN_SET_DIFF_GAIN 7 602 603 uint8_t flags; 604 uint16_t reserved1; 605 int8_t gain[3]; 606 #define IWN_GAIN_SET (1 << 2) 607 608 uint8_t reserved2; 609 } __packed; 610 611 612 /* structure for IWN_UC_READY notification */ 613 #define IWN_NATTEN_GROUPS 5 614 struct iwn_ucode_info { 615 uint8_t minor; 616 uint8_t major; 617 uint16_t reserved1; 618 uint8_t revision[8]; 619 uint8_t type; 620 uint8_t subtype; 621 #define IWN_UCODE_RUNTIME 0 622 #define IWN_UCODE_INIT 9 623 624 uint16_t reserved2; 625 uint32_t logptr; 626 uint32_t errorptr; 627 uint32_t tstamp; 628 uint32_t valid; 629 630 /* the following fields are for UCODE_INIT only */ 631 int32_t volt; 632 struct { 633 int32_t chan20MHz; 634 int32_t chan40MHz; 635 } __packed temp[4]; 636 int32_t atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS]; 637 } __packed; 638 639 /* structure for IWN_TX_DONE notification */ 640 struct iwn_tx_stat { 641 uint8_t nframes; 642 uint8_t nkill; 643 uint8_t nrts; 644 uint8_t ntries; 645 uint8_t rate; 646 uint8_t rflags; 647 uint16_t xrflags; 648 uint16_t duration; 649 uint16_t reserved; 650 uint32_t power[2]; 651 uint32_t status; 652 #define IWN_TX_SUCCESS 0x00 653 #define IWN_TX_FAIL 0x80 /* all failures have 0x80 set */ 654 #define IWN_TX_FAIL_SHORT_LIMIT 0x82 /* too many RTS retries */ 655 #define IWN_TX_FAIL_LONG_LIMIT 0x83 /* too many retries */ 656 #define IWN_TX_FAIL_FIFO_UNDERRRUN 0x84 /* tx fifo not kept running */ 657 #define IWN_TX_FAIL_DEST_IN_PS 0x88 /* sta found in power save */ 658 #define IWN_TX_FAIL_TX_LOCKED 0x90 /* waiting to see traffic */ 659 } __packed; 660 661 /* structure for IWN_BEACON_MISSED notification */ 662 struct iwn_beacon_missed { 663 uint32_t consecutive; 664 uint32_t total; 665 uint32_t expected; 666 uint32_t received; 667 } __packed; 668 669 /* structure for IWN_AMPDU_RX_DONE notification */ 670 struct iwn_rx_ampdu { 671 uint16_t len; 672 uint16_t reserved; 673 } __packed; 674 675 /* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */ 676 struct iwn_rx_stat { 677 uint8_t phy_len; 678 uint8_t cfg_phy_len; 679 #define IWN_STAT_MAXLEN 20 680 681 uint8_t id; 682 uint8_t reserved1; 683 uint64_t tstamp; 684 uint32_t beacon; 685 uint16_t flags; 686 uint16_t chan; 687 uint16_t antenna; 688 uint16_t agc; 689 uint8_t rssi[6]; 690 #define IWN_RSSI_TO_DBM 44 691 692 uint8_t reserved2[22]; 693 uint8_t rate; 694 uint8_t rflags; 695 uint16_t xrflags; 696 uint16_t len; 697 uint16_t reserve3; 698 } __packed; 699 700 /* structure for IWN_START_SCAN notification */ 701 struct iwn_start_scan { 702 uint64_t tstamp; 703 uint32_t tbeacon; 704 uint8_t chan; 705 uint8_t band; 706 uint16_t reserved; 707 uint32_t status; 708 } __packed; 709 710 /* structure for IWN_STOP_SCAN notification */ 711 struct iwn_stop_scan { 712 uint8_t nchan; 713 uint8_t status; 714 uint8_t reserved; 715 uint8_t chan; 716 uint64_t tsf; 717 } __packed; 718 719 /* structure for IWN_{RX,BEACON}_STATISTICS notification */ 720 struct iwn_rx_phy_stats { 721 uint32_t ina; 722 uint32_t fina; 723 uint32_t bad_plcp; 724 uint32_t bad_crc32; 725 uint32_t overrun; 726 uint32_t eoverrun; 727 uint32_t good_crc32; 728 uint32_t fa; 729 uint32_t bad_fina_sync; 730 uint32_t sfd_timeout; 731 uint32_t fina_timeout; 732 uint32_t no_rts_ack; 733 uint32_t rxe_limit; 734 uint32_t ack; 735 uint32_t cts; 736 uint32_t ba_resp; 737 uint32_t dsp_kill; 738 uint32_t bad_mh; 739 uint32_t rssi_sum; 740 uint32_t reserved; 741 } __packed; 742 743 struct iwn_rx_general_stats { 744 uint32_t bad_cts; 745 uint32_t bad_ack; 746 uint32_t not_bss; 747 uint32_t filtered; 748 uint32_t bad_chan; 749 uint32_t beacons; 750 uint32_t missed_beacons; 751 uint32_t adc_saturated; /* time in 0.8us */ 752 uint32_t ina_searched; /* time in 0.8us */ 753 uint32_t noise[3]; 754 uint32_t flags; 755 uint32_t load; 756 uint32_t fa; 757 uint32_t rssi[3]; 758 uint32_t energy[3]; 759 } __packed; 760 761 struct iwn_rx_ht_phy_stats { 762 uint32_t bad_plcp; 763 uint32_t overrun; 764 uint32_t eoverrun; 765 uint32_t good_crc32; 766 uint32_t bad_crc32; 767 uint32_t bad_mh; 768 uint32_t good_ampdu_crc32; 769 uint32_t ampdu; 770 uint32_t fragment; 771 uint32_t reserved; 772 } __packed; 773 774 struct iwn_rx_stats { 775 struct iwn_rx_phy_stats ofdm; 776 struct iwn_rx_phy_stats cck; 777 struct iwn_rx_general_stats general; 778 struct iwn_rx_ht_phy_stats ht; 779 } __packed; 780 781 struct iwn_tx_stats { 782 uint32_t preamble; 783 uint32_t rx_detected; 784 uint32_t bt_defer; 785 uint32_t bt_kill; 786 uint32_t short_len; 787 uint32_t cts_timeout; 788 uint32_t ack_timeout; 789 uint32_t exp_ack; 790 uint32_t ack; 791 uint32_t msdu; 792 uint32_t busrt_err1; 793 uint32_t burst_err2; 794 uint32_t cts_collision; 795 uint32_t ack_collision; 796 uint32_t ba_timeout; 797 uint32_t ba_resched; 798 uint32_t query_ampdu; 799 uint32_t query; 800 uint32_t query_ampdu_frag; 801 uint32_t query_mismatch; 802 uint32_t not_ready; 803 uint32_t underrun; 804 uint32_t bt_ht_kill; 805 uint32_t rx_ba_resp; 806 uint32_t reserved[2]; 807 } __packed; 808 809 struct iwn_general_stats { 810 uint32_t temp; 811 uint32_t temp_m; 812 uint32_t burst_check; 813 uint32_t burst; 814 uint32_t reserved1[4]; 815 uint32_t sleep; 816 uint32_t slot_out; 817 uint32_t slot_idle; 818 uint32_t ttl_tstamp; 819 uint32_t tx_ant_a; 820 uint32_t tx_ant_b; 821 uint32_t exec; 822 uint32_t probe; 823 uint32_t reserved2[2]; 824 uint32_t rx_enabled; 825 uint32_t reserved3[3]; 826 } __packed; 827 828 struct iwn_stats { 829 uint32_t flags; 830 struct iwn_rx_stats rx; 831 struct iwn_tx_stats tx; 832 struct iwn_general_stats general; 833 } __packed; 834 835 836 /* firmware image header */ 837 struct iwn_firmware_hdr { 838 uint32_t version; 839 uint32_t main_textsz; 840 uint32_t main_datasz; 841 uint32_t init_textsz; 842 uint32_t init_datasz; 843 uint32_t boot_textsz; 844 } __packed; 845 846 #define IWN_FW_MAIN_TEXT_MAXSZ (96 * 1024) 847 #define IWN_FW_MAIN_DATA_MAXSZ (40 * 1024) 848 #define IWN_FW_INIT_TEXT_MAXSZ (96 * 1024) 849 #define IWN_FW_INIT_DATA_MAXSZ (40 * 1024) 850 #define IWN_FW_BOOT_TEXT_MAXSZ 1024 851 852 853 /* 854 * Offsets into EEPROM. 855 */ 856 #define IWN_EEPROM_MAC 0x015 857 #define IWN_EEPROM_DOMAIN 0x060 858 #define IWN_EEPROM_BAND1 0x063 859 #define IWN_EEPROM_BAND2 0x072 860 #define IWN_EEPROM_BAND3 0x080 861 #define IWN_EEPROM_BAND4 0x08d 862 #define IWN_EEPROM_BAND5 0x099 863 #define IWN_EEPROM_BAND6 0x0a0 864 #define IWN_EEPROM_BAND7 0x0a8 865 #define IWN_EEPROM_MAXPOW 0x0e8 866 #define IWN_EEPROM_VOLTAGE 0x0e9 867 #define IWN_EEPROM_BANDS 0x0ea 868 869 struct iwn_eeprom_chan { 870 uint8_t flags; 871 #define IWN_EEPROM_CHAN_VALID (1 << 0) 872 #define IWN_EEPROM_CHAN_IBSS (1 << 1) /* adhoc permitted */ 873 /* NB: bit 2 is reserved */ 874 #define IWN_EEPROM_CHAN_ACTIVE (1 << 3) /* active/passive scan */ 875 #define IWN_EEPROM_CHAN_RADAR (1 << 4) /* DFS required */ 876 #define IWN_EEPROM_CHAN_WIDE (1 << 5) /* HT40 */ 877 #define IWN_EEPROM_CHAN_NARROW (1 << 6) /* HT20 */ 878 879 int8_t maxpwr; 880 } __packed; 881 882 #define IWN_NSAMPLES 3 883 struct iwn_eeprom_chan_samples { 884 uint8_t num; 885 struct { 886 uint8_t temp; 887 uint8_t gain; 888 uint8_t power; 889 int8_t pa_det; 890 } samples[IWN_NTXCHAINS][IWN_NSAMPLES]; 891 } __packed; 892 893 #define IWN_NBANDS 8 894 struct iwn_eeprom_band { 895 uint8_t lo; /* low channel number */ 896 uint8_t hi; /* high channel number */ 897 struct iwn_eeprom_chan_samples chans[2]; 898 } __packed; 899 900 #define IWN_MAX_PWR_INDEX 107 901 902 /* 903 * RF Tx gain values from highest to lowest power (values obtained from 904 * the reference driver.) 905 */ 906 static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { 907 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 908 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38, 909 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, 910 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 911 0x31, 0x30, 0x30, 0x30, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04, 912 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 917 }; 918 919 static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { 920 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 921 0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 922 0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 923 0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 924 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x25, 0x25, 0x25, 0x24, 0x24, 925 0x24, 0x23, 0x23, 0x23, 0x22, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 926 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 927 0x12, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x05, 0x05, 928 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 929 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 930 }; 931 932 /* 933 * DSP pre-DAC gain values from highest to lowest power (values obtained 934 * from the reference driver.) 935 */ 936 static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { 937 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 938 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 939 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 940 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 941 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 942 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 943 0x6e, 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 944 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 945 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 946 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b 947 }; 948 949 static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { 950 0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 951 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 952 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 953 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 954 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 955 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 956 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 957 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 958 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 959 0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e 960 }; 961 962 #define IWN_READ(sc, reg) \ 963 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) 964 965 #define IWN_WRITE(sc, reg, val) \ 966 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) 967 968 #define IWN_WRITE_REGION_4(sc, offset, datap, count) \ 969 bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset), \ 970 (datap), (count)) 971