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