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