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