1173362Sbenjsc/* $FreeBSD$ */ 2173362Sbenjsc 3173362Sbenjsc/*- 4173362Sbenjsc * Copyright (c) 2006,2007 5173362Sbenjsc * Damien Bergamini <damien.bergamini@free.fr> 6173362Sbenjsc * 7173362Sbenjsc * Permission to use, copy, modify, and distribute this software for any 8173362Sbenjsc * purpose with or without fee is hereby granted, provided that the above 9173362Sbenjsc * copyright notice and this permission notice appear in all copies. 10173362Sbenjsc * 11173362Sbenjsc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12173362Sbenjsc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13173362Sbenjsc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14173362Sbenjsc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15173362Sbenjsc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16173362Sbenjsc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17173362Sbenjsc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18173362Sbenjsc */ 19173362Sbenjsc 20173362Sbenjsc#define WPI_TX_RING_COUNT 256 21173362Sbenjsc#define WPI_CMD_RING_COUNT 256 22173362Sbenjsc#define WPI_RX_RING_COUNT 64 23173362Sbenjsc 24173362Sbenjsc/* 25173362Sbenjsc * Rings must be aligned on a 16K boundary. 26173362Sbenjsc */ 27173362Sbenjsc#define WPI_RING_DMA_ALIGN 0x4000 28173362Sbenjsc 29173362Sbenjsc/* maximum scatter/gather */ 30173362Sbenjsc#define WPI_MAX_SCATTER 4 31173362Sbenjsc 32173362Sbenjsc/* maximum Rx buffer size */ 33173362Sbenjsc#define WPI_RBUF_SIZE ( 3 * 1024 ) /* XXX 3000 but must be aligned */ 34173362Sbenjsc 35173362Sbenjsc/* 36173362Sbenjsc * Control and status registers. 37173362Sbenjsc */ 38173362Sbenjsc#define WPI_HWCONFIG 0x000 39173362Sbenjsc#define WPI_INTR 0x008 40173362Sbenjsc#define WPI_MASK 0x00c 41173362Sbenjsc#define WPI_INTR_STATUS 0x010 42173362Sbenjsc#define WPI_GPIO_STATUS 0x018 43173362Sbenjsc#define WPI_RESET 0x020 44173362Sbenjsc#define WPI_GPIO_CTL 0x024 45173362Sbenjsc#define WPI_EEPROM_CTL 0x02c 46173362Sbenjsc#define WPI_EEPROM_STATUS 0x030 47177043Sthompsa#define WPI_UCODE_SET 0x058 48173362Sbenjsc#define WPI_UCODE_CLR 0x05c 49173362Sbenjsc#define WPI_TEMPERATURE 0x060 50173362Sbenjsc#define WPI_CHICKEN 0x100 51173362Sbenjsc#define WPI_PLL_CTL 0x20c 52173362Sbenjsc#define WPI_WRITE_MEM_ADDR 0x444 53173362Sbenjsc#define WPI_READ_MEM_ADDR 0x448 54173362Sbenjsc#define WPI_WRITE_MEM_DATA 0x44c 55173362Sbenjsc#define WPI_READ_MEM_DATA 0x450 56173362Sbenjsc#define WPI_TX_WIDX 0x460 57173362Sbenjsc#define WPI_TX_CTL(qid) (0x940 + (qid) * 8) 58173362Sbenjsc#define WPI_TX_BASE(qid) (0x944 + (qid) * 8) 59173362Sbenjsc#define WPI_TX_DESC(qid) (0x980 + (qid) * 80) 60173362Sbenjsc#define WPI_RX_CONFIG 0xc00 61173362Sbenjsc#define WPI_RX_BASE 0xc04 62173362Sbenjsc#define WPI_RX_WIDX 0xc20 63173362Sbenjsc#define WPI_RX_RIDX_PTR 0xc24 64173362Sbenjsc#define WPI_RX_CTL 0xcc0 65173362Sbenjsc#define WPI_RX_STATUS 0xcc4 66173362Sbenjsc#define WPI_TX_CONFIG(qid) (0xd00 + (qid) * 32) 67173362Sbenjsc#define WPI_TX_CREDIT(qid) (0xd04 + (qid) * 32) 68173362Sbenjsc#define WPI_TX_STATE(qid) (0xd08 + (qid) * 32) 69173362Sbenjsc#define WPI_TX_BASE_PTR 0xe80 70173362Sbenjsc#define WPI_MSG_CONFIG 0xe88 71173362Sbenjsc#define WPI_TX_STATUS 0xe90 72173362Sbenjsc 73173362Sbenjsc 74173362Sbenjsc/* 75173362Sbenjsc * NIC internal memory offsets. 76173362Sbenjsc */ 77173362Sbenjsc#define WPI_MEM_MODE 0x2e00 78173362Sbenjsc#define WPI_MEM_RA 0x2e04 79173362Sbenjsc#define WPI_MEM_TXCFG 0x2e10 80173362Sbenjsc#define WPI_MEM_MAGIC4 0x2e14 81173362Sbenjsc#define WPI_MEM_MAGIC5 0x2e20 82173362Sbenjsc#define WPI_MEM_BYPASS1 0x2e2c 83173362Sbenjsc#define WPI_MEM_BYPASS2 0x2e30 84173362Sbenjsc#define WPI_MEM_CLOCK1 0x3004 85173362Sbenjsc#define WPI_MEM_CLOCK2 0x3008 86173362Sbenjsc#define WPI_MEM_POWER 0x300c 87173362Sbenjsc#define WPI_MEM_PCIDEV 0x3010 88173362Sbenjsc#define WPI_MEM_HW_RADIO_OFF 0x3014 89173362Sbenjsc#define WPI_MEM_UCODE_CTL 0x3400 90173362Sbenjsc#define WPI_MEM_UCODE_SRC 0x3404 91173362Sbenjsc#define WPI_MEM_UCODE_DST 0x3408 92173362Sbenjsc#define WPI_MEM_UCODE_SIZE 0x340c 93173362Sbenjsc#define WPI_MEM_UCODE_BASE 0x3800 94173362Sbenjsc 95173362Sbenjsc#define WPI_MEM_TEXT_BASE 0x3490 96173362Sbenjsc#define WPI_MEM_TEXT_SIZE 0x3494 97173362Sbenjsc#define WPI_MEM_DATA_BASE 0x3498 98173362Sbenjsc#define WPI_MEM_DATA_SIZE 0x349c 99173362Sbenjsc 100173362Sbenjsc 101173362Sbenjsc/* possible flags for register WPI_HWCONFIG */ 102173362Sbenjsc#define WPI_HW_ALM_MB (1 << 8) 103173362Sbenjsc#define WPI_HW_ALM_MM (1 << 9) 104173362Sbenjsc#define WPI_HW_SKU_MRC (1 << 10) 105173362Sbenjsc#define WPI_HW_REV_D (1 << 11) 106173362Sbenjsc#define WPI_HW_TYPE_B (1 << 12) 107173362Sbenjsc 108173362Sbenjsc/* possible flags for registers WPI_READ_MEM_ADDR/WPI_WRITE_MEM_ADDR */ 109173362Sbenjsc#define WPI_MEM_4 ((sizeof (uint32_t) - 1) << 24) 110173362Sbenjsc 111173362Sbenjsc/* possible values for WPI_MEM_UCODE_DST */ 112173362Sbenjsc#define WPI_FW_TEXT 0x00000000 113173362Sbenjsc 114173362Sbenjsc/* possible flags for WPI_GPIO_STATUS */ 115173362Sbenjsc#define WPI_POWERED (1 << 9) 116173362Sbenjsc 117173362Sbenjsc/* possible flags for register WPI_RESET */ 118173362Sbenjsc#define WPI_NEVO_RESET (1 << 0) 119173362Sbenjsc#define WPI_SW_RESET (1 << 7) 120173362Sbenjsc#define WPI_MASTER_DISABLED (1 << 8) 121173362Sbenjsc#define WPI_STOP_MASTER (1 << 9) 122173362Sbenjsc 123173362Sbenjsc/* possible flags for register WPI_GPIO_CTL */ 124173362Sbenjsc#define WPI_GPIO_CLOCK (1 << 0) 125173362Sbenjsc#define WPI_GPIO_INIT (1 << 2) 126173362Sbenjsc#define WPI_GPIO_MAC (1 << 3) 127173362Sbenjsc#define WPI_GPIO_SLEEP (1 << 4) 128173362Sbenjsc#define WPI_GPIO_PWR_STATUS 0x07000000 129173362Sbenjsc#define WPI_GPIO_PWR_SLEEP (4 << 24) 130173362Sbenjsc 131173362Sbenjsc/* possible flags for register WPI_CHICKEN */ 132173362Sbenjsc#define WPI_CHICKEN_RXNOLOS (1 << 23) 133173362Sbenjsc 134173362Sbenjsc/* possible flags for register WPI_PLL_CTL */ 135173362Sbenjsc#define WPI_PLL_INIT (1 << 24) 136173362Sbenjsc 137173362Sbenjsc/* possible flags for register WPI_UCODE_CLR */ 138173362Sbenjsc#define WPI_RADIO_OFF (1 << 1) 139173362Sbenjsc#define WPI_DISABLE_CMD (1 << 2) 140173362Sbenjsc 141173362Sbenjsc/* possible flags for WPI_RX_STATUS */ 142173362Sbenjsc#define WPI_RX_IDLE (1 << 24) 143173362Sbenjsc 144173362Sbenjsc/* possible flags for register WPI_UC_CTL */ 145173362Sbenjsc#define WPI_UC_ENABLE (1 << 30) 146261455Seadler#define WPI_UC_RUN (1U << 31) 147173362Sbenjsc 148173362Sbenjsc/* possible flags for register WPI_INTR_CSR */ 149173362Sbenjsc#define WPI_ALIVE_INTR (1 << 0) 150173362Sbenjsc#define WPI_WAKEUP_INTR (1 << 1) 151173362Sbenjsc#define WPI_SW_ERROR (1 << 25) 152173362Sbenjsc#define WPI_TX_INTR (1 << 27) 153173362Sbenjsc#define WPI_HW_ERROR (1 << 29) 154261455Seadler#define WPI_RX_INTR (1U << 31) 155173362Sbenjsc 156173362Sbenjsc#define WPI_INTR_MASK \ 157173362Sbenjsc (WPI_SW_ERROR | WPI_HW_ERROR | WPI_TX_INTR | WPI_RX_INTR | \ 158173362Sbenjsc WPI_ALIVE_INTR | WPI_WAKEUP_INTR) 159173362Sbenjsc 160173362Sbenjsc/* possible flags for register WPI_TX_STATUS */ 161173362Sbenjsc#define WPI_TX_IDLE(qid) (1 << ((qid) + 24) | 1 << ((qid) + 16)) 162173362Sbenjsc 163173362Sbenjsc/* possible flags for register WPI_EEPROM_CTL */ 164173362Sbenjsc#define WPI_EEPROM_READY (1 << 0) 165173362Sbenjsc 166173362Sbenjsc/* possible flags for register WPI_EEPROM_STATUS */ 167173362Sbenjsc#define WPI_EEPROM_VERSION 0x00000007 168173362Sbenjsc#define WPI_EEPROM_LOCKED 0x00000180 169173362Sbenjsc 170173362Sbenjsc 171173362Sbenjscstruct wpi_shared { 172173362Sbenjsc uint32_t txbase[8]; 173173362Sbenjsc uint32_t next; 174173362Sbenjsc uint32_t reserved[2]; 175173362Sbenjsc} __packed; 176173362Sbenjsc 177173362Sbenjsc#define WPI_MAX_SEG_LEN 65520 178173362Sbenjscstruct wpi_tx_desc { 179173362Sbenjsc uint32_t flags; 180173362Sbenjsc#define WPI_PAD32(x) (roundup2(x, 4) - (x)) 181173362Sbenjsc 182173362Sbenjsc struct { 183173362Sbenjsc uint32_t addr; 184173362Sbenjsc uint32_t len; 185173362Sbenjsc } __attribute__((__packed__)) segs[WPI_MAX_SCATTER]; 186173362Sbenjsc uint8_t reserved[28]; 187173362Sbenjsc} __packed; 188173362Sbenjsc 189173362Sbenjscstruct wpi_tx_stat { 190173362Sbenjsc uint8_t nrts; 191173362Sbenjsc uint8_t ntries; 192173362Sbenjsc uint8_t nkill; 193173362Sbenjsc uint8_t rate; 194173362Sbenjsc uint32_t duration; 195173362Sbenjsc uint32_t status; 196173362Sbenjsc} __packed; 197173362Sbenjsc 198173362Sbenjscstruct wpi_rx_desc { 199173362Sbenjsc uint32_t len; 200173362Sbenjsc uint8_t type; 201173362Sbenjsc#define WPI_UC_READY 1 202173362Sbenjsc#define WPI_RX_DONE 27 203173362Sbenjsc#define WPI_TX_DONE 28 204173362Sbenjsc#define WPI_START_SCAN 130 205177043Sthompsa#define WPI_SCAN_RESULTS 131 206173362Sbenjsc#define WPI_STOP_SCAN 132 207173362Sbenjsc#define WPI_STATE_CHANGED 161 208173976Sbenjsc#define WPI_MISSED_BEACON 162 209173362Sbenjsc 210173362Sbenjsc uint8_t flags; 211173362Sbenjsc uint8_t idx; 212173362Sbenjsc uint8_t qid; 213173362Sbenjsc} __packed; 214173362Sbenjsc 215173362Sbenjscstruct wpi_rx_stat { 216173362Sbenjsc uint8_t len; 217173362Sbenjsc#define WPI_STAT_MAXLEN 20 218173362Sbenjsc 219173362Sbenjsc uint8_t id; 220173362Sbenjsc uint8_t rssi; /* received signal strength */ 221173362Sbenjsc#define WPI_RSSI_OFFSET 95 222173362Sbenjsc 223173362Sbenjsc uint8_t agc; /* access gain control */ 224173362Sbenjsc uint16_t signal; 225173362Sbenjsc uint16_t noise; 226173362Sbenjsc} __packed; 227173362Sbenjsc 228173362Sbenjscstruct wpi_rx_head { 229173362Sbenjsc uint16_t chan; 230173362Sbenjsc uint16_t flags; 231173362Sbenjsc uint8_t reserved; 232173362Sbenjsc uint8_t rate; 233173362Sbenjsc uint16_t len; 234173362Sbenjsc} __packed; 235173362Sbenjsc 236173362Sbenjscstruct wpi_rx_tail { 237173362Sbenjsc uint32_t flags; 238173362Sbenjsc#define WPI_RX_NO_CRC_ERR (1 << 0) 239173362Sbenjsc#define WPI_RX_NO_OVFL_ERR (1 << 1) 240173362Sbenjsc/* shortcut for the above */ 241173362Sbenjsc#define WPI_RX_NOERROR (WPI_RX_NO_CRC_ERR | WPI_RX_NO_OVFL_ERR) 242173362Sbenjsc uint64_t tstamp; 243173362Sbenjsc uint32_t tbeacon; 244173362Sbenjsc} __packed; 245173362Sbenjsc 246173362Sbenjscstruct wpi_tx_cmd { 247173362Sbenjsc uint8_t code; 248173362Sbenjsc#define WPI_CMD_CONFIGURE 16 249173362Sbenjsc#define WPI_CMD_ASSOCIATE 17 250173362Sbenjsc#define WPI_CMD_SET_WME 19 251173362Sbenjsc#define WPI_CMD_TSF 20 252173362Sbenjsc#define WPI_CMD_ADD_NODE 24 253173362Sbenjsc#define WPI_CMD_TX_DATA 28 254173362Sbenjsc#define WPI_CMD_MRR_SETUP 71 255173362Sbenjsc#define WPI_CMD_SET_LED 72 256173362Sbenjsc#define WPI_CMD_SET_POWER_MODE 119 257173362Sbenjsc#define WPI_CMD_SCAN 128 258173362Sbenjsc#define WPI_CMD_SET_BEACON 145 259173362Sbenjsc#define WPI_CMD_TXPOWER 151 260173362Sbenjsc#define WPI_CMD_BLUETOOTH 155 261173362Sbenjsc 262173362Sbenjsc uint8_t flags; 263173362Sbenjsc uint8_t idx; 264173362Sbenjsc uint8_t qid; 265173362Sbenjsc uint8_t data[360]; 266173362Sbenjsc} __packed; 267173362Sbenjsc 268173362Sbenjsc/* structure for WPI_CMD_CONFIGURE */ 269173362Sbenjscstruct wpi_config { 270173362Sbenjsc uint8_t myaddr[IEEE80211_ADDR_LEN]; 271173362Sbenjsc uint16_t reserved1; 272173362Sbenjsc uint8_t bssid[IEEE80211_ADDR_LEN]; 273173362Sbenjsc uint16_t reserved2; 274173362Sbenjsc uint8_t wlap_bssid_addr[6]; 275173362Sbenjsc uint16_t reserved3; 276173362Sbenjsc uint8_t mode; 277173362Sbenjsc#define WPI_MODE_HOSTAP 1 278173362Sbenjsc#define WPI_MODE_STA 3 279173362Sbenjsc#define WPI_MODE_IBSS 4 280173362Sbenjsc#define WPI_MODE_MONITOR 6 281173362Sbenjsc 282173362Sbenjsc uint8_t air_propogation; 283173362Sbenjsc uint16_t reserved4; 284173362Sbenjsc uint8_t ofdm_mask; 285173362Sbenjsc uint8_t cck_mask; 286173362Sbenjsc uint16_t associd; 287173362Sbenjsc uint32_t flags; 288173362Sbenjsc#define WPI_CONFIG_24GHZ (1 << 0) 289173362Sbenjsc#define WPI_CONFIG_CCK (1 << 1) 290173362Sbenjsc#define WPI_CONFIG_AUTO (1 << 2) 291173362Sbenjsc#define WPI_CONFIG_SHSLOT (1 << 4) 292173362Sbenjsc#define WPI_CONFIG_SHPREAMBLE (1 << 5) 293173362Sbenjsc#define WPI_CONFIG_NODIVERSITY (1 << 7) 294173362Sbenjsc#define WPI_CONFIG_ANTENNA_A (1 << 8) 295173362Sbenjsc#define WPI_CONFIG_ANTENNA_B (1 << 9) 296173362Sbenjsc#define WPI_CONFIG_TSF (1 << 15) 297173362Sbenjsc 298173362Sbenjsc uint32_t filter; 299173362Sbenjsc#define WPI_FILTER_PROMISC (1 << 0) 300173362Sbenjsc#define WPI_FILTER_CTL (1 << 1) 301173362Sbenjsc#define WPI_FILTER_MULTICAST (1 << 2) 302173362Sbenjsc#define WPI_FILTER_NODECRYPT (1 << 3) 303173362Sbenjsc#define WPI_FILTER_BSS (1 << 5) 304173362Sbenjsc#define WPI_FILTER_BEACON (1 << 6) 305173362Sbenjsc 306173362Sbenjsc uint8_t chan; 307173362Sbenjsc uint16_t reserved6; 308173362Sbenjsc} __packed; 309173362Sbenjsc 310173362Sbenjsc/* structure for command WPI_CMD_ASSOCIATE */ 311173362Sbenjscstruct wpi_assoc { 312173362Sbenjsc uint32_t flags; 313173362Sbenjsc uint32_t filter; 314173362Sbenjsc uint8_t ofdm_mask; 315173362Sbenjsc uint8_t cck_mask; 316173362Sbenjsc uint16_t reserved; 317173362Sbenjsc} __packed; 318173362Sbenjsc 319173362Sbenjsc/* structure for command WPI_CMD_SET_WME */ 320173362Sbenjscstruct wpi_wme_setup { 321173362Sbenjsc uint32_t flags; 322173362Sbenjsc struct { 323173362Sbenjsc uint16_t cwmin; 324173362Sbenjsc uint16_t cwmax; 325173362Sbenjsc uint8_t aifsn; 326173362Sbenjsc uint8_t reserved; 327173362Sbenjsc uint16_t txop; 328173362Sbenjsc } __packed ac[WME_NUM_AC]; 329173362Sbenjsc} __packed; 330173362Sbenjsc 331173362Sbenjsc/* structure for command WPI_CMD_TSF */ 332173362Sbenjscstruct wpi_cmd_tsf { 333173362Sbenjsc uint64_t tstamp; 334173362Sbenjsc uint16_t bintval; 335173362Sbenjsc uint16_t atim; 336173362Sbenjsc uint32_t binitval; 337173362Sbenjsc uint16_t lintval; 338173362Sbenjsc uint16_t reserved; 339173362Sbenjsc} __packed; 340173362Sbenjsc 341173362Sbenjsc/* structure for WPI_CMD_ADD_NODE */ 342173362Sbenjscstruct wpi_node_info { 343173362Sbenjsc uint8_t control; 344173362Sbenjsc#define WPI_NODE_UPDATE (1 << 0) 345173362Sbenjsc 346173362Sbenjsc uint8_t reserved1[3]; 347173362Sbenjsc uint8_t bssid[IEEE80211_ADDR_LEN]; 348173362Sbenjsc uint16_t reserved2; 349173362Sbenjsc uint8_t id; 350173362Sbenjsc#define WPI_ID_BSS 0 351173362Sbenjsc#define WPI_ID_BROADCAST 24 352173362Sbenjsc 353173362Sbenjsc uint8_t flags; 354173362Sbenjsc uint16_t reserved3; 355173362Sbenjsc uint16_t key_flags; 356173362Sbenjsc uint8_t tkip; 357173362Sbenjsc uint8_t reserved4; 358173362Sbenjsc uint16_t ttak[5]; 359173362Sbenjsc uint16_t reserved5; 360173362Sbenjsc uint8_t key[IEEE80211_KEYBUF_SIZE]; 361173362Sbenjsc uint32_t action; 362173362Sbenjsc#define WPI_ACTION_SET_RATE 4 363173362Sbenjsc uint32_t mask; 364173362Sbenjsc uint16_t tid; 365173362Sbenjsc uint8_t rate; 366173362Sbenjsc uint8_t antenna; 367173362Sbenjsc#define WPI_ANTENNA_A (1<<6) 368173362Sbenjsc#define WPI_ANTENNA_B (1<<7) 369173362Sbenjsc#define WPI_ANTENNA_BOTH (WPI_ANTENNA_A|WPI_ANTENNA_B) 370173362Sbenjsc uint8_t add_imm; 371173362Sbenjsc uint8_t del_imm; 372173362Sbenjsc uint16_t add_imm_start; 373173362Sbenjsc} __packed; 374173362Sbenjsc 375173362Sbenjsc/* structure for command WPI_CMD_TX_DATA */ 376173362Sbenjscstruct wpi_cmd_data { 377173362Sbenjsc uint16_t len; 378173362Sbenjsc uint16_t lnext; 379173362Sbenjsc uint32_t flags; 380173362Sbenjsc#define WPI_TX_NEED_RTS (1 << 1) 381173362Sbenjsc#define WPI_TX_NEED_CTS (1 << 2) 382173362Sbenjsc#define WPI_TX_NEED_ACK (1 << 3) 383173362Sbenjsc#define WPI_TX_FULL_TXOP (1 << 7) 384173362Sbenjsc#define WPI_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */ 385173362Sbenjsc#define WPI_TX_AUTO_SEQ (1 << 13) 386173362Sbenjsc#define WPI_TX_INSERT_TSTAMP (1 << 16) 387173362Sbenjsc 388173362Sbenjsc uint8_t rate; 389173362Sbenjsc uint8_t id; 390173362Sbenjsc uint8_t tid; 391173362Sbenjsc uint8_t security; 392173362Sbenjsc uint8_t key[IEEE80211_KEYBUF_SIZE]; 393173362Sbenjsc uint8_t tkip[IEEE80211_WEP_MICLEN]; 394173362Sbenjsc uint32_t fnext; 395173362Sbenjsc uint32_t lifetime; 396173362Sbenjsc#define WPI_LIFETIME_INFINITE 0xffffffff 397173362Sbenjsc uint8_t ofdm_mask; 398173362Sbenjsc uint8_t cck_mask; 399173362Sbenjsc uint8_t rts_ntries; 400173362Sbenjsc uint8_t data_ntries; 401173362Sbenjsc uint16_t timeout; 402173362Sbenjsc uint16_t txop; 403173362Sbenjsc struct ieee80211_frame wh; 404173362Sbenjsc} __packed; 405173362Sbenjsc 406173362Sbenjsc/* structure for command WPI_CMD_SET_BEACON */ 407173362Sbenjscstruct wpi_cmd_beacon { 408173362Sbenjsc uint16_t len; 409173362Sbenjsc uint16_t reserved1; 410173362Sbenjsc uint32_t flags; /* same as wpi_cmd_data */ 411173362Sbenjsc uint8_t rate; 412173362Sbenjsc uint8_t id; 413173362Sbenjsc uint8_t reserved2[30]; 414173362Sbenjsc uint32_t lifetime; 415173362Sbenjsc uint8_t ofdm_mask; 416173362Sbenjsc uint8_t cck_mask; 417173362Sbenjsc uint16_t reserved3[3]; 418173362Sbenjsc uint16_t tim; 419173362Sbenjsc uint8_t timsz; 420173362Sbenjsc uint8_t reserved4; 421173362Sbenjsc struct ieee80211_frame wh; 422173362Sbenjsc} __packed; 423173362Sbenjsc 424173976Sbenjsc/* structure for notification WPI_MISSED_BEACON */ 425173976Sbenjscstruct wpi_missed_beacon { 426173976Sbenjsc uint32_t consecutive; 427173976Sbenjsc uint32_t total; 428173976Sbenjsc uint32_t expected; 429173976Sbenjsc uint32_t received; 430173976Sbenjsc} __packed; 431173976Sbenjsc 432173976Sbenjsc 433173362Sbenjsc/* structure for WPI_CMD_MRR_SETUP */ 434173362Sbenjscstruct wpi_mrr_setup { 435173362Sbenjsc uint8_t which; 436173362Sbenjsc#define WPI_MRR_CTL 0 437173362Sbenjsc#define WPI_MRR_DATA 1 438173362Sbenjsc 439173362Sbenjsc uint8_t reserved[3]; 440173362Sbenjsc 441173362Sbenjsc struct { 442173362Sbenjsc uint8_t signal; 443173362Sbenjsc uint8_t flags; 444173362Sbenjsc uint8_t ntries; 445173362Sbenjsc uint8_t next; 446173362Sbenjsc#define WPI_OFDM6 0 447173362Sbenjsc#define WPI_OFDM54 7 448173362Sbenjsc#define WPI_CCK1 8 449173362Sbenjsc#define WPI_CCK2 9 450173362Sbenjsc#define WPI_CCK11 11 451173362Sbenjsc 452173362Sbenjsc } __attribute__((__packed__)) rates[WPI_CCK11 + 1]; 453173362Sbenjsc} __packed; 454173362Sbenjsc 455173362Sbenjsc/* structure for WPI_CMD_SET_LED */ 456173362Sbenjscstruct wpi_cmd_led { 457173362Sbenjsc uint32_t unit; /* multiplier (in usecs) */ 458173362Sbenjsc uint8_t which; 459173362Sbenjsc#define WPI_LED_ACTIVITY 1 460173362Sbenjsc#define WPI_LED_LINK 2 461173362Sbenjsc 462173362Sbenjsc uint8_t off; 463173362Sbenjsc uint8_t on; 464173362Sbenjsc uint8_t reserved; 465173362Sbenjsc} __packed; 466173362Sbenjsc 467173362Sbenjsc/* structure for WPI_CMD_SET_POWER_MODE */ 468173362Sbenjscstruct wpi_power { 469173362Sbenjsc uint32_t flags; 470173362Sbenjsc#define WPI_POWER_CAM 0 /* constantly awake mode */ 471173362Sbenjsc uint32_t rx_timeout; 472173362Sbenjsc uint32_t tx_timeout; 473173362Sbenjsc uint32_t sleep[5]; 474173362Sbenjsc} __packed; 475173362Sbenjsc 476173362Sbenjsc/* structure for command WPI_CMD_SCAN */ 477173362Sbenjscstruct wpi_scan_hdr { 478173362Sbenjsc uint16_t len; 479173362Sbenjsc uint8_t reserved1; 480173362Sbenjsc uint8_t nchan; 481173362Sbenjsc uint16_t quiet; 482173362Sbenjsc uint16_t threshold; 483173362Sbenjsc uint16_t promotion; 484173362Sbenjsc uint16_t reserved2; 485173362Sbenjsc uint32_t maxtimeout; 486173362Sbenjsc uint32_t suspend; 487173362Sbenjsc uint32_t flags; 488173362Sbenjsc uint32_t filter; 489173362Sbenjsc 490173362Sbenjscstruct { 491173362Sbenjsc uint16_t len; 492173362Sbenjsc uint16_t lnext; 493173362Sbenjsc uint32_t flags; 494173362Sbenjsc uint8_t rate; 495173362Sbenjsc uint8_t id; 496173362Sbenjsc uint8_t tid; 497173362Sbenjsc uint8_t security; 498173362Sbenjsc uint8_t key[IEEE80211_KEYBUF_SIZE]; 499173362Sbenjsc uint8_t tkip[IEEE80211_WEP_MICLEN]; 500173362Sbenjsc uint32_t fnext; 501173362Sbenjsc uint32_t lifetime; 502173362Sbenjsc uint8_t ofdm_mask; 503173362Sbenjsc uint8_t cck_mask; 504173362Sbenjsc uint8_t rts_ntries; 505173362Sbenjsc uint8_t data_ntries; 506173362Sbenjsc uint16_t timeout; 507173362Sbenjsc uint16_t txop; 508173362Sbenjsc} tx __attribute__((__packed__)); 509173362Sbenjsc 510173362Sbenjsc#define WPI_SCAN_MAX_ESSIDS 4 511173362Sbenjsc struct { 512173362Sbenjsc uint8_t id; 513173362Sbenjsc uint8_t esslen; 514173362Sbenjsc uint8_t essid[32]; 515173362Sbenjsc }scan_essids[WPI_SCAN_MAX_ESSIDS]; 516173362Sbenjsc /* followed by probe request body */ 517173362Sbenjsc /* followed by nchan x wpi_scan_chan */ 518173362Sbenjsc} __packed; 519173362Sbenjsc 520173362Sbenjscstruct wpi_scan_chan { 521173362Sbenjsc uint8_t flags; 522173362Sbenjsc uint8_t chan; 523173362Sbenjsc#define WPI_CHAN_ACTIVE (1 << 0) 524173362Sbenjsc#define WPI_CHAN_DIRECT (1 << 1) 525173362Sbenjsc uint8_t gain_radio; 526173362Sbenjsc uint8_t gain_dsp; 527173362Sbenjsc uint16_t active; /* msecs */ 528173362Sbenjsc uint16_t passive; /* msecs */ 529173362Sbenjsc} __packed; 530173362Sbenjsc 531173362Sbenjsc/* structure for WPI_CMD_BLUETOOTH */ 532173362Sbenjscstruct wpi_bluetooth { 533173362Sbenjsc uint8_t flags; 534173362Sbenjsc uint8_t lead; 535173362Sbenjsc uint8_t kill; 536173362Sbenjsc uint8_t reserved; 537173362Sbenjsc uint32_t ack; 538173362Sbenjsc uint32_t cts; 539173362Sbenjsc} __packed; 540173362Sbenjsc 541173362Sbenjsc/* structure for command WPI_CMD_TXPOWER */ 542173362Sbenjscstruct wpi_cmd_txpower { 543173362Sbenjsc 544173362Sbenjsc uint8_t band; 545173362Sbenjsc#define WPI_RATE_5GHZ 0 546173362Sbenjsc#define WPI_RATE_2GHZ 1 547173362Sbenjsc uint8_t reserved; 548173362Sbenjsc uint16_t channel; 549173362Sbenjsc 550173362Sbenjsc#define WPI_RATE_MAPPING_COUNT 12 551173362Sbenjsc struct { 552173362Sbenjsc uint8_t rate; 553173362Sbenjsc uint8_t gain_radio; 554173362Sbenjsc uint8_t gain_dsp; 555173362Sbenjsc uint8_t reserved; 556173362Sbenjsc } __packed rates [WPI_RATE_MAPPING_COUNT]; 557173362Sbenjsc 558173362Sbenjsc} __packed; 559173362Sbenjsc 560173362Sbenjsc 561173362Sbenjsc 562173362Sbenjsc#define WPI_FW_MAIN_TEXT_MAXSZ (80 * 1024 ) 563173362Sbenjsc#define WPI_FW_MAIN_DATA_MAXSZ (32 * 1024 ) 564173362Sbenjsc#define WPI_FW_INIT_TEXT_MAXSZ (80 * 1024 ) 565173362Sbenjsc#define WPI_FW_INIT_DATA_MAXSZ (32 * 1024 ) 566173362Sbenjsc#define WPI_FW_BOOT_TEXT_MAXSZ 1024 567173362Sbenjsc 568173362Sbenjsc#define WPI_FW_UPDATED (1 << 31 ) 569173362Sbenjsc 570173362Sbenjsc/* firmware image header */ 571173362Sbenjscstruct wpi_firmware_hdr { 572173362Sbenjsc 573173362Sbenjsc#define WPI_FW_MINVERSION 2144 574173362Sbenjsc 575173362Sbenjsc uint32_t version; 576173362Sbenjsc uint32_t rtextsz; 577173362Sbenjsc uint32_t rdatasz; 578173362Sbenjsc uint32_t itextsz; 579173362Sbenjsc uint32_t idatasz; 580173362Sbenjsc uint32_t btextsz; 581173362Sbenjsc} __packed; 582173362Sbenjsc 583173362Sbenjsc/* structure for WPI_UC_READY notification */ 584173362Sbenjscstruct wpi_ucode_info { 585173362Sbenjsc uint32_t version; 586173362Sbenjsc uint8_t revision[8]; 587173362Sbenjsc uint8_t type; 588173362Sbenjsc uint8_t subtype; 589173362Sbenjsc uint16_t reserved; 590173362Sbenjsc uint32_t logptr; 591173362Sbenjsc uint32_t errorptr; 592173362Sbenjsc uint32_t timestamp; 593173362Sbenjsc uint32_t valid; 594173362Sbenjsc} __packed; 595173362Sbenjsc 596173362Sbenjsc/* structure for WPI_START_SCAN notification */ 597173362Sbenjscstruct wpi_start_scan { 598173362Sbenjsc uint64_t tstamp; 599173362Sbenjsc uint32_t tbeacon; 600173362Sbenjsc uint8_t chan; 601173362Sbenjsc uint8_t band; 602173362Sbenjsc uint16_t reserved; 603173362Sbenjsc uint32_t status; 604173362Sbenjsc} __packed; 605173362Sbenjsc 606173362Sbenjsc/* structure for WPI_STOP_SCAN notification */ 607173362Sbenjscstruct wpi_stop_scan { 608173362Sbenjsc uint8_t nchan; 609173362Sbenjsc uint8_t status; 610173362Sbenjsc uint8_t reserved; 611173362Sbenjsc uint8_t chan; 612173362Sbenjsc uint64_t tsf; 613173362Sbenjsc} __packed; 614173362Sbenjsc 615173362Sbenjsc#define WPI_EEPROM_MAC 0x015 616173362Sbenjsc#define WPI_EEPROM_REVISION 0x035 617173362Sbenjsc#define WPI_EEPROM_CAPABILITIES 0x045 618173362Sbenjsc#define WPI_EEPROM_TYPE 0x04a 619173362Sbenjsc#define WPI_EEPROM_DOMAIN 0x060 620173362Sbenjsc#define WPI_EEPROM_BAND1 0x063 621173362Sbenjsc#define WPI_EEPROM_BAND2 0x072 622173362Sbenjsc#define WPI_EEPROM_BAND3 0x080 623173362Sbenjsc#define WPI_EEPROM_BAND4 0x08d 624173362Sbenjsc#define WPI_EEPROM_BAND5 0x099 625173362Sbenjsc#define WPI_EEPROM_POWER_GRP 0x100 626173362Sbenjsc 627173362Sbenjscstruct wpi_eeprom_chan { 628173362Sbenjsc uint8_t flags; 629173362Sbenjsc#define WPI_EEPROM_CHAN_VALID (1<<0) 630173362Sbenjsc#define WPI_EEPROM_CHAN_IBSS (1<<1) 631173362Sbenjsc#define WPI_EEPROM_CHAN_ACTIVE (1<<3) 632173362Sbenjsc#define WPI_EEPROM_CHAN_RADAR (1<<4) 633173362Sbenjsc 634173362Sbenjsc int8_t maxpwr; 635173362Sbenjsc} __packed; 636173362Sbenjsc 637173362Sbenjscstruct wpi_eeprom_sample { 638173362Sbenjsc uint8_t index; 639173362Sbenjsc int8_t power; 640173362Sbenjsc uint16_t volt; 641173362Sbenjsc}; 642173362Sbenjsc 643173362Sbenjsc#define WPI_POWER_GROUPS_COUNT 5 644173362Sbenjsc 645173362Sbenjscstruct wpi_eeprom_group { 646173362Sbenjsc struct wpi_eeprom_sample samples[5]; 647173362Sbenjsc int32_t coef[5]; 648173362Sbenjsc int32_t corr[5]; 649173362Sbenjsc int8_t maxpwr; 650173362Sbenjsc uint8_t chan; 651173362Sbenjsc int16_t temp; 652173362Sbenjsc} __packed; 653173362Sbenjsc 654173362Sbenjsc#define WPI_CHAN_BANDS_COUNT 5 655173362Sbenjsc#define WPI_MAX_CHAN_PER_BAND 14 656173362Sbenjsc 657173362Sbenjscstatic const struct wpi_chan_band { 658173362Sbenjsc uint32_t addr; /* offset in EEPROM */ 659173362Sbenjsc uint8_t nchan; 660173362Sbenjsc uint8_t chan[WPI_MAX_CHAN_PER_BAND]; 661173362Sbenjsc} wpi_bands[5] = { 662173362Sbenjsc { WPI_EEPROM_BAND1, 14, 663173362Sbenjsc { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }}, 664173362Sbenjsc { WPI_EEPROM_BAND2, 13, 665173362Sbenjsc { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 }}, 666173362Sbenjsc { WPI_EEPROM_BAND3, 12, 667173362Sbenjsc { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 }}, 668173362Sbenjsc { WPI_EEPROM_BAND4, 11, 669173362Sbenjsc { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }}, 670173362Sbenjsc { WPI_EEPROM_BAND5, 6, 671173362Sbenjsc { 145, 149, 153, 157, 161, 165 }} 672173362Sbenjsc}; 673173362Sbenjsc 674173362Sbenjsc#define WPI_MAX_PWR_INDEX 77 675173362Sbenjsc 676173362Sbenjsc/* 677173362Sbenjsc * RF Tx gain values from highest to lowest power (values obtained from 678173362Sbenjsc * the reference driver.) 679173362Sbenjsc */ 680173362Sbenjscstatic const uint8_t wpi_rf_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = { 681173362Sbenjsc 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xbb, 0xbb, 0xbb, 682173362Sbenjsc 0xbb, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xd3, 0xd3, 0xb3, 0xb3, 0xb3, 683173362Sbenjsc 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x73, 0xeb, 0xeb, 0xeb, 684173362Sbenjsc 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xab, 0xab, 0xab, 0x8b, 685173362Sbenjsc 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xa3, 686173362Sbenjsc 0xa3, 0xa3, 0xa3, 0x83, 0x83, 0x83, 0x83, 0x63, 0x63, 0x63, 0x63, 687173362Sbenjsc 0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23, 0x03, 0x03, 0x03, 688173362Sbenjsc 0x03 689173362Sbenjsc}; 690173362Sbenjsc 691173362Sbenjscstatic const uint8_t wpi_rf_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = { 692173362Sbenjsc 0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xbb, 0xbb, 0x9b, 0x9b, 0x7b, 0x7b, 693173362Sbenjsc 0x7b, 0x7b, 0x5b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1b, 0x1b, 694173362Sbenjsc 0x1b, 0x73, 0x73, 0x73, 0x53, 0x53, 0x53, 0x53, 0x53, 0x33, 0x33, 695173362Sbenjsc 0x33, 0x33, 0x13, 0x13, 0x13, 0x13, 0x13, 0xab, 0xab, 0xab, 0x8b, 696173362Sbenjsc 0x8b, 0x8b, 0x8b, 0x6b, 0x6b, 0x6b, 0x6b, 0x4b, 0x4b, 0x4b, 0x4b, 697173362Sbenjsc 0x2b, 0x2b, 0x2b, 0x2b, 0x0b, 0x0b, 0x0b, 0x0b, 0x83, 0x83, 0x63, 698173362Sbenjsc 0x63, 0x63, 0x63, 0x43, 0x43, 0x43, 0x43, 0x23, 0x23, 0x23, 0x23, 699173362Sbenjsc 0x03 700173362Sbenjsc}; 701173362Sbenjsc 702173362Sbenjsc/* 703173362Sbenjsc * DSP pre-DAC gain values from highest to lowest power (values obtained 704173362Sbenjsc * from the reference driver.) 705173362Sbenjsc */ 706173362Sbenjscstatic const uint8_t wpi_dsp_gain_2ghz[WPI_MAX_PWR_INDEX + 1] = { 707173362Sbenjsc 0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x6e, 0x69, 0x62, 0x7d, 0x73, 0x6c, 708173362Sbenjsc 0x63, 0x77, 0x6f, 0x69, 0x61, 0x5c, 0x6a, 0x64, 0x78, 0x71, 0x6b, 709173362Sbenjsc 0x7d, 0x77, 0x70, 0x6a, 0x65, 0x61, 0x5b, 0x6b, 0x79, 0x73, 0x6d, 710173362Sbenjsc 0x7f, 0x79, 0x73, 0x6c, 0x66, 0x60, 0x5c, 0x6e, 0x68, 0x62, 0x74, 711173362Sbenjsc 0x7d, 0x77, 0x71, 0x6b, 0x65, 0x60, 0x71, 0x6a, 0x66, 0x5f, 0x71, 712173362Sbenjsc 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 713173362Sbenjsc 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 0x5f, 0x71, 0x6a, 0x66, 714173362Sbenjsc 0x5f 715173362Sbenjsc}; 716173362Sbenjsc 717173362Sbenjscstatic const uint8_t wpi_dsp_gain_5ghz[WPI_MAX_PWR_INDEX + 1] = { 718173362Sbenjsc 0x7f, 0x78, 0x72, 0x77, 0x65, 0x71, 0x66, 0x72, 0x67, 0x75, 0x6b, 719173362Sbenjsc 0x63, 0x5c, 0x6c, 0x7d, 0x76, 0x6d, 0x66, 0x60, 0x5a, 0x68, 0x62, 720173362Sbenjsc 0x5c, 0x76, 0x6f, 0x68, 0x7e, 0x79, 0x71, 0x69, 0x63, 0x76, 0x6f, 721173362Sbenjsc 0x68, 0x62, 0x74, 0x6d, 0x66, 0x62, 0x5d, 0x71, 0x6b, 0x63, 0x78, 722173362Sbenjsc 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 723173362Sbenjsc 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x6b, 0x63, 0x78, 724173362Sbenjsc 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 0x78, 0x71, 0x6b, 0x63, 725173362Sbenjsc 0x78 726173362Sbenjsc}; 727173362Sbenjsc 728173362Sbenjsc 729173362Sbenjsc#define WPI_READ(sc, reg) \ 730173362Sbenjsc bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) 731173362Sbenjsc 732173362Sbenjsc#define WPI_WRITE(sc, reg, val) \ 733173362Sbenjsc bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) 734173362Sbenjsc 735173362Sbenjsc#define WPI_WRITE_REGION_4(sc, offset, datap, count) \ 736173362Sbenjsc bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset), \ 737173362Sbenjsc (datap), (count)) 738