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