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