1 /* 2 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Sepherosa Ziehau <sepherosa@gmail.com> 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 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.13 2008/02/15 11:15:38 sephe Exp $ 35 */ 36 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD$"); 39 40 #include "opt_inet.h" 41 #include "opt_bwi.h" 42 #include "opt_wlan.h" 43 44 #include <sys/param.h> 45 #include <sys/endian.h> 46 #include <sys/kernel.h> 47 #include <sys/bus.h> 48 #include <sys/malloc.h> 49 #include <sys/proc.h> 50 #include <sys/rman.h> 51 #include <sys/socket.h> 52 #include <sys/sockio.h> 53 #include <sys/sysctl.h> 54 #include <sys/systm.h> 55 56 #include <sys/linker.h> 57 #include <sys/firmware.h> 58 59 #include <net/if.h> 60 #include <net/if_var.h> 61 #include <net/if_dl.h> 62 #include <net/if_media.h> 63 #include <net/if_types.h> 64 #include <net/if_arp.h> 65 #include <net/ethernet.h> 66 #include <net/if_llc.h> 67 68 #include <net80211/ieee80211_var.h> 69 #include <net80211/ieee80211_radiotap.h> 70 #include <net80211/ieee80211_amrr.h> 71 #include <net80211/ieee80211_phy.h> 72 73 #include <machine/bus.h> 74 75 #include <dev/bwi/bitops.h> 76 #include <dev/bwi/if_bwireg.h> 77 #include <dev/bwi/if_bwivar.h> 78 #include <dev/bwi/bwimac.h> 79 #include <dev/bwi/bwirf.h> 80 #include <dev/bwi/bwiphy.h> 81 82 struct bwi_retry_lim { 83 uint16_t shretry; 84 uint16_t shretry_fb; 85 uint16_t lgretry; 86 uint16_t lgretry_fb; 87 }; 88 89 static int bwi_mac_test(struct bwi_mac *); 90 static int bwi_mac_get_property(struct bwi_mac *); 91 92 static void bwi_mac_set_retry_lim(struct bwi_mac *, 93 const struct bwi_retry_lim *); 94 static void bwi_mac_set_ackrates(struct bwi_mac *, 95 const struct ieee80211_rate_table *rt, 96 const struct ieee80211_rateset *); 97 98 static int bwi_mac_gpio_init(struct bwi_mac *); 99 static int bwi_mac_gpio_fini(struct bwi_mac *); 100 static void bwi_mac_opmode_init(struct bwi_mac *); 101 static void bwi_mac_hostflags_init(struct bwi_mac *); 102 static void bwi_mac_bss_param_init(struct bwi_mac *); 103 104 static void bwi_mac_fw_free(struct bwi_mac *); 105 static int bwi_mac_fw_load(struct bwi_mac *); 106 static int bwi_mac_fw_init(struct bwi_mac *); 107 static int bwi_mac_fw_load_iv(struct bwi_mac *, const struct firmware *); 108 109 static void bwi_mac_setup_tpctl(struct bwi_mac *); 110 static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int); 111 112 static void bwi_mac_lock(struct bwi_mac *); 113 static void bwi_mac_unlock(struct bwi_mac *); 114 115 static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 }; 116 117 void 118 bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val) 119 { 120 struct bwi_softc *sc = mac->mac_sc; 121 122 if (mac->mac_flags & BWI_MAC_F_BSWAP) 123 val = bswap32(val); 124 125 CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs); 126 CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val); 127 } 128 129 void 130 bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags) 131 { 132 uint64_t val; 133 134 val = flags & 0xffff; 135 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val); 136 137 val = (flags >> 16) & 0xffff; 138 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val); 139 140 /* HI has unclear meaning, so leave it as it is */ 141 } 142 143 uint64_t 144 bwi_hostflags_read(struct bwi_mac *mac) 145 { 146 uint64_t flags, val; 147 148 /* HI has unclear meaning, so don't touch it */ 149 flags = 0; 150 151 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI); 152 flags |= val << 16; 153 154 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO); 155 flags |= val; 156 157 return flags; 158 } 159 160 uint16_t 161 bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) 162 { 163 struct bwi_softc *sc = mac->mac_sc; 164 uint32_t data_reg; 165 int ofs; 166 167 data_reg = BWI_MOBJ_DATA; 168 ofs = ofs0 / 4; 169 170 if (ofs0 % 4 != 0) 171 data_reg = BWI_MOBJ_DATA_UNALIGN; 172 173 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 174 return CSR_READ_2(sc, data_reg); 175 } 176 177 uint32_t 178 bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) 179 { 180 struct bwi_softc *sc = mac->mac_sc; 181 int ofs; 182 183 ofs = ofs0 / 4; 184 if (ofs0 % 4 != 0) { 185 uint32_t ret; 186 187 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 188 ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN); 189 ret <<= 16; 190 191 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 192 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1)); 193 ret |= CSR_READ_2(sc, BWI_MOBJ_DATA); 194 195 return ret; 196 } else { 197 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 198 return CSR_READ_4(sc, BWI_MOBJ_DATA); 199 } 200 } 201 202 void 203 bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, 204 uint16_t v) 205 { 206 struct bwi_softc *sc = mac->mac_sc; 207 uint32_t data_reg; 208 int ofs; 209 210 data_reg = BWI_MOBJ_DATA; 211 ofs = ofs0 / 4; 212 213 if (ofs0 % 4 != 0) 214 data_reg = BWI_MOBJ_DATA_UNALIGN; 215 216 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 217 CSR_WRITE_2(sc, data_reg, v); 218 } 219 220 void 221 bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, 222 uint32_t v) 223 { 224 struct bwi_softc *sc = mac->mac_sc; 225 int ofs; 226 227 ofs = ofs0 / 4; 228 if (ofs0 % 4 != 0) { 229 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 230 CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16); 231 232 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 233 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1)); 234 CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff); 235 } else { 236 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs)); 237 CSR_WRITE_4(sc, BWI_MOBJ_DATA, v); 238 } 239 } 240 241 int 242 bwi_mac_lateattach(struct bwi_mac *mac) 243 { 244 int error; 245 246 if (mac->mac_rev >= 5) 247 CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */ 248 249 bwi_mac_reset(mac, 1); 250 251 error = bwi_phy_attach(mac); 252 if (error) 253 return error; 254 255 error = bwi_rf_attach(mac); 256 if (error) 257 return error; 258 259 /* Link 11B/G PHY, unlink 11A PHY */ 260 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) 261 bwi_mac_reset(mac, 0); 262 else 263 bwi_mac_reset(mac, 1); 264 265 error = bwi_mac_test(mac); 266 if (error) 267 return error; 268 269 error = bwi_mac_get_property(mac); 270 if (error) 271 return error; 272 273 error = bwi_rf_map_txpower(mac); 274 if (error) 275 return error; 276 277 bwi_rf_off(mac); 278 CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC); 279 bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0); 280 281 return 0; 282 } 283 284 int 285 bwi_mac_init(struct bwi_mac *mac) 286 { 287 struct bwi_softc *sc = mac->mac_sc; 288 int error, i; 289 290 /* Clear MAC/PHY/RF states */ 291 bwi_mac_setup_tpctl(mac); 292 bwi_rf_clear_state(&mac->mac_rf); 293 bwi_phy_clear_state(&mac->mac_phy); 294 295 /* Enable MAC and linked it to PHY */ 296 if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin)) 297 bwi_mac_reset(mac, 1); 298 299 /* Initialize backplane */ 300 error = bwi_bus_init(sc, mac); 301 if (error) 302 return error; 303 304 /* do timeout fixup */ 305 if (sc->sc_bus_regwin.rw_rev <= 5 && 306 sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) { 307 CSR_SETBITS_4(sc, BWI_CONF_LO, 308 __SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) | 309 __SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK)); 310 } 311 312 /* Calibrate PHY */ 313 error = bwi_phy_calibrate(mac); 314 if (error) { 315 device_printf(sc->sc_dev, "PHY calibrate failed\n"); 316 return error; 317 } 318 319 /* Prepare to initialize firmware */ 320 CSR_WRITE_4(sc, BWI_MAC_STATUS, 321 BWI_MAC_STATUS_UCODE_JUMP0 | 322 BWI_MAC_STATUS_IHREN); 323 324 /* 325 * Load and initialize firmwares 326 */ 327 error = bwi_mac_fw_load(mac); 328 if (error) 329 return error; 330 331 error = bwi_mac_gpio_init(mac); 332 if (error) 333 return error; 334 335 error = bwi_mac_fw_init(mac); 336 if (error) 337 return error; 338 339 /* 340 * Turn on RF 341 */ 342 bwi_rf_on(mac); 343 344 /* TODO: LED, hardware rf enabled is only related to LED setting */ 345 346 /* 347 * Initialize PHY 348 */ 349 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 350 bwi_phy_init(mac); 351 352 /* TODO: interference mitigation */ 353 354 /* 355 * Setup antenna mode 356 */ 357 bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode); 358 359 /* 360 * Initialize operation mode (RX configuration) 361 */ 362 bwi_mac_opmode_init(mac); 363 364 /* set up Beacon interval */ 365 if (mac->mac_rev < 3) { 366 CSR_WRITE_2(sc, 0x60e, 0); 367 CSR_WRITE_2(sc, 0x610, 0x8000); 368 CSR_WRITE_2(sc, 0x604, 0); 369 CSR_WRITE_2(sc, 0x606, 0x200); 370 } else { 371 CSR_WRITE_4(sc, 0x188, 0x80000000); 372 CSR_WRITE_4(sc, 0x18c, 0x2000000); 373 } 374 375 /* 376 * Initialize TX/RX interrupts' mask 377 */ 378 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1); 379 for (i = 0; i < BWI_TXRX_NRING; ++i) { 380 uint32_t intrs; 381 382 if (BWI_TXRX_IS_RX(i)) 383 intrs = BWI_TXRX_RX_INTRS; 384 else 385 intrs = BWI_TXRX_TX_INTRS; 386 CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs); 387 } 388 389 /* allow the MAC to control the PHY clock (dynamic on/off) */ 390 CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000); 391 392 /* Setup MAC power up delay */ 393 CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay); 394 395 /* Set MAC regwin revision */ 396 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev); 397 398 /* 399 * Initialize host flags 400 */ 401 bwi_mac_hostflags_init(mac); 402 403 /* 404 * Initialize BSS parameters 405 */ 406 bwi_mac_bss_param_init(mac); 407 408 /* 409 * Initialize TX rings 410 */ 411 for (i = 0; i < BWI_TX_NRING; ++i) { 412 error = sc->sc_init_tx_ring(sc, i); 413 if (error) { 414 device_printf(sc->sc_dev, 415 "can't initialize %dth TX ring\n", i); 416 return error; 417 } 418 } 419 420 /* 421 * Initialize RX ring 422 */ 423 error = sc->sc_init_rx_ring(sc); 424 if (error) { 425 device_printf(sc->sc_dev, "can't initialize RX ring\n"); 426 return error; 427 } 428 429 /* 430 * Initialize TX stats if the current MAC uses that 431 */ 432 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) { 433 error = sc->sc_init_txstats(sc); 434 if (error) { 435 device_printf(sc->sc_dev, 436 "can't initialize TX stats ring\n"); 437 return error; 438 } 439 } 440 441 /* update PRETBTT */ 442 CSR_WRITE_2(sc, 0x612, 0x50); /* Force Pre-TBTT to 80? */ 443 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50); 444 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4); 445 446 mac->mac_flags |= BWI_MAC_F_INITED; 447 return 0; 448 } 449 450 void 451 bwi_mac_reset(struct bwi_mac *mac, int link_phy) 452 { 453 struct bwi_softc *sc = mac->mac_sc; 454 uint32_t flags, state_lo, status; 455 456 flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN; 457 if (link_phy) 458 flags |= BWI_STATE_LO_FLAG_PHYLNK; 459 bwi_regwin_enable(sc, &mac->mac_regwin, flags); 460 DELAY(2000); 461 462 state_lo = CSR_READ_4(sc, BWI_STATE_LO); 463 state_lo |= BWI_STATE_LO_GATED_CLOCK; 464 state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST, 465 BWI_STATE_LO_FLAGS_MASK); 466 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 467 /* Flush pending bus write */ 468 CSR_READ_4(sc, BWI_STATE_LO); 469 DELAY(1000); 470 471 state_lo &= ~BWI_STATE_LO_GATED_CLOCK; 472 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo); 473 /* Flush pending bus write */ 474 CSR_READ_4(sc, BWI_STATE_LO); 475 DELAY(1000); 476 477 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 478 479 status = CSR_READ_4(sc, BWI_MAC_STATUS); 480 status |= BWI_MAC_STATUS_IHREN; 481 if (link_phy) 482 status |= BWI_MAC_STATUS_PHYLNK; 483 else 484 status &= ~BWI_MAC_STATUS_PHYLNK; 485 CSR_WRITE_4(sc, BWI_MAC_STATUS, status); 486 487 if (link_phy) { 488 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT, 489 "%s\n", "PHY is linked"); 490 mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED; 491 } else { 492 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT, 493 "%s\n", "PHY is unlinked"); 494 mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED; 495 } 496 } 497 498 void 499 bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl) 500 { 501 struct bwi_rf *rf = &mac->mac_rf; 502 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 503 504 if (new_tpctl != NULL) { 505 KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX, 506 ("bbp_atten %d", new_tpctl->bbp_atten)); 507 KASSERT(new_tpctl->rf_atten <= 508 (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0 509 : BWI_RF_ATTEN_MAX1), 510 ("rf_atten %d", new_tpctl->rf_atten)); 511 KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX, 512 ("tp_ctrl1 %d", new_tpctl->tp_ctrl1)); 513 514 tpctl->bbp_atten = new_tpctl->bbp_atten; 515 tpctl->rf_atten = new_tpctl->rf_atten; 516 tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1; 517 } 518 519 /* Set BBP attenuation */ 520 bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten); 521 522 /* Set RF attenuation */ 523 RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten); 524 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN, 525 tpctl->rf_atten); 526 527 /* Set TX power */ 528 if (rf->rf_type == BWI_RF_T_BCM2050) { 529 RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK, 530 __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK)); 531 } 532 533 /* Adjust RF Local Oscillator */ 534 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) 535 bwi_rf_lo_adjust(mac, tpctl); 536 } 537 538 static int 539 bwi_mac_test(struct bwi_mac *mac) 540 { 541 struct bwi_softc *sc = mac->mac_sc; 542 uint32_t orig_val, val; 543 544 #define TEST_VAL1 0xaa5555aa 545 #define TEST_VAL2 0x55aaaa55 546 547 /* Save it for later restoring */ 548 orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 549 550 /* Test 1 */ 551 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1); 552 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 553 if (val != TEST_VAL1) { 554 device_printf(sc->sc_dev, "TEST1 failed\n"); 555 return ENXIO; 556 } 557 558 /* Test 2 */ 559 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2); 560 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0); 561 if (val != TEST_VAL2) { 562 device_printf(sc->sc_dev, "TEST2 failed\n"); 563 return ENXIO; 564 } 565 566 /* Restore to the original value */ 567 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val); 568 569 val = CSR_READ_4(sc, BWI_MAC_STATUS); 570 if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) { 571 device_printf(sc->sc_dev, "%s failed, MAC status 0x%08x\n", 572 __func__, val); 573 return ENXIO; 574 } 575 576 val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 577 if (val != 0) { 578 device_printf(sc->sc_dev, "%s failed, intr status %08x\n", 579 __func__, val); 580 return ENXIO; 581 } 582 583 #undef TEST_VAL2 584 #undef TEST_VAL1 585 586 return 0; 587 } 588 589 static void 590 bwi_mac_setup_tpctl(struct bwi_mac *mac) 591 { 592 struct bwi_softc *sc = mac->mac_sc; 593 struct bwi_rf *rf = &mac->mac_rf; 594 struct bwi_phy *phy = &mac->mac_phy; 595 struct bwi_tpctl *tpctl = &mac->mac_tpctl; 596 597 /* Calc BBP attenuation */ 598 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6) 599 tpctl->bbp_atten = 0; 600 else 601 tpctl->bbp_atten = 2; 602 603 /* Calc TX power CTRL1?? */ 604 tpctl->tp_ctrl1 = 0; 605 if (rf->rf_type == BWI_RF_T_BCM2050) { 606 if (rf->rf_rev == 1) 607 tpctl->tp_ctrl1 = 3; 608 else if (rf->rf_rev < 6) 609 tpctl->tp_ctrl1 = 2; 610 else if (rf->rf_rev == 8) 611 tpctl->tp_ctrl1 = 1; 612 } 613 614 /* Empty TX power CTRL2?? */ 615 tpctl->tp_ctrl2 = 0xffff; 616 617 /* 618 * Calc RF attenuation 619 */ 620 if (phy->phy_mode == IEEE80211_MODE_11A) { 621 tpctl->rf_atten = 0x60; 622 goto back; 623 } 624 625 if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) { 626 tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3; 627 goto back; 628 } 629 630 tpctl->rf_atten = 5; 631 632 if (rf->rf_type != BWI_RF_T_BCM2050) { 633 if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1) 634 tpctl->rf_atten = 6; 635 goto back; 636 } 637 638 /* 639 * NB: If we reaches here and the card is BRCM_BCM4309G, 640 * then the card's PCI revision must >= 0x51 641 */ 642 643 /* BCM2050 RF */ 644 switch (rf->rf_rev) { 645 case 1: 646 if (phy->phy_mode == IEEE80211_MODE_11G) { 647 if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc)) 648 tpctl->rf_atten = 3; 649 else 650 tpctl->rf_atten = 1; 651 } else { 652 if (BWI_IS_BRCM_BCM4309G(sc)) 653 tpctl->rf_atten = 7; 654 else 655 tpctl->rf_atten = 6; 656 } 657 break; 658 case 2: 659 if (phy->phy_mode == IEEE80211_MODE_11G) { 660 /* 661 * NOTE: Order of following conditions is critical 662 */ 663 if (BWI_IS_BRCM_BCM4309G(sc)) 664 tpctl->rf_atten = 3; 665 else if (BWI_IS_BRCM_BU4306(sc)) 666 tpctl->rf_atten = 5; 667 else if (sc->sc_bbp_id == BWI_BBPID_BCM4320) 668 tpctl->rf_atten = 4; 669 else 670 tpctl->rf_atten = 3; 671 } else { 672 tpctl->rf_atten = 6; 673 } 674 break; 675 case 4: 676 case 5: 677 tpctl->rf_atten = 1; 678 break; 679 case 8: 680 tpctl->rf_atten = 0x1a; 681 break; 682 } 683 back: 684 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER, 685 "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n", 686 tpctl->bbp_atten, tpctl->rf_atten, 687 tpctl->tp_ctrl1, tpctl->tp_ctrl2); 688 } 689 690 void 691 bwi_mac_dummy_xmit(struct bwi_mac *mac) 692 { 693 #define PACKET_LEN 5 694 static const uint32_t packet_11a[PACKET_LEN] = 695 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; 696 static const uint32_t packet_11bg[PACKET_LEN] = 697 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; 698 699 struct bwi_softc *sc = mac->mac_sc; 700 struct bwi_rf *rf = &mac->mac_rf; 701 const uint32_t *packet; 702 uint16_t val_50c; 703 int wait_max, i; 704 705 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { 706 wait_max = 30; 707 packet = packet_11a; 708 val_50c = 1; 709 } else { 710 wait_max = 250; 711 packet = packet_11bg; 712 val_50c = 0; 713 } 714 715 for (i = 0; i < PACKET_LEN; ++i) 716 TMPLT_WRITE_4(mac, i * 4, packet[i]); 717 718 CSR_READ_4(sc, BWI_MAC_STATUS); /* dummy read */ 719 720 CSR_WRITE_2(sc, 0x568, 0); 721 CSR_WRITE_2(sc, 0x7c0, 0); 722 CSR_WRITE_2(sc, 0x50c, val_50c); 723 CSR_WRITE_2(sc, 0x508, 0); 724 CSR_WRITE_2(sc, 0x50a, 0); 725 CSR_WRITE_2(sc, 0x54c, 0); 726 CSR_WRITE_2(sc, 0x56a, 0x14); 727 CSR_WRITE_2(sc, 0x568, 0x826); 728 CSR_WRITE_2(sc, 0x500, 0); 729 CSR_WRITE_2(sc, 0x502, 0x30); 730 731 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5) 732 RF_WRITE(mac, 0x51, 0x17); 733 734 for (i = 0; i < wait_max; ++i) { 735 if (CSR_READ_2(sc, 0x50e) & 0x80) 736 break; 737 DELAY(10); 738 } 739 for (i = 0; i < 10; ++i) { 740 if (CSR_READ_2(sc, 0x50e) & 0x400) 741 break; 742 DELAY(10); 743 } 744 for (i = 0; i < 10; ++i) { 745 if ((CSR_READ_2(sc, 0x690) & 0x100) == 0) 746 break; 747 DELAY(10); 748 } 749 750 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5) 751 RF_WRITE(mac, 0x51, 0x37); 752 #undef PACKET_LEN 753 } 754 755 void 756 bwi_mac_init_tpctl_11bg(struct bwi_mac *mac) 757 { 758 struct bwi_softc *sc = mac->mac_sc; 759 struct bwi_phy *phy = &mac->mac_phy; 760 struct bwi_rf *rf = &mac->mac_rf; 761 struct bwi_tpctl tpctl_orig; 762 int restore_tpctl = 0; 763 764 KASSERT(phy->phy_mode != IEEE80211_MODE_11A, 765 ("phy_mode %d", phy->phy_mode)); 766 767 if (BWI_IS_BRCM_BU4306(sc)) 768 return; 769 770 PHY_WRITE(mac, 0x28, 0x8018); 771 CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20); 772 773 if (phy->phy_mode == IEEE80211_MODE_11G) { 774 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0) 775 return; 776 PHY_WRITE(mac, 0x47a, 0xc111); 777 } 778 if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED) 779 return; 780 781 if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 && 782 rf->rf_type == BWI_RF_T_BCM2050) { 783 RF_SETBITS(mac, 0x76, 0x84); 784 } else { 785 struct bwi_tpctl tpctl; 786 787 /* Backup original TX power control variables */ 788 bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig)); 789 restore_tpctl = 1; 790 791 bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl)); 792 tpctl.bbp_atten = 11; 793 tpctl.tp_ctrl1 = 0; 794 #ifdef notyet 795 if (rf->rf_rev >= 6 && rf->rf_rev <= 8) 796 tpctl.rf_atten = 31; 797 else 798 #endif 799 tpctl.rf_atten = 9; 800 801 bwi_mac_set_tpctl_11bg(mac, &tpctl); 802 } 803 804 bwi_mac_dummy_xmit(mac); 805 806 mac->mac_flags |= BWI_MAC_F_TPCTL_INITED; 807 rf->rf_base_tssi = PHY_READ(mac, 0x29); 808 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER, 809 "base tssi %d\n", rf->rf_base_tssi); 810 811 if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) { 812 device_printf(sc->sc_dev, "base tssi measure failed\n"); 813 mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR; 814 } 815 816 if (restore_tpctl) 817 bwi_mac_set_tpctl_11bg(mac, &tpctl_orig); 818 else 819 RF_CLRBITS(mac, 0x76, 0x84); 820 821 bwi_rf_clear_tssi(mac); 822 } 823 824 void 825 bwi_mac_detach(struct bwi_mac *mac) 826 { 827 bwi_mac_fw_free(mac); 828 } 829 830 static __inline int 831 bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw, 832 uint8_t fw_type) 833 { 834 const struct bwi_fwhdr *hdr; 835 struct ifnet *ifp = sc->sc_ifp; 836 837 if (fw->datasize < sizeof(*hdr)) { 838 if_printf(ifp, "invalid firmware (%s): invalid size %zu\n", 839 fw->name, fw->datasize); 840 return 0; 841 } 842 843 hdr = (const struct bwi_fwhdr *)fw->data; 844 845 if (fw_type != BWI_FW_T_IV) { 846 /* 847 * Don't verify IV's size, it has different meaning 848 */ 849 if (be32toh(hdr->fw_size) != fw->datasize - sizeof(*hdr)) { 850 if_printf(ifp, "invalid firmware (%s): size mismatch, " 851 "fw %u, real %zu\n", fw->name, 852 be32toh(hdr->fw_size), 853 fw->datasize - sizeof(*hdr)); 854 return 0; 855 } 856 } 857 858 if (hdr->fw_type != fw_type) { 859 if_printf(ifp, "invalid firmware (%s): type mismatch, " 860 "fw \'%c\', target \'%c\'\n", fw->name, 861 hdr->fw_type, fw_type); 862 return 0; 863 } 864 865 if (hdr->fw_gen != BWI_FW_GEN_1) { 866 if_printf(ifp, "invalid firmware (%s): wrong generation, " 867 "fw %d, target %d\n", fw->name, 868 hdr->fw_gen, BWI_FW_GEN_1); 869 return 0; 870 } 871 return 1; 872 } 873 874 /* 875 * XXX Error cleanup 876 */ 877 int 878 bwi_mac_fw_alloc(struct bwi_mac *mac) 879 { 880 struct bwi_softc *sc = mac->mac_sc; 881 char fwname[64]; 882 int idx; 883 884 /* 885 * Try getting the firmware stub so firmware 886 * module would be loaded automatically 887 */ 888 if (mac->mac_stub == NULL) { 889 snprintf(fwname, sizeof(fwname), BWI_FW_STUB_PATH, 890 sc->sc_fw_version); 891 mac->mac_stub = firmware_get(fwname); 892 if (mac->mac_stub == NULL) 893 goto no_firmware; 894 } 895 896 if (mac->mac_ucode == NULL) { 897 snprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH, 898 sc->sc_fw_version, 899 mac->mac_rev >= 5 ? 5 : mac->mac_rev); 900 901 mac->mac_ucode = firmware_get(fwname); 902 if (mac->mac_ucode == NULL) 903 goto no_firmware; 904 if (!bwi_fwimage_is_valid(sc, mac->mac_ucode, BWI_FW_T_UCODE)) 905 return EINVAL; 906 } 907 908 if (mac->mac_pcm == NULL) { 909 snprintf(fwname, sizeof(fwname), BWI_FW_PCM_PATH, 910 sc->sc_fw_version, 911 mac->mac_rev < 5 ? 4 : 5); 912 913 mac->mac_pcm = firmware_get(fwname); 914 if (mac->mac_pcm == NULL) 915 goto no_firmware; 916 if (!bwi_fwimage_is_valid(sc, mac->mac_pcm, BWI_FW_T_PCM)) 917 return EINVAL; 918 } 919 920 if (mac->mac_iv == NULL) { 921 /* TODO: 11A */ 922 if (mac->mac_rev == 2 || mac->mac_rev == 4) { 923 idx = 2; 924 } else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) { 925 idx = 5; 926 } else { 927 device_printf(sc->sc_dev, 928 "no suitible IV for MAC rev %d\n", mac->mac_rev); 929 return ENODEV; 930 } 931 932 snprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH, 933 sc->sc_fw_version, idx); 934 935 mac->mac_iv = firmware_get(fwname); 936 if (mac->mac_iv == NULL) 937 goto no_firmware; 938 if (!bwi_fwimage_is_valid(sc, mac->mac_iv, BWI_FW_T_IV)) 939 return EINVAL; 940 } 941 942 if (mac->mac_iv_ext == NULL) { 943 /* TODO: 11A */ 944 if (mac->mac_rev == 2 || mac->mac_rev == 4 || 945 mac->mac_rev >= 11) { 946 /* No extended IV */ 947 return (0); 948 } else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) { 949 idx = 5; 950 } else { 951 device_printf(sc->sc_dev, 952 "no suitible ExtIV for MAC rev %d\n", mac->mac_rev); 953 return ENODEV; 954 } 955 956 snprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH, 957 sc->sc_fw_version, idx); 958 959 mac->mac_iv_ext = firmware_get(fwname); 960 if (mac->mac_iv_ext == NULL) 961 goto no_firmware; 962 if (!bwi_fwimage_is_valid(sc, mac->mac_iv_ext, BWI_FW_T_IV)) 963 return EINVAL; 964 } 965 return (0); 966 967 no_firmware: 968 device_printf(sc->sc_dev, "request firmware %s failed\n", fwname); 969 return (ENOENT); 970 } 971 972 static void 973 bwi_mac_fw_free(struct bwi_mac *mac) 974 { 975 if (mac->mac_ucode != NULL) { 976 firmware_put(mac->mac_ucode, FIRMWARE_UNLOAD); 977 mac->mac_ucode = NULL; 978 } 979 980 if (mac->mac_pcm != NULL) { 981 firmware_put(mac->mac_pcm, FIRMWARE_UNLOAD); 982 mac->mac_pcm = NULL; 983 } 984 985 if (mac->mac_iv != NULL) { 986 firmware_put(mac->mac_iv, FIRMWARE_UNLOAD); 987 mac->mac_iv = NULL; 988 } 989 990 if (mac->mac_iv_ext != NULL) { 991 firmware_put(mac->mac_iv_ext, FIRMWARE_UNLOAD); 992 mac->mac_iv_ext = NULL; 993 } 994 995 if (mac->mac_stub != NULL) { 996 firmware_put(mac->mac_stub, FIRMWARE_UNLOAD); 997 mac->mac_stub = NULL; 998 } 999 } 1000 1001 static int 1002 bwi_mac_fw_load(struct bwi_mac *mac) 1003 { 1004 struct bwi_softc *sc = mac->mac_sc; 1005 struct ifnet *ifp = sc->sc_ifp; 1006 const uint32_t *fw; 1007 uint16_t fw_rev; 1008 int fw_len, i; 1009 1010 /* 1011 * Load ucode image 1012 */ 1013 fw = (const uint32_t *) 1014 ((const uint8_t *)mac->mac_ucode->data + BWI_FWHDR_SZ); 1015 fw_len = (mac->mac_ucode->datasize - BWI_FWHDR_SZ) / sizeof(uint32_t); 1016 1017 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 1018 BWI_MOBJ_CTRL_VAL( 1019 BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0)); 1020 for (i = 0; i < fw_len; ++i) { 1021 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i])); 1022 DELAY(10); 1023 } 1024 1025 /* 1026 * Load PCM image 1027 */ 1028 fw = (const uint32_t *) 1029 ((const uint8_t *)mac->mac_pcm->data + BWI_FWHDR_SZ); 1030 fw_len = (mac->mac_pcm->datasize - BWI_FWHDR_SZ) / sizeof(uint32_t); 1031 1032 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 1033 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea)); 1034 CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000); 1035 1036 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, 1037 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb)); 1038 for (i = 0; i < fw_len; ++i) { 1039 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i])); 1040 DELAY(10); 1041 } 1042 1043 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS); 1044 CSR_WRITE_4(sc, BWI_MAC_STATUS, 1045 BWI_MAC_STATUS_UCODE_START | 1046 BWI_MAC_STATUS_IHREN | 1047 BWI_MAC_STATUS_INFRA); 1048 1049 #define NRETRY 200 1050 1051 for (i = 0; i < NRETRY; ++i) { 1052 uint32_t intr_status; 1053 1054 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 1055 if (intr_status == BWI_INTR_READY) 1056 break; 1057 DELAY(10); 1058 } 1059 if (i == NRETRY) { 1060 if_printf(ifp, "firmware (ucode&pcm) loading timed out\n"); 1061 return ETIMEDOUT; 1062 } 1063 1064 #undef NRETRY 1065 1066 CSR_READ_4(sc, BWI_MAC_INTR_STATUS); /* dummy read */ 1067 1068 fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV); 1069 if (fw_rev > BWI_FW_VERSION3_REVMAX) { 1070 if_printf(ifp, "firmware version 4 is not supported yet\n"); 1071 return ENODEV; 1072 } 1073 1074 if_printf(ifp, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev, 1075 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); 1076 return 0; 1077 } 1078 1079 static int 1080 bwi_mac_gpio_init(struct bwi_mac *mac) 1081 { 1082 struct bwi_softc *sc = mac->mac_sc; 1083 struct bwi_regwin *old, *gpio_rw; 1084 uint32_t filt, bits; 1085 int error; 1086 1087 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK); 1088 /* TODO:LED */ 1089 1090 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf); 1091 1092 filt = 0x1f; 1093 bits = 0xf; 1094 if (sc->sc_bbp_id == BWI_BBPID_BCM4301) { 1095 filt |= 0x60; 1096 bits |= 0x60; 1097 } 1098 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) { 1099 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200); 1100 filt |= 0x200; 1101 bits |= 0x200; 1102 } 1103 1104 gpio_rw = BWI_GPIO_REGWIN(sc); 1105 error = bwi_regwin_switch(sc, gpio_rw, &old); 1106 if (error) 1107 return error; 1108 1109 CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits); 1110 1111 return bwi_regwin_switch(sc, old, NULL); 1112 } 1113 1114 static int 1115 bwi_mac_gpio_fini(struct bwi_mac *mac) 1116 { 1117 struct bwi_softc *sc = mac->mac_sc; 1118 struct bwi_regwin *old, *gpio_rw; 1119 int error; 1120 1121 gpio_rw = BWI_GPIO_REGWIN(sc); 1122 error = bwi_regwin_switch(sc, gpio_rw, &old); 1123 if (error) 1124 return error; 1125 1126 CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0); 1127 1128 return bwi_regwin_switch(sc, old, NULL); 1129 } 1130 1131 static int 1132 bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) 1133 { 1134 struct bwi_softc *sc = mac->mac_sc; 1135 struct ifnet *ifp = sc->sc_ifp; 1136 const struct bwi_fwhdr *hdr; 1137 const struct bwi_fw_iv *iv; 1138 int n, i, iv_img_size; 1139 1140 /* Get the number of IVs in the IV image */ 1141 hdr = (const struct bwi_fwhdr *)fw->data; 1142 n = be32toh(hdr->fw_iv_cnt); 1143 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE, 1144 "IV count %d\n", n); 1145 1146 /* Calculate the IV image size, for later sanity check */ 1147 iv_img_size = fw->datasize - sizeof(*hdr); 1148 1149 /* Locate the first IV */ 1150 iv = (const struct bwi_fw_iv *) 1151 ((const uint8_t *)fw->data + sizeof(*hdr)); 1152 1153 for (i = 0; i < n; ++i) { 1154 uint16_t iv_ofs, ofs; 1155 int sz = 0; 1156 1157 if (iv_img_size < sizeof(iv->iv_ofs)) { 1158 if_printf(ifp, "invalid IV image, ofs\n"); 1159 return EINVAL; 1160 } 1161 iv_img_size -= sizeof(iv->iv_ofs); 1162 sz += sizeof(iv->iv_ofs); 1163 1164 iv_ofs = be16toh(iv->iv_ofs); 1165 1166 ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK); 1167 if (ofs >= 0x1000) { 1168 if_printf(ifp, "invalid ofs (0x%04x) " 1169 "for %dth iv\n", ofs, i); 1170 return EINVAL; 1171 } 1172 1173 if (iv_ofs & BWI_FW_IV_IS_32BIT) { 1174 uint32_t val32; 1175 1176 if (iv_img_size < sizeof(iv->iv_val.val32)) { 1177 if_printf(ifp, "invalid IV image, val32\n"); 1178 return EINVAL; 1179 } 1180 iv_img_size -= sizeof(iv->iv_val.val32); 1181 sz += sizeof(iv->iv_val.val32); 1182 1183 val32 = be32toh(iv->iv_val.val32); 1184 CSR_WRITE_4(sc, ofs, val32); 1185 } else { 1186 uint16_t val16; 1187 1188 if (iv_img_size < sizeof(iv->iv_val.val16)) { 1189 if_printf(ifp, "invalid IV image, val16\n"); 1190 return EINVAL; 1191 } 1192 iv_img_size -= sizeof(iv->iv_val.val16); 1193 sz += sizeof(iv->iv_val.val16); 1194 1195 val16 = be16toh(iv->iv_val.val16); 1196 CSR_WRITE_2(sc, ofs, val16); 1197 } 1198 1199 iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz); 1200 } 1201 1202 if (iv_img_size != 0) { 1203 if_printf(ifp, "invalid IV image, size left %d\n", iv_img_size); 1204 return EINVAL; 1205 } 1206 return 0; 1207 } 1208 1209 static int 1210 bwi_mac_fw_init(struct bwi_mac *mac) 1211 { 1212 struct ifnet *ifp = mac->mac_sc->sc_ifp; 1213 int error; 1214 1215 error = bwi_mac_fw_load_iv(mac, mac->mac_iv); 1216 if (error) { 1217 if_printf(ifp, "load IV failed\n"); 1218 return error; 1219 } 1220 1221 if (mac->mac_iv_ext != NULL) { 1222 error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext); 1223 if (error) 1224 if_printf(ifp, "load ExtIV failed\n"); 1225 } 1226 return error; 1227 } 1228 1229 static void 1230 bwi_mac_opmode_init(struct bwi_mac *mac) 1231 { 1232 struct bwi_softc *sc = mac->mac_sc; 1233 struct ifnet *ifp = sc->sc_ifp; 1234 struct ieee80211com *ic = ifp->if_l2com; 1235 uint32_t mac_status; 1236 uint16_t pre_tbtt; 1237 1238 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA); 1239 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA); 1240 1241 /* Set probe resp timeout to infinite */ 1242 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0); 1243 1244 /* 1245 * TODO: factor out following part 1246 */ 1247 1248 mac_status = CSR_READ_4(sc, BWI_MAC_STATUS); 1249 mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP | 1250 BWI_MAC_STATUS_PASS_CTL | 1251 BWI_MAC_STATUS_PASS_BCN | 1252 BWI_MAC_STATUS_PASS_BADPLCP | 1253 BWI_MAC_STATUS_PASS_BADFCS | 1254 BWI_MAC_STATUS_PROMISC); 1255 mac_status |= BWI_MAC_STATUS_INFRA; 1256 1257 /* Always turn on PROMISC on old hardware */ 1258 if (mac->mac_rev < 5) 1259 mac_status |= BWI_MAC_STATUS_PROMISC; 1260 1261 switch (ic->ic_opmode) { 1262 case IEEE80211_M_IBSS: 1263 mac_status &= ~BWI_MAC_STATUS_INFRA; 1264 break; 1265 case IEEE80211_M_HOSTAP: 1266 mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP; 1267 break; 1268 case IEEE80211_M_MONITOR: 1269 #if 0 1270 /* Do you want data from your microwave oven? */ 1271 mac_status |= BWI_MAC_STATUS_PASS_CTL | 1272 BWI_MAC_STATUS_PASS_BADPLCP | 1273 BWI_MAC_STATUS_PASS_BADFCS; 1274 #else 1275 mac_status |= BWI_MAC_STATUS_PASS_CTL; 1276 #endif 1277 /* Promisc? */ 1278 break; 1279 default: 1280 break; 1281 } 1282 1283 if (ic->ic_ifp->if_flags & IFF_PROMISC) 1284 mac_status |= BWI_MAC_STATUS_PROMISC; 1285 1286 CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status); 1287 1288 if (ic->ic_opmode != IEEE80211_M_IBSS && 1289 ic->ic_opmode != IEEE80211_M_HOSTAP) { 1290 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3) 1291 pre_tbtt = 100; 1292 else 1293 pre_tbtt = 50; 1294 } else { 1295 pre_tbtt = 2; 1296 } 1297 CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt); 1298 } 1299 1300 static void 1301 bwi_mac_hostflags_init(struct bwi_mac *mac) 1302 { 1303 struct bwi_softc *sc = mac->mac_sc; 1304 struct bwi_phy *phy = &mac->mac_phy; 1305 struct bwi_rf *rf = &mac->mac_rf; 1306 uint64_t host_flags; 1307 1308 if (phy->phy_mode == IEEE80211_MODE_11A) 1309 return; 1310 1311 host_flags = HFLAGS_READ(mac); 1312 host_flags |= BWI_HFLAG_SYM_WA; 1313 1314 if (phy->phy_mode == IEEE80211_MODE_11G) { 1315 if (phy->phy_rev == 1) 1316 host_flags |= BWI_HFLAG_GDC_WA; 1317 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 1318 host_flags |= BWI_HFLAG_OFDM_PA; 1319 } else if (phy->phy_mode == IEEE80211_MODE_11B) { 1320 if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050) 1321 host_flags &= ~BWI_HFLAG_GDC_WA; 1322 } else { 1323 panic("unknown PHY mode %u\n", phy->phy_mode); 1324 } 1325 1326 HFLAGS_WRITE(mac, host_flags); 1327 } 1328 1329 static void 1330 bwi_mac_bss_param_init(struct bwi_mac *mac) 1331 { 1332 struct bwi_softc *sc = mac->mac_sc; 1333 struct bwi_phy *phy = &mac->mac_phy; 1334 struct ifnet *ifp = sc->sc_ifp; 1335 struct ieee80211com *ic = ifp->if_l2com; 1336 const struct ieee80211_rate_table *rt; 1337 struct bwi_retry_lim lim; 1338 uint16_t cw_min; 1339 1340 /* 1341 * Set short/long retry limits 1342 */ 1343 bzero(&lim, sizeof(lim)); 1344 lim.shretry = BWI_SHRETRY; 1345 lim.shretry_fb = BWI_SHRETRY_FB; 1346 lim.lgretry = BWI_LGRETRY; 1347 lim.lgretry_fb = BWI_LGRETRY_FB; 1348 bwi_mac_set_retry_lim(mac, &lim); 1349 1350 /* 1351 * Implicitly prevent firmware from sending probe response 1352 * by setting its "probe response timeout" to 1us. 1353 */ 1354 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1); 1355 1356 /* 1357 * XXX MAC level acknowledge and CW min/max should depend 1358 * on the char rateset of the IBSS/BSS to join. 1359 * XXX this is all wrong; should be done on channel change 1360 */ 1361 if (phy->phy_mode == IEEE80211_MODE_11B) { 1362 rt = ieee80211_get_ratetable( 1363 ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_B)); 1364 bwi_mac_set_ackrates(mac, rt, 1365 &ic->ic_sup_rates[IEEE80211_MODE_11B]); 1366 } else { 1367 rt = ieee80211_get_ratetable( 1368 ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_G)); 1369 bwi_mac_set_ackrates(mac, rt, 1370 &ic->ic_sup_rates[IEEE80211_MODE_11G]); 1371 } 1372 1373 /* 1374 * Set CW min 1375 */ 1376 if (phy->phy_mode == IEEE80211_MODE_11B) 1377 cw_min = IEEE80211_CW_MIN_0; 1378 else 1379 cw_min = IEEE80211_CW_MIN_1; 1380 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min); 1381 1382 /* 1383 * Set CW max 1384 */ 1385 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX, 1386 IEEE80211_CW_MAX); 1387 } 1388 1389 static void 1390 bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim) 1391 { 1392 /* Short/Long retry limit */ 1393 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY, 1394 lim->shretry); 1395 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY, 1396 lim->lgretry); 1397 1398 /* Short/Long retry fallback limit */ 1399 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB, 1400 lim->shretry_fb); 1401 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB, 1402 lim->lgretry_fb); 1403 } 1404 1405 static void 1406 bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rate_table *rt, 1407 const struct ieee80211_rateset *rs) 1408 { 1409 int i; 1410 1411 /* XXX not standard conforming */ 1412 for (i = 0; i < rs->rs_nrates; ++i) { 1413 enum ieee80211_phytype modtype; 1414 uint16_t ofs; 1415 1416 modtype = ieee80211_rate2phytype(rt, 1417 rs->rs_rates[i] & IEEE80211_RATE_VAL); 1418 switch (modtype) { 1419 case IEEE80211_T_DS: 1420 ofs = 0x4c0; 1421 break; 1422 case IEEE80211_T_OFDM: 1423 ofs = 0x480; 1424 break; 1425 default: 1426 panic("unsupported modtype %u\n", modtype); 1427 } 1428 ofs += 2*(ieee80211_rate2plcp( 1429 rs->rs_rates[i] & IEEE80211_RATE_VAL, 1430 modtype) & 0xf); 1431 1432 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20, 1433 MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs)); 1434 } 1435 } 1436 1437 int 1438 bwi_mac_start(struct bwi_mac *mac) 1439 { 1440 struct bwi_softc *sc = mac->mac_sc; 1441 1442 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE); 1443 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY); 1444 1445 /* Flush pending bus writes */ 1446 CSR_READ_4(sc, BWI_MAC_STATUS); 1447 CSR_READ_4(sc, BWI_MAC_INTR_STATUS); 1448 1449 return bwi_mac_config_ps(mac); 1450 } 1451 1452 int 1453 bwi_mac_stop(struct bwi_mac *mac) 1454 { 1455 struct bwi_softc *sc = mac->mac_sc; 1456 int error, i; 1457 1458 error = bwi_mac_config_ps(mac); 1459 if (error) 1460 return error; 1461 1462 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE); 1463 1464 /* Flush pending bus write */ 1465 CSR_READ_4(sc, BWI_MAC_STATUS); 1466 1467 #define NRETRY 10000 1468 for (i = 0; i < NRETRY; ++i) { 1469 if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY) 1470 break; 1471 DELAY(1); 1472 } 1473 if (i == NRETRY) { 1474 device_printf(sc->sc_dev, "can't stop MAC\n"); 1475 return ETIMEDOUT; 1476 } 1477 #undef NRETRY 1478 1479 return 0; 1480 } 1481 1482 int 1483 bwi_mac_config_ps(struct bwi_mac *mac) 1484 { 1485 struct bwi_softc *sc = mac->mac_sc; 1486 uint32_t status; 1487 1488 status = CSR_READ_4(sc, BWI_MAC_STATUS); 1489 1490 status &= ~BWI_MAC_STATUS_HW_PS; 1491 status |= BWI_MAC_STATUS_WAKEUP; 1492 CSR_WRITE_4(sc, BWI_MAC_STATUS, status); 1493 1494 /* Flush pending bus write */ 1495 CSR_READ_4(sc, BWI_MAC_STATUS); 1496 1497 if (mac->mac_rev >= 5) { 1498 int i; 1499 1500 #define NRETRY 100 1501 for (i = 0; i < NRETRY; ++i) { 1502 if (MOBJ_READ_2(mac, BWI_COMM_MOBJ, 1503 BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS) 1504 break; 1505 DELAY(10); 1506 } 1507 if (i == NRETRY) { 1508 device_printf(sc->sc_dev, "config PS failed\n"); 1509 return ETIMEDOUT; 1510 } 1511 #undef NRETRY 1512 } 1513 return 0; 1514 } 1515 1516 void 1517 bwi_mac_reset_hwkeys(struct bwi_mac *mac) 1518 { 1519 /* TODO: firmware crypto */ 1520 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS); 1521 } 1522 1523 void 1524 bwi_mac_shutdown(struct bwi_mac *mac) 1525 { 1526 struct bwi_softc *sc = mac->mac_sc; 1527 int i; 1528 1529 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) 1530 sc->sc_free_txstats(sc); 1531 1532 sc->sc_free_rx_ring(sc); 1533 1534 for (i = 0; i < BWI_TX_NRING; ++i) 1535 sc->sc_free_tx_ring(sc, i); 1536 1537 bwi_rf_off(mac); 1538 1539 /* TODO:LED */ 1540 1541 bwi_mac_gpio_fini(mac); 1542 1543 bwi_rf_off(mac); /* XXX again */ 1544 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC); 1545 bwi_regwin_disable(sc, &mac->mac_regwin, 0); 1546 1547 mac->mac_flags &= ~BWI_MAC_F_INITED; 1548 } 1549 1550 static int 1551 bwi_mac_get_property(struct bwi_mac *mac) 1552 { 1553 struct bwi_softc *sc = mac->mac_sc; 1554 enum bwi_bus_space old_bus_space; 1555 uint32_t val; 1556 1557 /* 1558 * Byte swap 1559 */ 1560 val = CSR_READ_4(sc, BWI_MAC_STATUS); 1561 if (val & BWI_MAC_STATUS_BSWAP) { 1562 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1563 "need byte swap"); 1564 mac->mac_flags |= BWI_MAC_F_BSWAP; 1565 } 1566 1567 /* 1568 * DMA address space 1569 */ 1570 old_bus_space = sc->sc_bus_space; 1571 1572 val = CSR_READ_4(sc, BWI_STATE_HI); 1573 if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) & 1574 BWI_STATE_HI_FLAG_64BIT) { 1575 /* 64bit address */ 1576 sc->sc_bus_space = BWI_BUS_SPACE_64BIT; 1577 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1578 "64bit bus space"); 1579 } else { 1580 uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL; 1581 1582 CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK); 1583 if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) { 1584 /* 32bit address */ 1585 sc->sc_bus_space = BWI_BUS_SPACE_32BIT; 1586 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1587 "32bit bus space"); 1588 } else { 1589 /* 30bit address */ 1590 sc->sc_bus_space = BWI_BUS_SPACE_30BIT; 1591 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1592 "30bit bus space"); 1593 } 1594 } 1595 1596 if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) { 1597 device_printf(sc->sc_dev, "MACs bus space mismatch!\n"); 1598 return ENXIO; 1599 } 1600 return 0; 1601 } 1602 1603 void 1604 bwi_mac_updateslot(struct bwi_mac *mac, int shslot) 1605 { 1606 uint16_t slot_time; 1607 1608 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) 1609 return; 1610 1611 if (shslot) 1612 slot_time = IEEE80211_DUR_SHSLOT; 1613 else 1614 slot_time = IEEE80211_DUR_SLOT; 1615 1616 CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME, 1617 slot_time + BWI_MAC_SLOTTIME_ADJUST); 1618 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time); 1619 } 1620 1621 int 1622 bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev) 1623 { 1624 struct bwi_mac *mac; 1625 int i; 1626 1627 KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0, 1628 ("sc_nmac %d", sc->sc_nmac)); 1629 1630 if (sc->sc_nmac == BWI_MAC_MAX) { 1631 device_printf(sc->sc_dev, "too many MACs\n"); 1632 return 0; 1633 } 1634 1635 /* 1636 * More than one MAC is only supported by BCM4309 1637 */ 1638 if (sc->sc_nmac != 0 && 1639 sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) { 1640 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1641 "ignore second MAC"); 1642 return 0; 1643 } 1644 1645 mac = &sc->sc_mac[sc->sc_nmac]; 1646 1647 /* XXX will this happen? */ 1648 if (BWI_REGWIN_EXIST(&mac->mac_regwin)) { 1649 device_printf(sc->sc_dev, "%dth MAC already attached\n", 1650 sc->sc_nmac); 1651 return 0; 1652 } 1653 1654 /* 1655 * Test whether the revision of this MAC is supported 1656 */ 1657 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 1658 for (i = 0; i < N(bwi_sup_macrev); ++i) { 1659 if (bwi_sup_macrev[i] == rev) 1660 break; 1661 } 1662 if (i == N(bwi_sup_macrev)) { 1663 device_printf(sc->sc_dev, "MAC rev %u is " 1664 "not supported\n", rev); 1665 return ENXIO; 1666 } 1667 #undef N 1668 1669 BWI_CREATE_MAC(mac, sc, id, rev); 1670 sc->sc_nmac++; 1671 1672 if (mac->mac_rev < 5) { 1673 mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS; 1674 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", 1675 "has TX stats"); 1676 } else { 1677 mac->mac_flags |= BWI_MAC_F_PHYE_RESET; 1678 } 1679 1680 device_printf(sc->sc_dev, "MAC: rev %u\n", rev); 1681 return 0; 1682 } 1683 1684 static __inline void 1685 bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0) 1686 { 1687 int bbp_atten, rf_atten, rf_atten_lim = -1; 1688 1689 bbp_atten = *bbp_atten0; 1690 rf_atten = *rf_atten0; 1691 1692 /* 1693 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times 1694 * as much as BBP attenuation, so we try our best to keep RF 1695 * attenuation within range. BBP attenuation will be clamped 1696 * later if it is out of range during balancing. 1697 * 1698 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit. 1699 */ 1700 1701 /* 1702 * Use BBP attenuation to balance RF attenuation 1703 */ 1704 if (rf_atten < 0) 1705 rf_atten_lim = 0; 1706 else if (rf_atten > BWI_RF_ATTEN_MAX0) 1707 rf_atten_lim = BWI_RF_ATTEN_MAX0; 1708 1709 if (rf_atten_lim >= 0) { 1710 bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim)); 1711 rf_atten = rf_atten_lim; 1712 } 1713 1714 /* 1715 * If possible, use RF attenuation to balance BBP attenuation 1716 * NOTE: RF attenuation is still kept within range. 1717 */ 1718 while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) { 1719 bbp_atten -= BWI_RF_ATTEN_FACTOR; 1720 ++rf_atten; 1721 } 1722 while (rf_atten > 0 && bbp_atten < 0) { 1723 bbp_atten += BWI_RF_ATTEN_FACTOR; 1724 --rf_atten; 1725 } 1726 1727 /* RF attenuation MUST be within range */ 1728 KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0, 1729 ("rf_atten %d", rf_atten)); 1730 1731 /* 1732 * Clamp BBP attenuation 1733 */ 1734 if (bbp_atten < 0) 1735 bbp_atten = 0; 1736 else if (bbp_atten > BWI_BBP_ATTEN_MAX) 1737 bbp_atten = BWI_BBP_ATTEN_MAX; 1738 1739 *rf_atten0 = rf_atten; 1740 *bbp_atten0 = bbp_atten; 1741 } 1742 1743 static void 1744 bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj) 1745 { 1746 struct bwi_softc *sc = mac->mac_sc; 1747 struct bwi_rf *rf = &mac->mac_rf; 1748 struct bwi_tpctl tpctl; 1749 int bbp_atten, rf_atten, tp_ctrl1; 1750 1751 bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl)); 1752 1753 /* NOTE: Use signed value to do calulation */ 1754 bbp_atten = tpctl.bbp_atten; 1755 rf_atten = tpctl.rf_atten; 1756 tp_ctrl1 = tpctl.tp_ctrl1; 1757 1758 bbp_atten += bbp_atten_adj; 1759 rf_atten += rf_atten_adj; 1760 1761 bwi_mac_balance_atten(&bbp_atten, &rf_atten); 1762 1763 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) { 1764 if (rf_atten <= 1) { 1765 if (tp_ctrl1 == 0) { 1766 tp_ctrl1 = 3; 1767 bbp_atten += 2; 1768 rf_atten += 2; 1769 } else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) { 1770 bbp_atten += 1771 (BWI_RF_ATTEN_FACTOR * (rf_atten - 2)); 1772 rf_atten = 2; 1773 } 1774 } else if (rf_atten > 4 && tp_ctrl1 != 0) { 1775 tp_ctrl1 = 0; 1776 if (bbp_atten < 3) { 1777 bbp_atten += 2; 1778 rf_atten -= 3; 1779 } else { 1780 bbp_atten -= 2; 1781 rf_atten -= 2; 1782 } 1783 } 1784 bwi_mac_balance_atten(&bbp_atten, &rf_atten); 1785 } 1786 1787 tpctl.bbp_atten = bbp_atten; 1788 tpctl.rf_atten = rf_atten; 1789 tpctl.tp_ctrl1 = tp_ctrl1; 1790 1791 bwi_mac_lock(mac); 1792 bwi_mac_set_tpctl_11bg(mac, &tpctl); 1793 bwi_mac_unlock(mac); 1794 } 1795 1796 /* 1797 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower 1798 */ 1799 void 1800 bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type) 1801 { 1802 struct bwi_softc *sc = mac->mac_sc; 1803 struct bwi_rf *rf = &mac->mac_rf; 1804 int8_t tssi[4], tssi_avg, cur_txpwr; 1805 int error, i, ofdm_tssi; 1806 int txpwr_diff, rf_atten_adj, bbp_atten_adj; 1807 1808 if (!sc->sc_txpwr_calib) 1809 return; 1810 1811 if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) { 1812 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 1813 "tpctl error happened, can't set txpower"); 1814 return; 1815 } 1816 1817 if (BWI_IS_BRCM_BU4306(sc)) { 1818 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 1819 "BU4306, can't set txpower"); 1820 return; 1821 } 1822 1823 /* 1824 * Save latest TSSI and reset the related memory objects 1825 */ 1826 ofdm_tssi = 0; 1827 error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS); 1828 if (error) { 1829 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 1830 "no DS tssi"); 1831 1832 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) { 1833 if (type == BWI_TXPWR_FORCE) { 1834 rf_atten_adj = 0; 1835 bbp_atten_adj = 1; 1836 goto calib; 1837 } else { 1838 return; 1839 } 1840 } 1841 1842 error = bwi_rf_get_latest_tssi(mac, tssi, 1843 BWI_COMM_MOBJ_TSSI_OFDM); 1844 if (error) { 1845 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 1846 "no OFDM tssi"); 1847 if (type == BWI_TXPWR_FORCE) { 1848 rf_atten_adj = 0; 1849 bbp_atten_adj = 1; 1850 goto calib; 1851 } else { 1852 return; 1853 } 1854 } 1855 1856 for (i = 0; i < 4; ++i) { 1857 tssi[i] += 0x20; 1858 tssi[i] &= 0x3f; 1859 } 1860 ofdm_tssi = 1; 1861 } 1862 bwi_rf_clear_tssi(mac); 1863 1864 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 1865 "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n", 1866 tssi[0], tssi[1], tssi[2], tssi[3]); 1867 1868 /* 1869 * Calculate RF/BBP attenuation adjustment based on 1870 * the difference between desired TX power and sampled 1871 * TX power. 1872 */ 1873 /* +8 == "each incremented by 1/2" */ 1874 tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4; 1875 if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS)) 1876 tssi_avg -= 13; 1877 1878 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "tssi avg %d\n", tssi_avg); 1879 1880 error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr); 1881 if (error) 1882 return; 1883 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "current txpower %d\n", 1884 cur_txpwr); 1885 1886 txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */ 1887 1888 rf_atten_adj = -howmany(txpwr_diff, 8); 1889 if (type == BWI_TXPWR_INIT) { 1890 /* 1891 * Move toward EEPROM max TX power as fast as we can 1892 */ 1893 bbp_atten_adj = -txpwr_diff; 1894 } else { 1895 bbp_atten_adj = -(txpwr_diff / 2); 1896 } 1897 bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj); 1898 1899 if (rf_atten_adj == 0 && bbp_atten_adj == 0) { 1900 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n", 1901 "no need to adjust RF/BBP attenuation"); 1902 /* TODO: LO */ 1903 return; 1904 } 1905 1906 calib: 1907 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, 1908 "rf atten adjust %d, bbp atten adjust %d\n", 1909 rf_atten_adj, bbp_atten_adj); 1910 bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj); 1911 /* TODO: LO */ 1912 } 1913 1914 static void 1915 bwi_mac_lock(struct bwi_mac *mac) 1916 { 1917 struct bwi_softc *sc = mac->mac_sc; 1918 struct ifnet *ifp = sc->sc_ifp; 1919 struct ieee80211com *ic = ifp->if_l2com; 1920 1921 KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0, 1922 ("mac_flags 0x%x", mac->mac_flags)); 1923 1924 if (mac->mac_rev < 3) 1925 bwi_mac_stop(mac); 1926 else if (ic->ic_opmode != IEEE80211_M_HOSTAP) 1927 bwi_mac_config_ps(mac); 1928 1929 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK); 1930 1931 /* Flush pending bus write */ 1932 CSR_READ_4(sc, BWI_MAC_STATUS); 1933 DELAY(10); 1934 1935 mac->mac_flags |= BWI_MAC_F_LOCKED; 1936 } 1937 1938 static void 1939 bwi_mac_unlock(struct bwi_mac *mac) 1940 { 1941 struct bwi_softc *sc = mac->mac_sc; 1942 struct ifnet *ifp = sc->sc_ifp; 1943 struct ieee80211com *ic = ifp->if_l2com; 1944 1945 KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED, 1946 ("mac_flags 0x%x", mac->mac_flags)); 1947 1948 CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */ 1949 1950 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK); 1951 1952 if (mac->mac_rev < 3) 1953 bwi_mac_start(mac); 1954 else if (ic->ic_opmode != IEEE80211_M_HOSTAP) 1955 bwi_mac_config_ps(mac); 1956 1957 mac->mac_flags &= ~BWI_MAC_F_LOCKED; 1958 } 1959 1960 void 1961 bwi_mac_set_promisc(struct bwi_mac *mac, int promisc) 1962 { 1963 struct bwi_softc *sc = mac->mac_sc; 1964 1965 if (mac->mac_rev < 5) /* Promisc is always on */ 1966 return; 1967 1968 if (promisc) 1969 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC); 1970 else 1971 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC); 1972 } 1973