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