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