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