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