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