1 /* $NetBSD: bwivar.h,v 1.11 2025/01/19 00:29:28 jmcneill Exp $ */ 2 /* $OpenBSD: bwivar.h,v 1.23 2008/02/25 20:36:54 mglocker Exp $ */ 3 4 /* 5 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Sepherosa Ziehau <sepherosa@gmail.com> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 3. Neither the name of The DragonFly Project nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific, prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.1 2007/09/08 06:15:54 sephe Exp $ 38 */ 39 40 #ifndef _DEV_IC_BWIVAR_H 41 #define _DEV_IC_BWIVAR_H 42 43 #define BWI_ALIGN 0x1000 44 #define BWI_RING_ALIGN BWI_ALIGN 45 #define BWI_BUS_SPACE_MAXADDR 0x3fffffff 46 47 #define BWI_TX_NRING 6 48 #define BWI_TXRX_NRING 6 49 #define BWI_TX_NDESC 128 50 #define BWI_RX_NDESC 64 51 #define BWI_TXSTATS_NDESC 64 52 #define BWI_TX_NSPRDESC 2 53 #define BWI_TX_DATA_RING 1 54 55 /* XXX Onoe/Sample/AMRR probably need different configuration */ 56 #define BWI_SHRETRY 7 57 #define BWI_LGRETRY 4 58 #define BWI_SHRETRY_FB 3 59 #define BWI_LGRETRY_FB 2 60 61 #define BWI_LED_EVENT_NONE -1 62 #define BWI_LED_EVENT_POLL 0 63 #define BWI_LED_EVENT_TX 1 64 #define BWI_LED_EVENT_RX 2 65 #define BWI_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2) 66 67 enum bwi_txpwrcb_type { 68 BWI_TXPWR_INIT = 0, 69 BWI_TXPWR_FORCE = 1, 70 BWI_TXPWR_CALIB = 2 71 }; 72 73 #define BWI_NOISE_FLOOR -95 /* TODO: noise floor calc */ 74 75 /* [TRC: Bizarreness. Cf. bwi_rxeof in OpenBSD's if_bwi.c and 76 DragonFlyBSD's bwi.c.] */ 77 #define BWI_FRAME_MIN_LEN(hdr) \ 78 ((hdr) + sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) 79 80 #define CSR_READ_4(sc, reg) \ 81 _bwi_read_4(sc, reg) 82 #define CSR_READ_2(sc, reg) \ 83 _bwi_read_2(sc, reg) 84 #define CSR_READ_MULTI_4(sc, reg, datap, count) \ 85 _bwi_read_multi_4(sc, reg, datap, count) 86 87 #define CSR_WRITE_4(sc, reg, val) \ 88 _bwi_write_4(sc, reg, val) 89 #define CSR_WRITE_2(sc, reg, val) \ 90 _bwi_write_2(sc, reg, val) 91 #define CSR_WRITE_MULTI_4(sc, reg, datap, count) \ 92 _bwi_write_multi_4(sc, reg, datap, count) 93 94 #define CSR_SETBITS_4(sc, reg, bits) \ 95 CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) | (bits)) 96 #define CSR_SETBITS_2(sc, reg, bits) \ 97 CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) | (bits)) 98 99 #define CSR_FILT_SETBITS_4(sc, reg, filt, bits) \ 100 CSR_WRITE_4((sc), (reg), (CSR_READ_4((sc), (reg)) & (filt)) | (bits)) 101 #define CSR_FILT_SETBITS_2(sc, reg, filt, bits) \ 102 CSR_WRITE_2((sc), (reg), (CSR_READ_2((sc), (reg)) & (filt)) | (bits)) 103 104 #define CSR_CLRBITS_4(sc, reg, bits) \ 105 CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) & ~(bits)) 106 #define CSR_CLRBITS_2(sc, reg, bits) \ 107 CSR_WRITE_2((sc), (reg), CSR_READ_2((sc), (reg)) & ~(bits)) 108 109 struct pool_cache; 110 struct workqueue; 111 112 struct bwi_desc32 { 113 /* Little endian */ 114 uint32_t ctrl; 115 uint32_t addr; /* BWI_DESC32_A_ */ 116 } __packed; 117 118 #define BWI_DESC32_A_FUNC_TXRX 0x1 119 #define BWI_DESC32_A_FUNC_MASK 0xc0000000 120 #define BWI_DESC32_A_ADDR_MASK 0x3fffffff 121 122 #define BWI_DESC32_C_BUFLEN_MASK 0x00001fff 123 #define BWI_DESC32_C_ADDRHI_MASK 0x00030000 124 #define BWI_DESC32_C_EOR (1 << 28) 125 #define BWI_DESC32_C_INTR (1 << 29) 126 #define BWI_DESC32_C_FRAME_END (1 << 30) 127 #define BWI_DESC32_C_FRAME_START (1 << 31) 128 129 struct bwi_desc64 { 130 /* Little endian */ 131 uint32_t ctrl0; 132 uint32_t ctrl1; 133 uint32_t addr_lo; 134 uint32_t addr_hi; 135 } __packed; 136 137 struct bwi_rxbuf_hdr { 138 /* Little endian */ 139 uint16_t rxh_buflen; /* exclude bwi_rxbuf_hdr */ 140 uint8_t rxh_pad1[2]; 141 uint16_t rxh_flags1; 142 uint8_t rxh_rssi; 143 uint8_t rxh_sq; 144 uint16_t rxh_phyinfo; /* BWI_RXH_PHYINFO_ */ 145 uint16_t rxh_flags3; 146 uint16_t rxh_flags2; /* BWI_RXH_F2_ */ 147 uint16_t rxh_tsf; 148 uint8_t rxh_pad3[14]; /* Padded to 30bytes */ 149 } __packed; 150 151 #define BWI_RXH_F1_BCM2053_RSSI (1 << 14) 152 #define BWI_RXH_F1_OFDM (1 << 0) 153 154 #define BWI_RXH_F2_TYPE2FRAME (1 << 2) 155 #define BWI_RXH_F2_INVALID (1 << 0) 156 157 #define BWI_RXH_F3_BCM2050_RSSI (1 << 10) 158 159 #define BWI_RXH_PHYINFO_LNAGAIN (3 << 14) 160 161 struct bwi_txbuf_hdr { 162 /* Little endian */ 163 uint32_t txh_mac_ctrl; /* BWI_TXH_MAC_C_ */ 164 uint8_t txh_fc[2]; 165 uint16_t txh_unknown1; 166 uint16_t txh_phy_ctrl; /* BWI_TXH_PHY_C_ */ 167 uint8_t txh_ivs[16]; 168 uint8_t txh_addr1[IEEE80211_ADDR_LEN]; 169 uint16_t txh_unknown2; 170 uint8_t txh_rts_fb_plcp[4]; 171 uint16_t txh_rts_fb_duration; 172 uint8_t txh_fb_plcp[4]; 173 uint16_t txh_fb_duration; 174 uint8_t txh_pad2[2]; 175 uint16_t txh_id; /* BWI_TXH_ID_ */ 176 uint16_t txh_unknown3; 177 uint8_t txh_rts_plcp[6]; 178 uint8_t txh_rts_fc[2]; 179 uint16_t txh_rts_duration; 180 uint8_t txh_rts_ra[IEEE80211_ADDR_LEN]; 181 uint8_t txh_rts_ta[IEEE80211_ADDR_LEN]; 182 uint8_t txh_pad3[2]; 183 uint8_t txh_plcp[6]; 184 } __packed; 185 186 #define BWI_TXH_ID_RING_MASK 0xe000 187 #define BWI_TXH_ID_IDX_MASK 0x1fff 188 189 #define BWI_TXH_PHY_C_OFDM (1 << 0) 190 #define BWI_TXH_PHY_C_SHPREAMBLE (1 << 4) 191 #define BWI_TXH_PHY_C_ANTMODE_MASK 0x0300 192 193 #define BWI_TXH_MAC_C_ACK (1 << 0) 194 #define BWI_TXH_MAC_C_FIRST_FRAG (1 << 3) 195 #define BWI_TXH_MAC_C_HWSEQ (1 << 4) 196 #define BWI_TXH_MAC_C_FB_OFDM (1 << 8) 197 198 struct bwi_txstats { 199 /* Little endian */ 200 uint8_t txs_pad1[4]; 201 uint16_t txs_id; 202 uint8_t txs_flags; 203 uint8_t txs_retry_cnt; 204 uint8_t txs_pad2[2]; 205 uint16_t txs_seq; 206 uint16_t txs_unknown; 207 uint8_t txs_pad3[2]; /* Padded to 16bytes */ 208 } __packed; 209 210 struct bwi_ring_data { 211 uint32_t rdata_txrx_ctrl; 212 bus_dma_segment_t rdata_seg; 213 bus_dmamap_t rdata_dmap; 214 bus_addr_t rdata_paddr; 215 void *rdata_desc; 216 }; 217 218 struct bwi_txbuf_data; 219 220 struct bwi_txbuf { 221 struct mbuf *tb_mbuf; 222 bus_dmamap_t tb_dmap; 223 224 struct ieee80211_node *tb_ni; 225 int tb_rate_idx[2]; 226 227 struct bwi_txbuf_data *tb_data; 228 STAILQ_ENTRY(bwi_txbuf) tb_entry; 229 }; 230 231 struct bwi_txbuf_data { 232 struct bwi_txbuf tbd_buf[BWI_TX_NDESC]; 233 int tbd_used; 234 int tbd_idx; 235 }; 236 237 struct bwi_rxbuf { 238 struct mbuf *rb_mbuf; 239 bus_addr_t rb_paddr; 240 bus_dmamap_t rb_dmap; 241 }; 242 243 struct bwi_rxbuf_data { 244 struct bwi_rxbuf rbd_buf[BWI_RX_NDESC]; 245 bus_dmamap_t rbd_tmp_dmap; 246 int rbd_idx; 247 }; 248 249 struct bwi_txstats_data { 250 bus_dma_segment_t stats_ring_seg; 251 bus_dmamap_t stats_ring_dmap; 252 bus_addr_t stats_ring_paddr; 253 void *stats_ring; 254 255 bus_dma_segment_t stats_seg; 256 bus_dmamap_t stats_dmap; 257 bus_addr_t stats_paddr; 258 struct bwi_txstats *stats; 259 260 uint32_t stats_ctrl_base; 261 int stats_idx; 262 }; 263 264 struct bwi_fwhdr { 265 /* Big endian */ 266 uint8_t fw_type; /* BWI_FW_T_ */ 267 uint8_t fw_gen; /* BWI_FW_GEN */ 268 uint8_t fw_pad[2]; 269 uint32_t fw_size; 270 #define fw_iv_cnt fw_size 271 } __packed; 272 273 #define BWI_FWHDR_SZ sizeof(struct bwi_fwhdr) 274 #define BWI_FW_VERSION3 3 275 #define BWI_FW_VERSION4 4 276 #define BWI_FW_VERSION3_REVMAX 0x128 277 #define BWI_FW_T_UCODE 'u' 278 #define BWI_FW_T_PCM 'p' 279 #define BWI_FW_T_IV 'i' 280 #define BWI_FW_GEN_1 1 281 #define BWI_FW_IV_OFS_MASK 0x7fff 282 #define BWI_FW_IV_IS_32BIT (1 << 15) 283 284 #define BWI_FW_NAME_FORMAT "v%d/%s%d.fw" 285 #define BWI_FW_UCODE_PREFIX "ucode" 286 #define BWI_FW_PCM_PREFIX "pcm" 287 #define BWI_FW_IV_PREFIX "b0g0initvals" 288 #define BWI_FW_IV_EXT_PREFIX "b0g0bsinitvals" 289 290 struct bwi_fw_image { 291 char fwi_name[64]; 292 uint8_t *fwi_data; 293 size_t fwi_size; 294 }; 295 296 struct bwi_fw_iv { 297 /* Big endian */ 298 uint16_t iv_ofs; 299 union { 300 uint32_t val32; 301 uint16_t val16; 302 } iv_val; 303 } __packed; 304 305 struct bwi_led { 306 uint8_t l_flags; /* BWI_LED_F_ */ 307 uint8_t l_act; /* BWI_LED_ACT_ */ 308 uint8_t l_mask; 309 }; 310 311 #define BWI_LED_F_ACTLOW 0x1 312 #define BWI_LED_F_BLINK 0x2 313 #define BWI_LED_F_POLLABLE 0x4 314 #define BWI_LED_F_SLOW 0x8 315 316 enum bwi_clock_mode { 317 BWI_CLOCK_MODE_SLOW, 318 BWI_CLOCK_MODE_FAST, 319 BWI_CLOCK_MODE_DYN 320 }; 321 322 struct bwi_regwin { 323 uint32_t rw_flags; /* BWI_REGWIN_F_ */ 324 uint16_t rw_type; /* BWI_REGWIN_T_ */ 325 uint8_t rw_id; 326 uint8_t rw_rev; 327 }; 328 329 #define BWI_REGWIN_F_EXIST 0x1 330 331 #define BWI_CREATE_REGWIN(rw, id, type, rev) \ 332 do { \ 333 (rw)->rw_flags = BWI_REGWIN_F_EXIST; \ 334 (rw)->rw_type = (type); \ 335 (rw)->rw_id = (id); \ 336 (rw)->rw_rev = (rev); \ 337 } while (0) 338 339 #define BWI_REGWIN_EXIST(rw) ((rw)->rw_flags & BWI_REGWIN_F_EXIST) 340 #define BWI_GPIO_REGWIN(sc) \ 341 (BWI_REGWIN_EXIST(&(sc)->sc_com_regwin) ? \ 342 &(sc)->sc_com_regwin : &(sc)->sc_bus_regwin) 343 344 struct bwi_mac; 345 346 struct bwi_phy { 347 enum ieee80211_phymode phy_mode; 348 int phy_rev; 349 int phy_version; 350 351 uint32_t phy_flags; /* BWI_PHY_F_ */ 352 uint16_t phy_tbl_ctrl; 353 uint16_t phy_tbl_data_lo; 354 uint16_t phy_tbl_data_hi; 355 356 void (*phy_init)(struct bwi_mac *); 357 }; 358 359 #define BWI_PHY_F_CALIBRATED 0x1 360 #define BWI_PHY_F_LINKED 0x2 361 #define BWI_CLEAR_PHY_FLAGS (BWI_PHY_F_CALIBRATED) 362 363 /* TX power control */ 364 struct bwi_tpctl { 365 uint16_t bbp_atten; /* BBP attenuation: 4bits */ 366 uint16_t rf_atten; /* RF attenuation */ 367 uint16_t tp_ctrl1; /* ??: 3bits */ 368 uint16_t tp_ctrl2; /* ??: 4bits */ 369 }; 370 371 #define BWI_RF_ATTEN_FACTOR 4 372 #define BWI_RF_ATTEN_MAX0 9 373 #define BWI_RF_ATTEN_MAX1 31 374 #define BWI_BBP_ATTEN_MAX 11 375 #define BWI_TPCTL1_MAX 7 376 377 struct bwi_rf_lo { 378 int8_t ctrl_lo; 379 int8_t ctrl_hi; 380 }; 381 382 struct bwi_rf { 383 uint16_t rf_type; /* BWI_RF_T_ */ 384 uint16_t rf_manu; 385 int rf_rev; 386 387 uint32_t rf_flags; /* BWI_RF_F_ */ 388 389 #define BWI_RFLO_MAX 56 390 struct bwi_rf_lo rf_lo[BWI_RFLO_MAX]; 391 uint8_t rf_lo_used[8]; 392 393 #define BWI_INVALID_NRSSI -1000 394 int16_t rf_nrssi[2]; /* Narrow RSSI */ 395 int32_t rf_nrssi_slope; 396 397 #define BWI_NRSSI_TBLSZ 64 398 int8_t rf_nrssi_table[BWI_NRSSI_TBLSZ]; 399 400 uint16_t rf_lo_gain; /* loopback gain */ 401 uint16_t rf_rx_gain; /* TRSW RX gain */ 402 403 uint16_t rf_calib; /* RF calibration value */ 404 uint rf_curchan; /* current channel */ 405 406 uint16_t rf_ctrl_rd; 407 int rf_ctrl_adj; 408 void (*rf_off)(struct bwi_mac *); 409 void (*rf_on)(struct bwi_mac *); 410 411 void (*rf_set_nrssi_thr)(struct bwi_mac *); 412 void (*rf_calc_nrssi_slope)(struct bwi_mac *); 413 int (*rf_calc_rssi) 414 (struct bwi_mac *, 415 const struct bwi_rxbuf_hdr *); 416 417 void (*rf_lo_update)(struct bwi_mac *); 418 419 #define BWI_TSSI_MAX 64 420 int8_t rf_txpower_map0[BWI_TSSI_MAX]; 421 /* Indexed by TSSI */ 422 int rf_idle_tssi0; 423 424 int8_t rf_txpower_map[BWI_TSSI_MAX]; 425 int rf_idle_tssi; 426 427 int rf_base_tssi; 428 429 int rf_txpower_max; /* dBm */ 430 431 int rf_ant_mode; /* BWI_ANT_MODE_ */ 432 }; 433 434 #define BWI_RF_F_INITED 0x1 435 #define BWI_RF_F_ON 0x2 436 #define BWI_RF_CLEAR_FLAGS (BWI_RF_F_INITED) 437 438 #define BWI_ANT_MODE_0 0 439 #define BWI_ANT_MODE_1 1 440 #define BWI_ANT_MODE_UNKN 2 441 #define BWI_ANT_MODE_AUTO 3 442 443 struct fw_image; 444 445 struct bwi_mac { 446 struct bwi_regwin mac_regwin; /* MUST be first field */ 447 #define mac_rw_flags mac_regwin.rw_flags 448 #define mac_type mac_regwin.rw_type 449 #define mac_id mac_regwin.rw_id 450 #define mac_rev mac_regwin.rw_rev 451 struct bwi_softc *mac_sc; 452 453 struct bwi_phy mac_phy; /* PHY I/F */ 454 struct bwi_rf mac_rf; /* RF I/F */ 455 456 struct bwi_tpctl mac_tpctl; /* TX power control */ 457 uint32_t mac_flags; /* BWI_MAC_F_ */ 458 459 struct bwi_fw_image mac_ucode_fwi; 460 struct bwi_fw_image mac_pcm_fwi; 461 struct bwi_fw_image mac_iv_fwi; 462 struct bwi_fw_image mac_iv_ext_fwi; 463 }; 464 465 #define mac_ucode mac_ucode_fwi.fwi_data 466 #define mac_ucode_size mac_ucode_fwi.fwi_size 467 #define mac_pcm mac_pcm_fwi.fwi_data 468 #define mac_pcm_size mac_pcm_fwi.fwi_size 469 #define mac_iv mac_iv_fwi.fwi_data 470 #define mac_iv_size mac_iv_fwi.fwi_size 471 #define mac_iv_ext mac_iv_ext_fwi.fwi_data 472 #define mac_iv_ext_size mac_iv_ext_fwi.fwi_size 473 474 #define BWI_MAC_F_BSWAP 0x1 475 #define BWI_MAC_F_TPCTL_INITED 0x2 476 #define BWI_MAC_F_HAS_TXSTATS 0x4 477 #define BWI_MAC_F_INITED 0x8 478 #define BWI_MAC_F_ENABLED 0x10 479 #define BWI_MAC_F_LOCKED 0x20 /* for debug */ 480 #define BWI_MAC_F_TPCTL_ERROR 0x40 481 #define BWI_MAC_F_PHYE_RESET 0x80 482 483 #define BWI_CREATE_MAC(mac, sc, id, rev) \ 484 do { \ 485 BWI_CREATE_REGWIN(&(mac)->mac_regwin, \ 486 (id), BWI_REGWIN_T_MAC, (rev)); \ 487 (mac)->mac_sc = (sc); \ 488 } while (0) 489 490 #define BWI_MAC_MAX 2 491 #define BWI_LED_MAX 4 492 493 enum bwi_bus_space { 494 BWI_BUS_SPACE_30BIT = 1, 495 BWI_BUS_SPACE_32BIT, 496 BWI_BUS_SPACE_64BIT 497 }; 498 499 #define BWI_TX_RADIOTAP_PRESENT \ 500 ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 501 (1 << IEEE80211_RADIOTAP_RATE) | \ 502 (1 << IEEE80211_RADIOTAP_CHANNEL)) 503 504 struct bwi_tx_radiotap_hdr { 505 struct ieee80211_radiotap_header wt_ihdr; 506 uint8_t wt_flags; 507 uint8_t wt_rate; 508 uint16_t wt_chan_freq; 509 uint16_t wt_chan_flags; 510 }; 511 512 #define BWI_RX_RADIOTAP_PRESENT \ 513 ((1 << IEEE80211_RADIOTAP_TSFT) | \ 514 (1 << IEEE80211_RADIOTAP_FLAGS) | \ 515 (1 << IEEE80211_RADIOTAP_RATE) | \ 516 (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 517 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 518 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 519 520 struct bwi_rx_radiotap_hdr { 521 struct ieee80211_radiotap_header wr_ihdr; 522 uint64_t wr_tsf; 523 uint8_t wr_flags; 524 uint8_t wr_rate; 525 uint16_t wr_chan_freq; 526 uint16_t wr_chan_flags; 527 int8_t wr_antsignal; 528 int8_t wr_antnoise; 529 /* TODO: sq */ 530 }; 531 532 /* [TRC: XXX amrr] */ 533 struct bwi_node { 534 struct ieee80211_node ni; 535 struct ieee80211_amrr_node amn; 536 }; 537 538 enum bwi_task_cmd { 539 BWI_TASK_NEWSTATE, 540 BWI_TASK_UPDATESLOT, 541 BWI_TASK_TX, 542 BWI_TASK_INIT, 543 BWI_TASK_CALIBRATE, 544 }; 545 546 #define BWI_TASK_COUNT 64 547 548 struct bwi_task { 549 struct work t_work; 550 struct ieee80211com *t_ic; 551 enum bwi_task_cmd t_cmd; 552 union { 553 struct { 554 enum ieee80211_state state; 555 int arg; 556 } t_newstate; 557 }; 558 }; 559 560 struct bwi_softc { 561 device_t sc_dev; 562 struct ethercom sc_ec; 563 struct ieee80211com sc_ic; 564 #define sc_if sc_ec.ec_if 565 uint32_t sc_flags; /* BWI_F_ */ 566 void *sc_ih; /* [TRC: interrupt handler] */ 567 void *sc_soft_ih; 568 569 uint32_t sc_cap; /* BWI_CAP_ */ 570 uint16_t sc_bbp_id; /* BWI_BBPID_ */ 571 uint8_t sc_bbp_rev; 572 uint8_t sc_bbp_pkg; 573 574 uint8_t sc_pci_revid; 575 uint16_t sc_pci_did; 576 uint16_t sc_pci_subvid; 577 uint16_t sc_pci_subdid; 578 579 uint16_t sc_card_flags; /* BWI_CARD_F_ */ 580 uint16_t sc_pwron_delay; 581 int sc_locale; 582 583 /* [TRC: No clue what these are for.] 584 int sc_irq_rid; 585 struct resource *sc_irq_res; 586 void *sc_irq_handle; 587 */ 588 589 /* [TRC: Likewise.] 590 int sc_mem_rid; 591 struct resource *sc_mem_res; 592 */ 593 bus_dma_tag_t sc_dmat; 594 bus_space_tag_t sc_mem_bt; 595 bus_space_handle_t sc_mem_bh; 596 597 struct callout sc_scan_ch; 598 struct callout sc_calib_ch; 599 600 /* [TRC: XXX amrr] */ 601 struct callout sc_amrr_ch; 602 struct ieee80211_amrr sc_amrr; 603 604 struct bwi_regwin *sc_cur_regwin; 605 struct bwi_regwin sc_com_regwin; 606 struct bwi_regwin sc_bus_regwin; 607 608 int sc_nmac; 609 struct bwi_mac sc_mac[BWI_MAC_MAX]; 610 611 int sc_rx_rate; 612 int sc_tx_rate; 613 enum bwi_txpwrcb_type sc_txpwrcb_type; 614 615 int sc_led_blinking; 616 int sc_led_ticks; 617 struct bwi_led *sc_blink_led; 618 struct callout sc_led_blink_ch; 619 int sc_led_blink_offdur; 620 struct bwi_led sc_leds[BWI_LED_MAX]; 621 622 enum bwi_bus_space sc_bus_space; 623 624 struct bwi_txbuf_data sc_tx_bdata[BWI_TX_NRING]; 625 struct bwi_rxbuf_data sc_rx_bdata; 626 627 struct bwi_ring_data sc_tx_rdata[BWI_TX_NRING]; 628 struct bwi_ring_data sc_rx_rdata; 629 630 struct bwi_txstats_data *sc_txstats; 631 632 int sc_tx_timer; 633 634 int (*sc_newstate) 635 (struct ieee80211com *, 636 enum ieee80211_state, int); 637 638 int (*sc_init_tx_ring)(struct bwi_softc *, int); 639 void (*sc_free_tx_ring)(struct bwi_softc *, int); 640 641 int (*sc_init_rx_ring)(struct bwi_softc *); 642 void (*sc_free_rx_ring)(struct bwi_softc *); 643 644 int (*sc_init_txstats)(struct bwi_softc *); 645 void (*sc_free_txstats)(struct bwi_softc *); 646 647 void (*sc_setup_rxdesc) 648 (struct bwi_softc *, int, bus_addr_t, int); 649 int (*sc_rxeof)(struct bwi_softc *); 650 651 void (*sc_setup_txdesc) 652 (struct bwi_softc *, struct bwi_ring_data *, 653 int, bus_addr_t, int); 654 void (*sc_start_tx) 655 (struct bwi_softc *, uint32_t, int); 656 657 void (*sc_txeof_status)(struct bwi_softc *); 658 659 int (*sc_enable)(struct bwi_softc *, int); 660 void (*sc_disable)(struct bwi_softc *, int); 661 662 void (*sc_conf_write)(void *, uint32_t, uint32_t); 663 uint32_t (*sc_conf_read)(void *, uint32_t); 664 665 void (*sc_reg_write_2)(void *, uint32_t, uint16_t); 666 uint16_t (*sc_reg_read_2)(void *, uint32_t); 667 void (*sc_reg_write_4)(void *, uint32_t, uint32_t); 668 uint32_t (*sc_reg_read_4)(void *, uint32_t); 669 670 void (*sc_reg_write_multi_4)(void *, uint32_t, 671 const uint32_t *, size_t); 672 void (*sc_reg_read_multi_4)(void *, uint32_t, 673 uint32_t *, size_t); 674 675 struct pool_cache *sc_freetask; 676 struct workqueue *sc_taskq; 677 uint8_t *sc_pio_databuf; 678 kmutex_t sc_pio_txlock; 679 STAILQ_HEAD(, bwi_txbuf) sc_pio_txpend; 680 size_t sc_pio_fifolen; 681 size_t sc_pio_fifoavail; 682 683 struct sysctllog *sc_sysctllog; 684 685 /* Sysctl variables */ 686 int sc_fw_version; /* BWI_FW_VERSION[34] */ 687 int sc_dwell_time; /* milliseconds */ 688 int sc_led_idle; 689 int sc_led_blink; 690 int sc_txpwr_calib; 691 int sc_debug; /* BWI_DBG_ */ 692 693 struct bpf_if *sc_drvbpf; 694 695 union { 696 struct bwi_rx_radiotap_hdr th; 697 uint8_t pad[64]; 698 } sc_rxtapu; 699 #define sc_rxtap sc_rxtapu.th 700 int sc_rxtap_len; 701 702 union { 703 struct bwi_tx_radiotap_hdr th; 704 uint8_t pad[64]; 705 } sc_txtapu; 706 #define sc_txtap sc_txtapu.th 707 int sc_txtap_len; 708 }; 709 710 static inline void 711 _bwi_read_multi_4(struct bwi_softc *sc, bus_size_t reg, uint32_t *datap, 712 bus_size_t count) 713 { 714 if (sc->sc_reg_read_multi_4 != NULL) { 715 return sc->sc_reg_read_multi_4(sc, reg, datap, count); 716 } else { 717 return bus_space_read_multi_4(sc->sc_mem_bt, sc->sc_mem_bh, 718 reg, datap, count); 719 } 720 } 721 722 static inline uint16_t 723 _bwi_read_2(struct bwi_softc *sc, bus_size_t reg) 724 { 725 if (sc->sc_reg_read_2 != NULL) { 726 return sc->sc_reg_read_2(sc, reg); 727 } else { 728 return bus_space_read_2(sc->sc_mem_bt, sc->sc_mem_bh, reg); 729 } 730 } 731 732 static inline uint32_t 733 _bwi_read_4(struct bwi_softc *sc, bus_size_t reg) 734 { 735 if (sc->sc_reg_read_4 != NULL) { 736 return sc->sc_reg_read_4(sc, reg); 737 } else { 738 return bus_space_read_4(sc->sc_mem_bt, sc->sc_mem_bh, reg); 739 } 740 } 741 742 static inline void 743 _bwi_write_multi_4(struct bwi_softc *sc, bus_size_t reg, const uint32_t *datap, 744 bus_size_t count) 745 { 746 if (sc->sc_reg_read_multi_4 != NULL) { 747 return sc->sc_reg_write_multi_4(sc, reg, datap, count); 748 } else { 749 return bus_space_write_multi_4(sc->sc_mem_bt, sc->sc_mem_bh, 750 reg, datap, count); 751 } 752 } 753 754 static inline void 755 _bwi_write_2(struct bwi_softc *sc, bus_size_t reg, uint16_t val) 756 { 757 if (sc->sc_reg_write_2 != NULL) { 758 sc->sc_reg_write_2(sc, reg, val); 759 } else { 760 bus_space_write_2(sc->sc_mem_bt, sc->sc_mem_bh, reg, val); 761 } 762 } 763 764 static inline void 765 _bwi_write_4(struct bwi_softc *sc, bus_size_t reg, uint32_t val) 766 { 767 if (sc->sc_reg_write_4 != NULL) { 768 sc->sc_reg_write_4(sc, reg, val); 769 } else { 770 bus_space_write_4(sc->sc_mem_bt, sc->sc_mem_bh, reg, val); 771 } 772 } 773 774 #define BWI_F_BUS_INITED 0x1 775 #define BWI_F_PROMISC 0x2 776 #define BWI_F_SDIO 0x4 777 #define BWI_F_PIO 0x8 778 779 #define BWI_IS_SDIO(sc) ISSET((sc)->sc_flags, BWI_F_SDIO) 780 #define BWI_IS_PIO(sc) ISSET((sc)->sc_flags, BWI_F_PIO) 781 782 #define BWI_DBG_MAC 0x00000001 783 #define BWI_DBG_RF 0x00000002 784 #define BWI_DBG_PHY 0x00000004 785 #define BWI_DBG_MISC 0x00000008 786 787 #define BWI_DBG_ATTACH 0x00000010 788 #define BWI_DBG_INIT 0x00000020 789 #define BWI_DBG_FIRMWARE 0x00000040 790 #define BWI_DBG_80211 0x00000080 791 #define BWI_DBG_TXPOWER 0x00000100 792 #define BWI_DBG_INTR 0x00000200 793 #define BWI_DBG_RX 0x00000400 794 #define BWI_DBG_TX 0x00000800 795 #define BWI_DBG_TXEOF 0x00001000 796 #define BWI_DBG_LED 0x00002000 797 #define BWI_DBG_STATION 0x00004000 798 799 #define abs(a) __builtin_abs(a) 800 801 #define MOBJ_WRITE_2(mac, objid, ofs, val) \ 802 bwi_memobj_write_2((mac), (objid), (ofs), (val)) 803 #define MOBJ_WRITE_4(mac, objid, ofs, val) \ 804 bwi_memobj_write_4((mac), (objid), (ofs), (val)) 805 #define MOBJ_READ_2(mac, objid, ofs) \ 806 bwi_memobj_read_2((mac), (objid), (ofs)) 807 #define MOBJ_READ_4(mac, objid, ofs) \ 808 bwi_memobj_read_4((mac), (objid), (ofs)) 809 810 #define MOBJ_SETBITS_4(mac, objid, ofs, bits) \ 811 MOBJ_WRITE_4((mac), (objid), (ofs), \ 812 MOBJ_READ_4((mac), (objid), (ofs)) | (bits)) 813 #define MOBJ_CLRBITS_4(mac, objid, ofs, bits) \ 814 MOBJ_WRITE_4((mac), (objid), (ofs), \ 815 MOBJ_READ_4((mac), (objid), (ofs)) & ~(bits)) 816 817 #define MOBJ_FILT_SETBITS_2(mac, objid, ofs, filt, bits) \ 818 MOBJ_WRITE_2((mac), (objid), (ofs), \ 819 (MOBJ_READ_2((mac), (objid), (ofs)) & (filt)) | (bits)) 820 821 #define TMPLT_WRITE_4(mac, ofs, val) bwi_tmplt_write_4((mac), (ofs), (val)) 822 823 #define HFLAGS_WRITE(mac, flags) bwi_hostflags_write((mac), (flags)) 824 #define HFLAGS_READ(mac) bwi_hostflags_read((mac)) 825 #define HFLAGS_CLRBITS(mac, bits) \ 826 HFLAGS_WRITE((mac), HFLAGS_READ((mac)) | (bits)) 827 #define HFLAGS_SETBITS(mac, bits) \ 828 HFLAGS_WRITE((mac), HFLAGS_READ((mac)) & ~(bits)) 829 830 /* PHY */ 831 832 struct bwi_gains { 833 int16_t tbl_gain1; 834 int16_t tbl_gain2; 835 int16_t phy_gain; 836 }; 837 838 static __inline void 839 bwi_phy_init(struct bwi_mac *_mac) 840 { 841 _mac->mac_phy.phy_init(_mac); 842 } 843 844 #define PHY_WRITE(mac, ctrl, val) bwi_phy_write((mac), (ctrl), (val)) 845 #define PHY_READ(mac, ctrl) bwi_phy_read((mac), (ctrl)) 846 847 #define PHY_SETBITS(mac, ctrl, bits) \ 848 PHY_WRITE((mac), (ctrl), PHY_READ((mac), (ctrl)) | (bits)) 849 #define PHY_CLRBITS(mac, ctrl, bits) \ 850 PHY_WRITE((mac), (ctrl), PHY_READ((mac), (ctrl)) & ~(bits)) 851 #define PHY_FILT_SETBITS(mac, ctrl, filt, bits) \ 852 PHY_WRITE((mac), (ctrl), (PHY_READ((mac), (ctrl)) & (filt)) | (bits)) 853 854 static __inline void 855 bwi_rf_off(struct bwi_mac *_mac) 856 { 857 _mac->mac_rf.rf_off(_mac); 858 /* TODO: LED */ 859 860 _mac->mac_rf.rf_flags &= ~BWI_RF_F_ON; 861 } 862 863 static __inline void 864 bwi_rf_on(struct bwi_mac *_mac) 865 { 866 if (_mac->mac_rf.rf_flags & BWI_RF_F_ON) 867 return; 868 869 _mac->mac_rf.rf_on(_mac); 870 /* TODO: LED */ 871 872 _mac->mac_rf.rf_flags |= BWI_RF_F_ON; 873 } 874 875 static __inline void 876 bwi_rf_calc_nrssi_slope(struct bwi_mac *_mac) 877 { 878 _mac->mac_rf.rf_calc_nrssi_slope(_mac); 879 } 880 881 static __inline void 882 bwi_rf_set_nrssi_thr(struct bwi_mac *_mac) 883 { 884 _mac->mac_rf.rf_set_nrssi_thr(_mac); 885 } 886 887 static __inline int 888 bwi_rf_calc_rssi(struct bwi_mac *_mac, const struct bwi_rxbuf_hdr *_hdr) 889 { 890 return (_mac->mac_rf.rf_calc_rssi(_mac, _hdr)); 891 } 892 893 static __inline void 894 bwi_rf_lo_update(struct bwi_mac *_mac) 895 { 896 _mac->mac_rf.rf_lo_update(_mac); 897 } 898 899 #define RF_WRITE(mac, ofs, val) bwi_rf_write((mac), (ofs), (val)) 900 #define RF_READ(mac, ofs) bwi_rf_read((mac), (ofs)) 901 902 #define RF_SETBITS(mac, ofs, bits) \ 903 RF_WRITE((mac), (ofs), RF_READ((mac), (ofs)) | (bits)) 904 #define RF_CLRBITS(mac, ofs, bits) \ 905 RF_WRITE((mac), (ofs), RF_READ((mac), (ofs)) & ~(bits)) 906 #define RF_FILT_SETBITS(mac, ofs, filt, bits) \ 907 RF_WRITE((mac), (ofs), (RF_READ((mac), (ofs)) & (filt)) | (bits)) 908 909 /* [TRC: XXX Why are these visible at all externally?] */ 910 911 int bwi_intr(void *); 912 int bwi_attach(struct bwi_softc *); 913 void bwi_detach(struct bwi_softc *); 914 915 /* Power Management Framework */ 916 bool bwi_suspend(device_t, const pmf_qual_t *); 917 bool bwi_resume(device_t, const pmf_qual_t *); 918 919 #endif /* !_DEV_IC_BWIVAR_H */ 920