1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 15 * redistribution must be conditioned upon including a substantially 16 * similar Disclaimer requirement for further binary redistribution. 17 * 18 * NO WARRANTY 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 24 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29 * THE POSSIBILITY OF SUCH DAMAGES. 30 */ 31 32 #ifndef _IF_BWNVAR_H 33 #define _IF_BWNVAR_H 34 35 #include <dev/bhnd/bhnd.h> 36 37 struct bwn_softc; 38 struct bwn_mac; 39 40 #define N(a) (sizeof(a) / sizeof(a[0])) 41 #define BWN_ALIGN 0x1000 42 #define BWN_RETRY_SHORT 7 43 #define BWN_RETRY_LONG 4 44 #define BWN_STAID_MAX 64 45 #define BWN_TXPWR_IGNORE_TIME (1 << 0) 46 #define BWN_TXPWR_IGNORE_TSSI (1 << 1) 47 #define BWN_HAS_TXMAG(phy) \ 48 (((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) && \ 49 ((phy)->rf_rev == 8)) 50 #define BWN_HAS_LOOPBACK(phy) \ 51 (((phy)->rev > 1) || ((phy)->gmode)) 52 #define BWN_TXERROR_MAX 1000 53 #define BWN_GETTIME(v) do { \ 54 struct timespec ts; \ 55 nanouptime(&ts); \ 56 (v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000; \ 57 } while (0) 58 #define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351) 59 #define BWN_TSSI2DBM(num, den) \ 60 ((int32_t)((num < 0) ? num / den : (num + den / 2) / den)) 61 #define BWN_HDRSIZE(mac) bwn_tx_hdrsize(mac) 62 #define BWN_MAXTXHDRSIZE (112 + (sizeof(struct bwn_plcp6))) 63 64 #define BWN_PIO_COOKIE(tq, tp) \ 65 ((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index)) 66 #define BWN_DMA_COOKIE(dr, slot) \ 67 ((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot) 68 #define BWN_READ_2(mac, o) \ 69 (bus_read_2((mac)->mac_sc->sc_mem_res, (o))) 70 #define BWN_READ_4(mac, o) \ 71 (bus_read_4((mac)->mac_sc->sc_mem_res, (o))) 72 #define BWN_WRITE_2(mac, o, v) \ 73 (bus_write_2((mac)->mac_sc->sc_mem_res, (o), (v))) 74 #define BWN_WRITE_2_F(mac, o, v) do { \ 75 (BWN_WRITE_2(mac, o, v)); \ 76 BWN_READ_2(mac, o); \ 77 } while(0) 78 #define BWN_WRITE_SETMASK2(mac, offset, mask, set) \ 79 BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set) 80 #define BWN_WRITE_4(mac, o, v) \ 81 (bus_write_4((mac)->mac_sc->sc_mem_res, (o), (v))) 82 #define BWN_WRITE_SETMASK4(mac, offset, mask, set) \ 83 BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set) 84 #define BWN_PIO_TXQOFFSET(mac) \ 85 ((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0) 86 #define BWN_PIO_RXQOFFSET(mac) \ 87 ((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8) 88 #define BWN_SEC_NEWAPI(mac) (mac->mac_fw.rev >= 351) 89 #define BWN_SEC_KEY2FW(mac, idx) \ 90 (BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx)) 91 #define BWN_RF_READ(mac, r) (mac->mac_phy.rf_read(mac, r)) 92 #define BWN_RF_WRITE(mac, r, v) (mac->mac_phy.rf_write(mac, r, v)) 93 #define BWN_RF_MASK(mac, o, m) \ 94 BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m) 95 #define BWN_RF_SETMASK(mac, offset, mask, set) \ 96 BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set) 97 #define BWN_RF_SET(mac, offset, set) \ 98 BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set) 99 #define BWN_PHY_READ(mac, r) (mac->mac_phy.phy_read(mac, r)) 100 #define BWN_PHY_WRITE(mac, r, v) \ 101 (mac->mac_phy.phy_write(mac, r, v)) 102 #define BWN_PHY_SET(mac, offset, set) do { \ 103 if (mac->mac_phy.phy_maskset != NULL) { \ 104 KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ 105 mac->mac_suspended > 0, \ 106 ("dont access PHY or RF registers after turning on MAC")); \ 107 mac->mac_phy.phy_maskset(mac, offset, 0xffff, set); \ 108 } else \ 109 BWN_PHY_WRITE(mac, offset, \ 110 BWN_PHY_READ(mac, offset) | (set)); \ 111 } while (0) 112 #define BWN_PHY_SETMASK(mac, offset, mask, set) do { \ 113 if (mac->mac_phy.phy_maskset != NULL) { \ 114 KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ 115 mac->mac_suspended > 0, \ 116 ("dont access PHY or RF registers after turning on MAC")); \ 117 mac->mac_phy.phy_maskset(mac, offset, mask, set); \ 118 } else \ 119 BWN_PHY_WRITE(mac, offset, \ 120 (BWN_PHY_READ(mac, offset) & (mask)) | (set)); \ 121 } while (0) 122 #define BWN_PHY_MASK(mac, offset, mask) do { \ 123 if (mac->mac_phy.phy_maskset != NULL) { \ 124 KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ 125 mac->mac_suspended > 0, \ 126 ("dont access PHY or RF registers after turning on MAC")); \ 127 mac->mac_phy.phy_maskset(mac, offset, mask, 0); \ 128 } else \ 129 BWN_PHY_WRITE(mac, offset, \ 130 BWN_PHY_READ(mac, offset) & (mask)); \ 131 } while (0) 132 #define BWN_PHY_COPY(mac, dst, src) do { \ 133 KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ 134 mac->mac_suspended > 0, \ 135 ("dont access PHY or RF registers after turning on MAC")); \ 136 BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src)); \ 137 } while (0) 138 #define BWN_LO_CALIB_EXPIRE (1000 * (30 - 2)) 139 #define BWN_LO_PWRVEC_EXPIRE (1000 * (30 - 2)) 140 #define BWN_LO_TXCTL_EXPIRE (1000 * (180 - 4)) 141 #define BWN_LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0)) 142 #define BWN_BITREV4(tmp) (BWN_BITREV8(tmp) >> 4) 143 #define BWN_BITREV8(byte) (bwn_bitrev_table[byte]) 144 #define BWN_BBATTCMP(a, b) ((a)->att == (b)->att) 145 #define BWN_RFATTCMP(a, b) \ 146 (((a)->att == (b)->att) && ((a)->padmix == (b)->padmix)) 147 #define BWN_PIO_WRITE_2(mac, tq, offset, value) \ 148 BWN_WRITE_2(mac, (tq)->tq_base + offset, value) 149 #define BWN_PIO_READ_4(mac, tq, offset) \ 150 BWN_READ_4(mac, tq->tq_base + offset) 151 #define BWN_ISCCKRATE(rate) \ 152 (rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \ 153 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB) 154 #define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate)) 155 #define BWN_BARRIER(mac, offset, length, flags) \ 156 bus_barrier((mac)->mac_sc->sc_mem_res, (offset), (length), (flags)) 157 #define BWN_DMA_READ(dr, offset) \ 158 (BWN_READ_4(dr->dr_mac, dr->dr_base + offset)) 159 #define BWN_DMA_WRITE(dr, offset, value) \ 160 (BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value)) 161 162 typedef enum { 163 BWN_PHY_BAND_2G = 0, 164 BWN_PHY_BAND_5G_LO = 1, 165 BWN_PHY_BAND_5G_MI = 2, 166 BWN_PHY_BAND_5G_HI = 3 167 } bwn_phy_band_t; 168 169 typedef enum { 170 BWN_BAND_2G, 171 BWN_BAND_5G, 172 } bwn_band_t; 173 174 typedef enum { 175 BWN_CHAN_TYPE_20, 176 BWN_CHAN_TYPE_20_HT, 177 BWN_CHAN_TYPE_40_HT_U, 178 BWN_CHAN_TYPE_40_HT_D, 179 } bwn_chan_type_t; 180 181 struct bwn_rate { 182 uint16_t rateid; 183 uint32_t flags; 184 }; 185 186 #define BWN_ANT0 0 187 #define BWN_ANT1 1 188 #define BWN_ANTAUTO0 2 189 #define BWN_ANTAUTO1 3 190 #define BWN_ANT2 4 191 #define BWN_ANT3 8 192 #define BWN_ANTAUTO BWN_ANTAUTO0 193 #define BWN_ANT_DEFAULT BWN_ANTAUTO 194 #define BWN_TX_SLOTS_PER_FRAME 2 195 196 struct bwn_channel { 197 unsigned freq; 198 unsigned ieee; 199 unsigned maxTxPow; 200 }; 201 202 struct bwn_channelinfo { 203 struct bwn_channel channels[IEEE80211_CHAN_MAX]; 204 unsigned nchannels; 205 }; 206 207 struct bwn_bbatt { 208 uint8_t att; 209 }; 210 211 struct bwn_bbatt_list { 212 const struct bwn_bbatt *array; 213 uint8_t len; 214 uint8_t min; 215 uint8_t max; 216 }; 217 218 struct bwn_rfatt { 219 uint8_t att; 220 int padmix; 221 }; 222 223 struct bwn_rfatt_list { 224 const struct bwn_rfatt *array; 225 uint8_t len; 226 uint8_t min; 227 uint8_t max; 228 }; 229 230 #define BWN_DC_LT_SIZE 32 231 232 struct bwn_loctl { 233 int8_t i; 234 int8_t q; 235 }; 236 237 typedef enum { 238 BWN_TXPWR_RES_NEED_ADJUST, 239 BWN_TXPWR_RES_DONE, 240 } bwn_txpwr_result_t; 241 242 struct bwn_lo_calib { 243 struct bwn_bbatt bbatt; 244 struct bwn_rfatt rfatt; 245 struct bwn_loctl ctl; 246 unsigned long calib_time; 247 TAILQ_ENTRY(bwn_lo_calib) list; 248 }; 249 250 struct bwn_rxhdr4 { 251 uint16_t frame_len; 252 uint8_t pad1[2]; 253 uint16_t phy_status0; 254 union { 255 struct { 256 uint8_t rssi; 257 uint8_t sig_qual; 258 } __packed abg; 259 struct { 260 int8_t power0; 261 int8_t power1; 262 } __packed n; 263 } __packed phy; 264 union { 265 struct { 266 int8_t power2; 267 uint8_t pad; 268 } __packed n; 269 struct { 270 uint8_t pad; 271 int8_t ht_power0; 272 } __packed ht; 273 uint16_t phy_status2; 274 } __packed ps2; 275 union { 276 struct { 277 uint16_t phy_status3; 278 } __packed lp; 279 struct { 280 int8_t phy_ht_power1; 281 int8_t phy_ht_power2; 282 } __packed ht; 283 } __packed ps3; 284 union { 285 struct { 286 uint32_t mac_status; 287 uint16_t mac_time; 288 uint16_t channel; 289 } __packed r351; 290 struct { 291 uint16_t phy_status4; 292 uint16_t phy_status5; 293 uint32_t mac_status; 294 uint16_t mac_time; 295 uint16_t channel; 296 } __packed r598; 297 } __packed ps4; 298 } __packed; 299 300 struct bwn_txstatus { 301 uint16_t cookie; 302 uint16_t seq; 303 uint8_t phy_stat; 304 uint8_t framecnt; 305 uint8_t rtscnt; 306 uint8_t sreason; 307 uint8_t pm; 308 uint8_t im; 309 uint8_t ampdu; 310 uint8_t ack; 311 }; 312 313 #define BWN_TXCTL_PA3DB 0x40 314 #define BWN_TXCTL_PA2DB 0x20 315 #define BWN_TXCTL_TXMIX 0x10 316 317 struct bwn_txpwr_loctl { 318 struct bwn_rfatt_list rfatt; 319 struct bwn_bbatt_list bbatt; 320 uint16_t dc_lt[BWN_DC_LT_SIZE]; 321 TAILQ_HEAD(, bwn_lo_calib) calib_list; 322 unsigned long pwr_vec_read_time; 323 unsigned long txctl_measured_time; 324 uint8_t tx_bias; 325 uint8_t tx_magn; 326 uint64_t power_vector; 327 }; 328 329 #define BWN_OFDMTAB_DIR_UNKNOWN 0 330 #define BWN_OFDMTAB_DIR_READ 1 331 #define BWN_OFDMTAB_DIR_WRITE 2 332 333 struct bwn_phy_g { 334 unsigned pg_flags; 335 #define BWN_PHY_G_FLAG_TSSITABLE_ALLOC (1 << 0) 336 #define BWN_PHY_G_FLAG_RADIOCTX_VALID (1 << 1) 337 int pg_aci_enable; 338 int pg_aci_wlan_automatic; 339 int pg_aci_hw_rssi; 340 int pg_rf_on; 341 uint16_t pg_radioctx_over; 342 uint16_t pg_radioctx_overval; 343 uint16_t pg_minlowsig[2]; 344 uint16_t pg_minlowsigpos[2]; 345 uint16_t pg_pa0maxpwr; 346 int8_t *pg_tssi2dbm; 347 int pg_idletssi; 348 int pg_curtssi; 349 uint8_t pg_avgtssi; 350 struct bwn_bbatt pg_bbatt; 351 struct bwn_rfatt pg_rfatt; 352 uint8_t pg_txctl; 353 int pg_bbatt_delta; 354 int pg_rfatt_delta; 355 356 struct bwn_txpwr_loctl pg_loctl; 357 int16_t pg_max_lb_gain; 358 int16_t pg_trsw_rx_gain; 359 int16_t pg_lna_lod_gain; 360 int16_t pg_lna_gain; 361 int16_t pg_pga_gain; 362 int pg_immode; 363 #define BWN_INTERFSTACK_SIZE 26 364 uint32_t pg_interfstack[BWN_INTERFSTACK_SIZE]; 365 366 int16_t pg_nrssi[2]; 367 int32_t pg_nrssi_slope; 368 int8_t pg_nrssi_lt[64]; 369 370 uint16_t pg_lofcal; 371 372 uint16_t pg_initval; 373 uint16_t pg_ofdmtab_addr; 374 unsigned pg_ofdmtab_dir; 375 }; 376 377 #define BWN_IMMODE_NONE 0 378 #define BWN_IMMODE_NONWLAN 1 379 #define BWN_IMMODE_MANUAL 2 380 #define BWN_IMMODE_AUTO 3 381 382 #define BWN_PHYLP_TXPCTL_UNKNOWN 0 383 #define BWN_PHYLP_TXPCTL_OFF 1 384 #define BWN_PHYLP_TXPCTL_ON_SW 2 385 #define BWN_PHYLP_TXPCTL_ON_HW 3 386 387 struct bwn_phy_lp { 388 uint8_t plp_chan; 389 uint8_t plp_chanfullcal; 390 int32_t plp_antenna; 391 uint8_t plp_txpctlmode; 392 uint8_t plp_txisoband_h; 393 uint8_t plp_txisoband_m; 394 uint8_t plp_txisoband_l; 395 uint8_t plp_rxpwroffset; 396 int8_t plp_txpwridx; 397 uint16_t plp_tssiidx; 398 uint16_t plp_tssinpt; 399 uint8_t plp_rssivf; 400 uint8_t plp_rssivc; 401 uint8_t plp_rssigs; 402 uint8_t plp_rccap; 403 uint8_t plp_bxarch; 404 uint8_t plp_crsusr_off; 405 uint8_t plp_crssys_off; 406 uint32_t plp_div; 407 int32_t plp_tonefreq; 408 uint16_t plp_digfilt[9]; 409 }; 410 411 /* for LP */ 412 struct bwn_txgain { 413 uint16_t tg_gm; 414 uint16_t tg_pga; 415 uint16_t tg_pad; 416 uint16_t tg_dac; 417 }; 418 419 struct bwn_rxcompco { 420 uint8_t rc_chan; 421 int8_t rc_c1; 422 int8_t rc_c0; 423 }; 424 425 struct bwn_phy_lp_iq_est { 426 uint32_t ie_iqprod; 427 uint32_t ie_ipwr; 428 uint32_t ie_qpwr; 429 }; 430 431 struct bwn_txgain_entry { 432 uint8_t te_gm; 433 uint8_t te_pga; 434 uint8_t te_pad; 435 uint8_t te_dac; 436 uint8_t te_bbmult; 437 }; 438 439 /* only for LP PHY */ 440 struct bwn_stxtable { 441 uint16_t st_phyoffset; 442 uint16_t st_physhift; 443 uint16_t st_rfaddr; 444 uint16_t st_rfshift; 445 uint16_t st_mask; 446 }; 447 448 struct bwn_b206x_chan { 449 uint8_t bc_chan; 450 uint16_t bc_freq; 451 const uint8_t *bc_data; 452 }; 453 454 struct bwn_b206x_rfinit_entry { 455 uint16_t br_offset; 456 uint16_t br_valuea; 457 uint16_t br_valueg; 458 uint8_t br_flags; 459 }; 460 461 struct bwn_phy_n; 462 463 struct bwn_phy { 464 uint8_t type; 465 uint8_t rev; 466 uint8_t analog; 467 468 int supports_2ghz; 469 int supports_5ghz; 470 471 int gmode; 472 struct bwn_phy_g phy_g; 473 struct bwn_phy_lp phy_lp; 474 475 /* 476 * I'd like the newer PHY code to not hide in the top-level 477 * structs.. 478 */ 479 struct bwn_phy_n *phy_n; 480 481 uint16_t rf_manuf; 482 uint16_t rf_ver; 483 uint8_t rf_rev; 484 int rf_on; 485 int phy_do_full_init; 486 487 int txpower; 488 int hwpctl; 489 unsigned long nexttime; 490 unsigned int chan; 491 int txerrors; 492 493 int (*attach)(struct bwn_mac *); 494 void (*detach)(struct bwn_mac *); 495 int (*prepare_hw)(struct bwn_mac *); 496 void (*init_pre)(struct bwn_mac *); 497 int (*init)(struct bwn_mac *); 498 void (*exit)(struct bwn_mac *); 499 uint16_t (*phy_read)(struct bwn_mac *, uint16_t); 500 void (*phy_write)(struct bwn_mac *, uint16_t, 501 uint16_t); 502 void (*phy_maskset)(struct bwn_mac *, 503 uint16_t, uint16_t, uint16_t); 504 uint16_t (*rf_read)(struct bwn_mac *, uint16_t); 505 void (*rf_write)(struct bwn_mac *, uint16_t, 506 uint16_t); 507 int (*use_hwpctl)(struct bwn_mac *); 508 void (*rf_onoff)(struct bwn_mac *, int); 509 void (*switch_analog)(struct bwn_mac *, int); 510 int (*switch_channel)(struct bwn_mac *, 511 unsigned int); 512 uint32_t (*get_default_chan)(struct bwn_mac *); 513 void (*set_antenna)(struct bwn_mac *, int); 514 int (*set_im)(struct bwn_mac *, int); 515 bwn_txpwr_result_t (*recalc_txpwr)(struct bwn_mac *, int); 516 void (*set_txpwr)(struct bwn_mac *); 517 void (*task_15s)(struct bwn_mac *); 518 void (*task_60s)(struct bwn_mac *); 519 }; 520 521 struct bwn_chan_band { 522 uint32_t flags; 523 uint8_t nchan; 524 #define BWN_MAX_CHAN_PER_BAND 14 525 uint8_t chan[BWN_MAX_CHAN_PER_BAND]; 526 }; 527 528 #define BWN_NR_WMEPARAMS 16 529 enum { 530 BWN_WMEPARAM_TXOP = 0, 531 BWN_WMEPARAM_CWMIN, 532 BWN_WMEPARAM_CWMAX, 533 BWN_WMEPARAM_CWCUR, 534 BWN_WMEPARAM_AIFS, 535 BWN_WMEPARAM_BSLOTS, 536 BWN_WMEPARAM_REGGAP, 537 BWN_WMEPARAM_STATUS, 538 }; 539 540 #define BWN_WME_PARAMS(queue) \ 541 (BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue))) 542 #define BWN_WME_BACKGROUND BWN_WME_PARAMS(0) 543 #define BWN_WME_BESTEFFORT BWN_WME_PARAMS(1) 544 #define BWN_WME_VIDEO BWN_WME_PARAMS(2) 545 #define BWN_WME_VOICE BWN_WME_PARAMS(3) 546 547 /* 548 * Radio capture format. 549 */ 550 #define BWN_RX_RADIOTAP_PRESENT ( \ 551 (1 << IEEE80211_RADIOTAP_TSFT) | \ 552 (1 << IEEE80211_RADIOTAP_FLAGS) | \ 553 (1 << IEEE80211_RADIOTAP_RATE) | \ 554 (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 555 (1 << IEEE80211_RADIOTAP_ANTENNA) | \ 556 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 557 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 558 0) 559 560 struct bwn_rx_radiotap_header { 561 struct ieee80211_radiotap_header wr_ihdr; 562 uint64_t wr_tsf; 563 u_int8_t wr_flags; 564 u_int8_t wr_rate; 565 u_int16_t wr_chan_freq; 566 u_int16_t wr_chan_flags; 567 int8_t wr_antsignal; 568 int8_t wr_antnoise; 569 u_int8_t wr_antenna; 570 } __packed __aligned(8); 571 572 #define BWN_TX_RADIOTAP_PRESENT ( \ 573 (1 << IEEE80211_RADIOTAP_FLAGS) | \ 574 (1 << IEEE80211_RADIOTAP_RATE) | \ 575 (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 576 (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \ 577 (1 << IEEE80211_RADIOTAP_ANTENNA) | \ 578 0) 579 580 struct bwn_tx_radiotap_header { 581 struct ieee80211_radiotap_header wt_ihdr; 582 u_int8_t wt_flags; 583 u_int8_t wt_rate; 584 u_int16_t wt_chan_freq; 585 u_int16_t wt_chan_flags; 586 u_int8_t wt_txpower; 587 u_int8_t wt_antenna; 588 } __packed; 589 590 struct bwn_stats { 591 int32_t rtsfail; 592 int32_t rts; 593 int32_t link_noise; 594 }; 595 596 /* Noise Calculation (Link Quality) */ 597 struct bwn_noise { 598 uint8_t noi_running; 599 uint8_t noi_nsamples; 600 int8_t noi_samples[8][4]; 601 }; 602 603 struct bwn_dmadesc_meta { 604 bus_dmamap_t mt_dmap; 605 bus_addr_t mt_paddr; 606 struct mbuf *mt_m; 607 struct ieee80211_node *mt_ni; 608 uint8_t mt_txtype; 609 #define BWN_DMADESC_METATYPE_HEADER 0 610 #define BWN_DMADESC_METATYPE_BODY 1 611 uint8_t mt_islast; 612 }; 613 614 #define BWN_DMAINTR_FATALMASK \ 615 ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15)) 616 #define BWN_DMAINTR_NONFATALMASK (1 << 13) 617 #define BWN_DMAINTR_RX_DONE (1 << 16) 618 619 #define BWN_DMA32_DCTL_BYTECNT 0x00001fff 620 #define BWN_DMA32_DCTL_ADDREXT_MASK 0x00030000 621 #define BWN_DMA32_DCTL_ADDREXT_SHIFT 16 622 #define BWN_DMA32_DCTL_DTABLEEND 0x10000000 623 #define BWN_DMA32_DCTL_IRQ 0x20000000 624 #define BWN_DMA32_DCTL_FRAMEEND 0x40000000 625 #define BWN_DMA32_DCTL_FRAMESTART 0x80000000 626 struct bwn_dmadesc32 { 627 uint32_t control; 628 uint32_t address; 629 } __packed; 630 631 #define BWN_DMA64_DCTL0_DTABLEEND 0x10000000 632 #define BWN_DMA64_DCTL0_IRQ 0x20000000 633 #define BWN_DMA64_DCTL0_FRAMEEND 0x40000000 634 #define BWN_DMA64_DCTL0_FRAMESTART 0x80000000 635 #define BWN_DMA64_DCTL1_BYTECNT 0x00001fff 636 #define BWN_DMA64_DCTL1_ADDREXT_MASK 0x00030000 637 #define BWN_DMA64_DCTL1_ADDREXT_SHIFT 16 638 struct bwn_dmadesc64 { 639 uint32_t control0; 640 uint32_t control1; 641 uint32_t address_low; 642 uint32_t address_high; 643 } __packed; 644 645 struct bwn_dmadesc_generic { 646 union { 647 struct bwn_dmadesc32 dma32; 648 struct bwn_dmadesc64 dma64; 649 } __packed dma; 650 } __packed; 651 652 struct bwn_dma_ring; 653 654 struct bwn_dma_ring { 655 struct bwn_mac *dr_mac; 656 const struct bwn_dma_ops *dr_ops; 657 struct bwn_dmadesc_meta *dr_meta; 658 void *dr_txhdr_cache; 659 bus_dma_tag_t dr_ring_dtag; 660 bus_dma_tag_t dr_txring_dtag; 661 bus_dmamap_t dr_spare_dmap; /* only for RX */ 662 bus_dmamap_t dr_ring_dmap; 663 bus_addr_t dr_txring_paddr; 664 void *dr_ring_descbase; 665 bus_addr_t dr_ring_dmabase; 666 int dr_numslots; 667 int dr_usedslot; 668 int dr_curslot; 669 uint32_t dr_frameoffset; 670 uint16_t dr_rx_bufsize; 671 uint16_t dr_base; 672 int dr_index; 673 uint8_t dr_tx; 674 uint8_t dr_stop; 675 int dr_type; 676 677 void (*getdesc)(struct bwn_dma_ring *, 678 int, struct bwn_dmadesc_generic **, 679 struct bwn_dmadesc_meta **); 680 void (*setdesc)(struct bwn_dma_ring *, 681 struct bwn_dmadesc_generic *, 682 bus_addr_t, uint16_t, int, int, 683 int); 684 void (*start_transfer)(struct bwn_dma_ring *, 685 int); 686 void (*suspend)(struct bwn_dma_ring *); 687 void (*resume)(struct bwn_dma_ring *); 688 int (*get_curslot)(struct bwn_dma_ring *); 689 void (*set_curslot)(struct bwn_dma_ring *, 690 int); 691 }; 692 693 struct bwn_dma { 694 bus_dma_tag_t parent_dtag; 695 bus_dma_tag_t rxbuf_dtag; 696 bus_dma_tag_t txbuf_dtag; 697 struct bhnd_dma_translation translation; 698 u_int addrext_shift; 699 700 struct bwn_dma_ring *wme[5]; 701 struct bwn_dma_ring *mcast; 702 struct bwn_dma_ring *rx; 703 uint64_t lastseq; /* XXX FIXME */ 704 }; 705 706 struct bwn_pio_rxqueue { 707 struct bwn_mac *prq_mac; 708 uint16_t prq_base; 709 uint8_t prq_rev; 710 }; 711 712 struct bwn_pio_txqueue; 713 struct bwn_pio_txpkt { 714 struct bwn_pio_txqueue *tp_queue; 715 struct ieee80211_node *tp_ni; 716 struct mbuf *tp_m; 717 uint8_t tp_index; 718 TAILQ_ENTRY(bwn_pio_txpkt) tp_list; 719 }; 720 721 #define BWN_PIO_MAX_TXPACKETS 32 722 struct bwn_pio_txqueue { 723 uint16_t tq_base; 724 uint16_t tq_size; 725 uint16_t tq_used; 726 uint16_t tq_free; 727 uint8_t tq_index; 728 struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS]; 729 TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist; 730 }; 731 732 struct bwn_pio { 733 struct bwn_pio_txqueue wme[5]; 734 struct bwn_pio_txqueue mcast; 735 struct bwn_pio_rxqueue rx; 736 }; 737 738 struct bwn_plcp4 { 739 union { 740 uint32_t data; 741 uint8_t raw[4]; 742 } __packed o; 743 } __packed; 744 745 struct bwn_plcp6 { 746 union { 747 uint32_t data; 748 uint8_t raw[6]; 749 } __packed o; 750 } __packed; 751 752 struct bwn_txhdr { 753 uint32_t macctl; 754 uint8_t macfc[2]; 755 uint16_t tx_festime; 756 uint16_t phyctl; 757 uint16_t phyctl_1; 758 uint16_t phyctl_1fb; 759 uint16_t phyctl_1rts; 760 uint16_t phyctl_1rtsfb; 761 uint8_t phyrate; 762 uint8_t phyrate_rts; 763 uint8_t eftypes; /* extra frame types */ 764 uint8_t chan; 765 uint8_t iv[16]; 766 uint8_t addr1[IEEE80211_ADDR_LEN]; 767 uint16_t tx_festime_fb; 768 struct bwn_plcp6 rts_plcp_fb; 769 uint16_t rts_dur_fb; 770 struct bwn_plcp6 plcp_fb; 771 uint16_t dur_fb; 772 uint16_t mimo_modelen; 773 uint16_t mimo_ratelen_fb; 774 uint32_t timeout; 775 776 union { 777 /* format <= r351 */ 778 struct { 779 uint8_t pad0[2]; 780 uint16_t cookie; 781 uint16_t tx_status; 782 struct bwn_plcp6 rts_plcp; 783 uint8_t rts_frame[16]; 784 uint8_t pad1[2]; 785 struct bwn_plcp6 plcp; 786 } __packed r351; 787 /* format > r410 < r598 */ 788 struct { 789 uint16_t mimo_antenna; 790 uint16_t preload_size; 791 uint8_t pad0[2]; 792 uint16_t cookie; 793 uint16_t tx_status; 794 struct bwn_plcp6 rts_plcp; 795 uint8_t rts_frame[16]; 796 uint8_t pad1[2]; 797 struct bwn_plcp6 plcp; 798 } __packed r410; 799 struct { 800 uint16_t mimo_antenna; 801 uint16_t preload_size; 802 uint8_t pad0[2]; 803 uint16_t cookie; 804 uint16_t tx_status; 805 uint16_t max_n_mpdus; 806 uint16_t max_a_bytes_mrt; 807 uint16_t max_a_bytes_fbr; 808 uint16_t min_m_bytes; 809 struct bwn_plcp6 rts_plcp; 810 uint8_t rts_frame[16]; 811 uint8_t pad1[2]; 812 struct bwn_plcp6 plcp; 813 } __packed r598; 814 } __packed body; 815 } __packed; 816 817 #define BWN_FWTYPE_UCODE 'u' 818 #define BWN_FWTYPE_PCM 'p' 819 #define BWN_FWTYPE_IV 'i' 820 struct bwn_fwhdr { 821 uint8_t type; 822 uint8_t ver; 823 uint8_t pad[2]; 824 uint32_t size; 825 } __packed; 826 827 #define BWN_FWINITVALS_OFFSET_MASK 0x7fff 828 #define BWN_FWINITVALS_32BIT 0x8000 829 struct bwn_fwinitvals { 830 uint16_t offset_size; 831 union { 832 uint16_t d16; 833 uint32_t d32; 834 } __packed data; 835 } __packed; 836 837 enum bwn_fw_hdr_format { 838 BWN_FW_HDR_598, 839 BWN_FW_HDR_410, 840 BWN_FW_HDR_351, 841 }; 842 843 enum bwn_fwtype { 844 BWN_FWTYPE_DEFAULT, 845 BWN_FWTYPE_OPENSOURCE, 846 BWN_NR_FWTYPES, 847 }; 848 849 struct bwn_fwfile { 850 const char *filename; 851 const struct firmware *fw; 852 enum bwn_fwtype type; 853 }; 854 855 struct bwn_key { 856 void *keyconf; 857 uint8_t algorithm; 858 }; 859 860 struct bwn_fw { 861 struct bwn_fwfile ucode; 862 struct bwn_fwfile pcm; 863 struct bwn_fwfile initvals; 864 struct bwn_fwfile initvals_band; 865 enum bwn_fw_hdr_format fw_hdr_format; 866 867 uint16_t rev; 868 uint16_t patch; 869 uint8_t opensource; 870 uint8_t no_pcmfile; 871 }; 872 873 struct bwn_lo_g_sm { 874 int curstate; 875 int nmeasure; 876 int multipler; 877 uint16_t feedth; 878 struct bwn_loctl loctl; 879 }; 880 881 struct bwn_lo_g_value { 882 uint8_t old_channel; 883 uint16_t phy_lomask; 884 uint16_t phy_extg; 885 uint16_t phy_dacctl_hwpctl; 886 uint16_t phy_dacctl; 887 uint16_t phy_hpwr_tssictl; 888 uint16_t phy_analogover; 889 uint16_t phy_analogoverval; 890 uint16_t phy_rfover; 891 uint16_t phy_rfoverval; 892 uint16_t phy_classctl; 893 uint16_t phy_crs0; 894 uint16_t phy_pgactl; 895 uint16_t phy_syncctl; 896 uint16_t phy_cck0; 897 uint16_t phy_cck1; 898 uint16_t phy_cck2; 899 uint16_t phy_cck3; 900 uint16_t phy_cck4; 901 uint16_t reg0; 902 uint16_t reg1; 903 uint16_t rf0; 904 uint16_t rf1; 905 uint16_t rf2; 906 }; 907 908 #define BWN_LED_MAX 4 909 910 #define BWN_LED_EVENT_NONE -1 911 #define BWN_LED_EVENT_POLL 0 912 #define BWN_LED_EVENT_TX 1 913 #define BWN_LED_EVENT_RX 2 914 #define BWN_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2) 915 916 struct bwn_led { 917 uint8_t led_flags; /* BWN_LED_F_ */ 918 uint8_t led_act; /* BWN_LED_ACT_ */ 919 uint8_t led_mask; 920 }; 921 922 #define BWN_LED_F_ACTLOW 0x1 923 #define BWN_LED_F_BLINK 0x2 924 #define BWN_LED_F_POLLABLE 0x4 925 #define BWN_LED_F_SLOW 0x8 926 927 struct bwn_mac { 928 struct bwn_softc *mac_sc; 929 unsigned mac_status; 930 #define BWN_MAC_STATUS_UNINIT 0 931 #define BWN_MAC_STATUS_INITED 1 932 #define BWN_MAC_STATUS_STARTED 2 933 unsigned mac_flags; 934 /* use "Bad Frames Preemption" */ 935 #define BWN_MAC_FLAG_BADFRAME_PREEMP (1 << 0) 936 #define BWN_MAC_FLAG_DFQVALID (1 << 1) 937 #define BWN_MAC_FLAG_RADIO_ON (1 << 2) 938 #define BWN_MAC_FLAG_DMA (1 << 3) 939 #define BWN_MAC_FLAG_WME (1 << 4) 940 #define BWN_MAC_FLAG_HWCRYPTO (1 << 5) 941 942 struct resource *mac_res_irq; 943 int mac_rid_irq; 944 void *mac_intrhand; 945 946 struct bwn_noise mac_noise; 947 struct bwn_phy mac_phy; 948 struct bwn_stats mac_stats; 949 uint32_t mac_reason_intr; 950 uint32_t mac_reason[6]; 951 uint32_t mac_intr_mask; 952 int mac_suspended; 953 954 struct bwn_fw mac_fw; 955 956 int mac_dmatype; 957 union { 958 struct bwn_dma dma; 959 struct bwn_pio pio; 960 } mac_method; 961 962 uint16_t mac_ktp; /* Key table pointer */ 963 uint8_t mac_max_nr_keys; 964 struct bwn_key mac_key[58]; 965 966 unsigned int mac_task_state; 967 struct task mac_intrtask; 968 struct task mac_hwreset; 969 struct task mac_txpower; 970 971 TAILQ_ENTRY(bwn_mac) mac_list; 972 }; 973 974 static inline int 975 bwn_tx_hdrsize(struct bwn_mac *mac) 976 { 977 switch (mac->mac_fw.fw_hdr_format) { 978 case BWN_FW_HDR_598: 979 return (112 + (sizeof(struct bwn_plcp6))); 980 case BWN_FW_HDR_410: 981 return (104 + (sizeof(struct bwn_plcp6))); 982 case BWN_FW_HDR_351: 983 return (100 + (sizeof(struct bwn_plcp6))); 984 default: 985 printf("%s: unknown header format (%d)\n", __func__, 986 mac->mac_fw.fw_hdr_format); 987 return (112 + (sizeof(struct bwn_plcp6))); 988 } 989 } 990 991 /* 992 * Driver-specific vap state. 993 */ 994 struct bwn_vap { 995 struct ieee80211vap bv_vap; /* base class */ 996 int (*bv_newstate)(struct ieee80211vap *, 997 enum ieee80211_state, int); 998 }; 999 #define BWN_VAP(vap) ((struct bwn_vap *)(vap)) 1000 #define BWN_VAP_CONST(vap) ((const struct mwl_vap *)(vap)) 1001 1002 enum bwn_quirk { 1003 /** 1004 * The ucode PCI slowclock workaround is required on this device. 1005 * @see BWN_HF_PCI_SLOWCLOCK_WORKAROUND. 1006 */ 1007 BWN_QUIRK_UCODE_SLOWCLOCK_WAR = (1<<0), 1008 1009 /** 1010 * DMA is unsupported on this device; PIO should be used instead. 1011 */ 1012 BWN_QUIRK_NODMA = (1<<1), 1013 }; 1014 1015 struct bwn_softc { 1016 device_t sc_dev; 1017 struct bhnd_board_info sc_board_info; 1018 struct bhnd_chipid sc_cid; 1019 uint32_t sc_quirks; /**< @see bwn_quirk */ 1020 struct resource *sc_mem_res; 1021 int sc_mem_rid; 1022 1023 device_t sc_chipc; /**< ChipCommon device */ 1024 device_t sc_gpio; /**< GPIO device */ 1025 device_t sc_pmu; /**< PMU device, or NULL if unsupported */ 1026 1027 struct mtx sc_mtx; 1028 struct ieee80211com sc_ic; 1029 struct mbufq sc_snd; 1030 unsigned sc_flags; 1031 #define BWN_FLAG_ATTACHED (1 << 0) 1032 #define BWN_FLAG_INVALID (1 << 1) 1033 #define BWN_FLAG_NEED_BEACON_TP (1 << 2) 1034 #define BWN_FLAG_RUNNING (1 << 3) 1035 unsigned sc_debug; 1036 1037 struct bwn_mac *sc_curmac; 1038 TAILQ_HEAD(, bwn_mac) sc_maclist; 1039 1040 uint8_t sc_bssid[IEEE80211_ADDR_LEN]; 1041 unsigned int sc_filters; 1042 uint8_t sc_beacons[2]; 1043 uint8_t sc_rf_enabled; 1044 1045 struct wmeParams sc_wmeParams[4]; 1046 1047 struct callout sc_rfswitch_ch; /* for laptop */ 1048 struct callout sc_task_ch; 1049 struct callout sc_watchdog_ch; 1050 int sc_watchdog_timer; 1051 struct taskqueue *sc_tq; /* private task queue */ 1052 int (*sc_newstate)(struct ieee80211com *, 1053 enum ieee80211_state, int); 1054 void (*sc_node_cleanup)( 1055 struct ieee80211_node *); 1056 1057 int sc_rx_rate; 1058 int sc_tx_rate; 1059 1060 int sc_led_blinking; 1061 int sc_led_ticks; 1062 struct bwn_led *sc_blink_led; 1063 struct callout sc_led_blink_ch; 1064 int sc_led_blink_offdur; 1065 struct bwn_led sc_leds[BWN_LED_MAX]; 1066 int sc_led_idle; 1067 int sc_led_blink; 1068 1069 uint8_t sc_ant2g; /**< available 2GHz antennas */ 1070 uint8_t sc_ant5g; /**< available 5GHz antennas */ 1071 1072 struct bwn_tx_radiotap_header sc_tx_th; 1073 struct bwn_rx_radiotap_header sc_rx_th; 1074 }; 1075 1076 #define BWN_LOCK_INIT(sc) \ 1077 mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ 1078 MTX_NETWORK_LOCK, MTX_DEF) 1079 #define BWN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) 1080 #define BWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 1081 #define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 1082 #define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 1083 1084 static inline bwn_band_t 1085 bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c) 1086 { 1087 if (IEEE80211_IS_CHAN_5GHZ(c)) 1088 return BWN_BAND_5G; 1089 /* XXX check 2g, log error if not 2g or 5g? */ 1090 return BWN_BAND_2G; 1091 } 1092 1093 static inline bwn_band_t 1094 bwn_current_band(struct bwn_mac *mac) 1095 { 1096 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1097 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 1098 return BWN_BAND_5G; 1099 /* XXX check 2g, log error if not 2g or 5g? */ 1100 return BWN_BAND_2G; 1101 } 1102 1103 static inline bool 1104 bwn_is_40mhz(struct bwn_mac *mac) 1105 { 1106 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1107 1108 return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan)); 1109 } 1110 1111 static inline int 1112 bwn_get_centre_freq(struct bwn_mac *mac) 1113 { 1114 1115 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1116 /* XXX TODO: calculate correctly for HT40 mode */ 1117 return ic->ic_curchan->ic_freq; 1118 } 1119 1120 static inline int 1121 bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan) 1122 { 1123 1124 /* XXX TODO: calculate correctly for HT40 mode */ 1125 return chan->ic_freq; 1126 } 1127 1128 static inline int 1129 bwn_get_chan(struct bwn_mac *mac) 1130 { 1131 1132 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1133 /* XXX TODO: calculate correctly for HT40 mode */ 1134 return ic->ic_curchan->ic_ieee; 1135 } 1136 1137 static inline struct ieee80211_channel * 1138 bwn_get_channel(struct bwn_mac *mac) 1139 { 1140 1141 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1142 return ic->ic_curchan; 1143 } 1144 1145 static inline bool 1146 bwn_is_chan_passive(struct bwn_mac *mac) 1147 { 1148 1149 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1150 return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan); 1151 } 1152 1153 static inline bwn_chan_type_t 1154 bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c) 1155 { 1156 struct ieee80211com *ic = &mac->mac_sc->sc_ic; 1157 if (c == NULL) 1158 c = ic->ic_curchan; 1159 if (IEEE80211_IS_CHAN_HT40U(c)) 1160 return BWN_CHAN_TYPE_40_HT_U; 1161 else if (IEEE80211_IS_CHAN_HT40D(c)) 1162 return BWN_CHAN_TYPE_40_HT_D; 1163 else if (IEEE80211_IS_CHAN_HT20(c)) 1164 return BWN_CHAN_TYPE_20_HT; 1165 else 1166 return BWN_CHAN_TYPE_20; 1167 } 1168 1169 static inline int 1170 bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c) 1171 { 1172 1173 /* return in dbm */ 1174 return c->ic_maxpower / 2; 1175 } 1176 1177 #endif /* !_IF_BWNVAR_H */ 1178