1 /*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 #include "opt_bwn.h" 32 #include "opt_wlan.h" 33 34 /* 35 * The Broadcom Wireless LAN controller driver. 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/kernel.h> 41 #include <sys/malloc.h> 42 #include <sys/module.h> 43 #include <sys/endian.h> 44 #include <sys/errno.h> 45 #include <sys/firmware.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <machine/bus.h> 49 #include <machine/resource.h> 50 #include <sys/bus.h> 51 #include <sys/rman.h> 52 #include <sys/socket.h> 53 #include <sys/sockio.h> 54 55 #include <net/ethernet.h> 56 #include <net/if.h> 57 #include <net/if_var.h> 58 #include <net/if_arp.h> 59 #include <net/if_dl.h> 60 #include <net/if_llc.h> 61 #include <net/if_media.h> 62 #include <net/if_types.h> 63 64 #include <dev/pci/pcivar.h> 65 #include <dev/pci/pcireg.h> 66 67 #include <net80211/ieee80211_var.h> 68 #include <net80211/ieee80211_radiotap.h> 69 #include <net80211/ieee80211_regdomain.h> 70 #include <net80211/ieee80211_phy.h> 71 #include <net80211/ieee80211_ratectl.h> 72 73 #include <dev/bwn/if_bwnreg.h> 74 #include <dev/bwn/if_bwnvar.h> 75 76 #include <dev/bwn/if_bwn_debug.h> 77 #include <dev/bwn/if_bwn_misc.h> 78 #include <dev/bwn/if_bwn_phy_g.h> 79 80 #include "bhnd_nvram_map.h" 81 82 static void bwn_phy_g_init_sub(struct bwn_mac *); 83 static uint8_t bwn_has_hwpctl(struct bwn_mac *); 84 static void bwn_phy_init_b5(struct bwn_mac *); 85 static void bwn_phy_init_b6(struct bwn_mac *); 86 static void bwn_phy_init_a(struct bwn_mac *); 87 static void bwn_loopback_calcgain(struct bwn_mac *); 88 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *); 89 static void bwn_lo_g_init(struct bwn_mac *); 90 static void bwn_lo_g_adjust(struct bwn_mac *); 91 static void bwn_lo_get_powervector(struct bwn_mac *); 92 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *, 93 const struct bwn_bbatt *, const struct bwn_rfatt *); 94 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *); 95 static void bwn_phy_hwpctl_init(struct bwn_mac *); 96 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t); 97 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *, 98 const struct bwn_bbatt *, const struct bwn_rfatt *, 99 uint8_t); 100 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t); 101 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t); 102 static void bwn_spu_workaround(struct bwn_mac *, uint8_t); 103 static void bwn_wa_init(struct bwn_mac *); 104 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t, 105 uint16_t); 106 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t, 107 uint32_t); 108 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t, 109 uint16_t); 110 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t); 111 static void bwn_nrssi_offset(struct bwn_mac *); 112 static void bwn_nrssi_threshold(struct bwn_mac *); 113 static void bwn_nrssi_slope_11g(struct bwn_mac *); 114 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t, 115 int16_t); 116 static void bwn_set_original_gains(struct bwn_mac *); 117 static void bwn_hwpctl_early_init(struct bwn_mac *); 118 static void bwn_hwpctl_init_gphy(struct bwn_mac *); 119 static uint16_t bwn_phy_g_chan2freq(uint8_t); 120 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t); 121 122 /* Stuff we need */ 123 124 static uint16_t bwn_phy_g_txctl(struct bwn_mac *mac); 125 static int bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset); 126 static void bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp); 127 static void bwn_phy_lock(struct bwn_mac *mac); 128 static void bwn_phy_unlock(struct bwn_mac *mac); 129 static void bwn_rf_lock(struct bwn_mac *mac); 130 static void bwn_rf_unlock(struct bwn_mac *mac); 131 132 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1; 133 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2; 134 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1; 135 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2; 136 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3; 137 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE; 138 139 static uint8_t 140 bwn_has_hwpctl(struct bwn_mac *mac) 141 { 142 143 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL) 144 return (0); 145 return (mac->mac_phy.use_hwpctl(mac)); 146 } 147 148 int 149 bwn_phy_g_attach(struct bwn_mac *mac) 150 { 151 struct bwn_softc *sc = mac->mac_sc; 152 struct bwn_phy *phy = &mac->mac_phy; 153 struct bwn_phy_g *pg = &phy->phy_g; 154 unsigned int i; 155 int16_t pab0, pab1, pab2; 156 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE; 157 int8_t bg; 158 int error; 159 160 /* Fetch SPROM configuration */ 161 #define BWN_PHY_G_READVAR(_dev, _type, _name, _result) \ 162 do { \ 163 error = bhnd_nvram_getvar_ ##_type((_dev), (_name), (_result)); \ 164 if (error) { \ 165 device_printf((_dev), "NVRAM variable %s unreadable: " \ 166 "%d\n", (_name), error); \ 167 return (error); \ 168 } \ 169 } while(0) 170 171 BWN_PHY_G_READVAR(sc->sc_dev, int8, BHND_NVAR_PA0ITSSIT, &bg); 172 BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B0, &pab0); 173 BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B1, &pab1); 174 BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B2, &pab2); 175 BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0MAXPWR, 176 &pg->pg_pa0maxpwr); 177 178 #undef BWN_PHY_G_READVAR 179 180 pg->pg_flags = 0; 181 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 || 182 pab2 == -1) { 183 pg->pg_idletssi = 52; 184 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table; 185 return (0); 186 } 187 188 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg; 189 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO); 190 if (pg->pg_tssi2dbm == NULL) { 191 device_printf(sc->sc_dev, "failed to allocate buffer\n"); 192 return (ENOMEM); 193 } 194 for (i = 0; i < 64; i++) { 195 int32_t m1, m2, f, q, delta; 196 int8_t j = 0; 197 198 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32); 199 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1); 200 f = 256; 201 202 do { 203 if (j > 15) { 204 device_printf(sc->sc_dev, 205 "failed to generate tssi2dBm\n"); 206 free(pg->pg_tssi2dbm, M_DEVBUF); 207 return (ENOMEM); 208 } 209 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) * 210 f, 2048); 211 delta = abs(q - f); 212 f = q; 213 j++; 214 } while (delta >= 2); 215 216 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127), 217 127); 218 } 219 220 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC; 221 return (0); 222 } 223 224 void 225 bwn_phy_g_detach(struct bwn_mac *mac) 226 { 227 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 228 229 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) { 230 free(pg->pg_tssi2dbm, M_DEVBUF); 231 pg->pg_tssi2dbm = NULL; 232 } 233 pg->pg_flags = 0; 234 } 235 236 void 237 bwn_phy_g_init_pre(struct bwn_mac *mac) 238 { 239 struct bwn_phy *phy = &mac->mac_phy; 240 struct bwn_phy_g *pg = &phy->phy_g; 241 void *tssi2dbm; 242 int idletssi; 243 unsigned int i; 244 245 tssi2dbm = pg->pg_tssi2dbm; 246 idletssi = pg->pg_idletssi; 247 248 memset(pg, 0, sizeof(*pg)); 249 250 pg->pg_tssi2dbm = tssi2dbm; 251 pg->pg_idletssi = idletssi; 252 253 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig)); 254 255 for (i = 0; i < N(pg->pg_nrssi); i++) 256 pg->pg_nrssi[i] = -1000; 257 for (i = 0; i < N(pg->pg_nrssi_lt); i++) 258 pg->pg_nrssi_lt[i] = i; 259 pg->pg_lofcal = 0xffff; 260 pg->pg_initval = 0xffff; 261 pg->pg_immode = BWN_IMMODE_NONE; 262 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN; 263 pg->pg_avgtssi = 0xff; 264 265 pg->pg_loctl.tx_bias = 0xff; 266 TAILQ_INIT(&pg->pg_loctl.calib_list); 267 } 268 269 int 270 bwn_phy_g_prepare_hw(struct bwn_mac *mac) 271 { 272 struct bwn_phy *phy = &mac->mac_phy; 273 struct bwn_phy_g *pg = &phy->phy_g; 274 struct bwn_softc *sc = mac->mac_sc; 275 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 276 static const struct bwn_rfatt rfatt0[] = { 277 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 }, 278 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 }, 279 { 3, 1 }, { 4, 1 } 280 }; 281 static const struct bwn_rfatt rfatt1[] = { 282 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 }, 283 { 14, 1 } 284 }; 285 static const struct bwn_rfatt rfatt2[] = { 286 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 }, 287 { 9, 1 } 288 }; 289 static const struct bwn_bbatt bbatt_0[] = { 290 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 } 291 }; 292 293 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 294 295 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6) 296 pg->pg_bbatt.att = 0; 297 else 298 pg->pg_bbatt.att = 2; 299 300 /* prepare Radio Attenuation */ 301 pg->pg_rfatt.padmix = 0; 302 303 if (sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM && 304 sc->sc_board_info.board_type == BHND_BOARD_BCM94309G) { 305 if (sc->sc_board_info.board_rev < 0x43) { 306 pg->pg_rfatt.att = 2; 307 goto done; 308 } else if (sc->sc_board_info.board_rev < 0x51) { 309 pg->pg_rfatt.att = 3; 310 goto done; 311 } 312 } 313 314 if (phy->type == BWN_PHYTYPE_A) { 315 pg->pg_rfatt.att = 0x60; 316 goto done; 317 } 318 319 switch (phy->rf_ver) { 320 case 0x2050: 321 switch (phy->rf_rev) { 322 case 0: 323 pg->pg_rfatt.att = 5; 324 goto done; 325 case 1: 326 if (phy->type == BWN_PHYTYPE_G) { 327 if (sc->sc_board_info.board_vendor == 328 PCI_VENDOR_BROADCOM && 329 sc->sc_board_info.board_type == 330 BHND_BOARD_BCM94309G && 331 sc->sc_board_info.board_rev >= 30) 332 pg->pg_rfatt.att = 3; 333 else if (sc->sc_board_info.board_vendor == 334 PCI_VENDOR_BROADCOM && 335 sc->sc_board_info.board_type == 336 BHND_BOARD_BU4306) 337 pg->pg_rfatt.att = 3; 338 else 339 pg->pg_rfatt.att = 1; 340 } else { 341 if (sc->sc_board_info.board_vendor == 342 PCI_VENDOR_BROADCOM && 343 sc->sc_board_info.board_type == 344 BHND_BOARD_BCM94309G && 345 sc->sc_board_info.board_rev >= 30) 346 pg->pg_rfatt.att = 7; 347 else 348 pg->pg_rfatt.att = 6; 349 } 350 goto done; 351 case 2: 352 if (phy->type == BWN_PHYTYPE_G) { 353 if (sc->sc_board_info.board_vendor == 354 PCI_VENDOR_BROADCOM && 355 sc->sc_board_info.board_type == 356 BHND_BOARD_BCM94309G && 357 sc->sc_board_info.board_rev >= 30) 358 pg->pg_rfatt.att = 3; 359 else if (sc->sc_board_info.board_vendor == 360 PCI_VENDOR_BROADCOM && 361 sc->sc_board_info.board_type == 362 BHND_BOARD_BU4306) 363 pg->pg_rfatt.att = 5; 364 else if (sc->sc_cid.chip_id == 365 BHND_CHIPID_BCM4320) 366 pg->pg_rfatt.att = 4; 367 else 368 pg->pg_rfatt.att = 3; 369 } else 370 pg->pg_rfatt.att = 6; 371 goto done; 372 case 3: 373 pg->pg_rfatt.att = 5; 374 goto done; 375 case 4: 376 case 5: 377 pg->pg_rfatt.att = 1; 378 goto done; 379 case 6: 380 case 7: 381 pg->pg_rfatt.att = 5; 382 goto done; 383 case 8: 384 pg->pg_rfatt.att = 0xa; 385 pg->pg_rfatt.padmix = 1; 386 goto done; 387 case 9: 388 default: 389 pg->pg_rfatt.att = 5; 390 goto done; 391 } 392 break; 393 case 0x2053: 394 switch (phy->rf_rev) { 395 case 1: 396 pg->pg_rfatt.att = 6; 397 goto done; 398 } 399 break; 400 } 401 pg->pg_rfatt.att = 5; 402 done: 403 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4); 404 405 if (!bwn_has_hwpctl(mac)) { 406 lo->rfatt.array = rfatt0; 407 lo->rfatt.len = N(rfatt0); 408 lo->rfatt.min = 0; 409 lo->rfatt.max = 9; 410 goto genbbatt; 411 } 412 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 413 lo->rfatt.array = rfatt1; 414 lo->rfatt.len = N(rfatt1); 415 lo->rfatt.min = 0; 416 lo->rfatt.max = 14; 417 goto genbbatt; 418 } 419 lo->rfatt.array = rfatt2; 420 lo->rfatt.len = N(rfatt2); 421 lo->rfatt.min = 0; 422 lo->rfatt.max = 9; 423 genbbatt: 424 lo->bbatt.array = bbatt_0; 425 lo->bbatt.len = N(bbatt_0); 426 lo->bbatt.min = 0; 427 lo->bbatt.max = 8; 428 429 BWN_READ_4(mac, BWN_MACCTL); 430 if (phy->rev == 1) { 431 phy->gmode = 0; 432 bwn_reset_core(mac, 0); 433 bwn_phy_g_init_sub(mac); 434 phy->gmode = 1; 435 bwn_reset_core(mac, 1); 436 } 437 return (0); 438 } 439 440 static uint16_t 441 bwn_phy_g_txctl(struct bwn_mac *mac) 442 { 443 struct bwn_phy *phy = &mac->mac_phy; 444 445 if (phy->rf_ver != 0x2050) 446 return (0); 447 if (phy->rf_rev == 1) 448 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX); 449 if (phy->rf_rev < 6) 450 return (BWN_TXCTL_PA2DB); 451 if (phy->rf_rev == 8) 452 return (BWN_TXCTL_TXMIX); 453 return (0); 454 } 455 456 int 457 bwn_phy_g_init(struct bwn_mac *mac) 458 { 459 460 bwn_phy_g_init_sub(mac); 461 return (0); 462 } 463 464 void 465 bwn_phy_g_exit(struct bwn_mac *mac) 466 { 467 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 468 struct bwn_lo_calib *cal, *tmp; 469 470 if (lo == NULL) 471 return; 472 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 473 TAILQ_REMOVE(&lo->calib_list, cal, list); 474 free(cal, M_DEVBUF); 475 } 476 } 477 478 uint16_t 479 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg) 480 { 481 482 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 483 return (BWN_READ_2(mac, BWN_PHYDATA)); 484 } 485 486 void 487 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 488 { 489 490 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 491 BWN_WRITE_2(mac, BWN_PHYDATA, value); 492 } 493 494 uint16_t 495 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg) 496 { 497 498 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 499 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80); 500 return (BWN_READ_2(mac, BWN_RFDATALO)); 501 } 502 503 void 504 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 505 { 506 507 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__)); 508 BWN_WRITE_2(mac, BWN_RFCTL, reg); 509 BWN_WRITE_2(mac, BWN_RFDATALO, value); 510 } 511 512 int 513 bwn_phy_g_hwpctl(struct bwn_mac *mac) 514 { 515 516 return (mac->mac_phy.rev >= 6); 517 } 518 519 void 520 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on) 521 { 522 struct bwn_phy *phy = &mac->mac_phy; 523 struct bwn_phy_g *pg = &phy->phy_g; 524 unsigned int channel; 525 uint16_t rfover, rfoverval; 526 527 if (on) { 528 if (phy->rf_on) 529 return; 530 531 BWN_PHY_WRITE(mac, 0x15, 0x8000); 532 BWN_PHY_WRITE(mac, 0x15, 0xcc00); 533 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0)); 534 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) { 535 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 536 pg->pg_radioctx_over); 537 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 538 pg->pg_radioctx_overval); 539 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID; 540 } 541 channel = phy->chan; 542 bwn_phy_g_switch_chan(mac, 6, 1); 543 bwn_phy_g_switch_chan(mac, channel, 0); 544 return; 545 } 546 547 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 548 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 549 pg->pg_radioctx_over = rfover; 550 pg->pg_radioctx_overval = rfoverval; 551 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID; 552 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c); 553 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73); 554 } 555 556 int 557 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan) 558 { 559 560 if ((newchan < 1) || (newchan > 14)) 561 return (EINVAL); 562 bwn_phy_g_switch_chan(mac, newchan, 0); 563 564 return (0); 565 } 566 567 uint32_t 568 bwn_phy_g_get_default_chan(struct bwn_mac *mac) 569 { 570 571 return (1); 572 } 573 574 void 575 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna) 576 { 577 struct bwn_phy *phy = &mac->mac_phy; 578 uint64_t hf; 579 int autodiv = 0; 580 uint16_t tmp; 581 582 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1) 583 autodiv = 1; 584 585 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER; 586 bwn_hf_write(mac, hf); 587 588 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG, 589 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) | 590 ((autodiv ? BWN_ANTAUTO1 : antenna) 591 << BWN_PHY_BBANDCFG_RXANT_SHIFT)); 592 593 if (autodiv) { 594 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL); 595 if (antenna == BWN_ANTAUTO1) 596 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1; 597 else 598 tmp |= BWN_PHY_ANTDWELL_AUTODIV1; 599 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp); 600 } 601 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT); 602 if (autodiv) 603 tmp |= BWN_PHY_ANTWRSETT_ARXDIV; 604 else 605 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV; 606 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp); 607 if (phy->rev >= 2) { 608 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61, 609 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10); 610 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK, 611 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) | 612 0x15); 613 if (phy->rev == 2) 614 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8); 615 else 616 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 617 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) | 618 8); 619 } 620 if (phy->rev >= 6) 621 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc); 622 623 hf |= BWN_HF_UCODE_ANTDIV_HELPER; 624 bwn_hf_write(mac, hf); 625 } 626 627 int 628 bwn_phy_g_im(struct bwn_mac *mac, int mode) 629 { 630 struct bwn_phy *phy = &mac->mac_phy; 631 struct bwn_phy_g *pg = &phy->phy_g; 632 633 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 634 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__)); 635 636 if (phy->rev == 0 || !phy->gmode) 637 return (ENODEV); 638 639 pg->pg_aci_wlan_automatic = 0; 640 return (0); 641 } 642 643 bwn_txpwr_result_t 644 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi) 645 { 646 struct bwn_phy *phy = &mac->mac_phy; 647 struct bwn_phy_g *pg = &phy->phy_g; 648 struct bwn_softc *sc = mac->mac_sc; 649 unsigned int tssi; 650 int cck, ofdm; 651 int power; 652 int rfatt, bbatt; 653 unsigned int max; 654 655 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 656 657 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK); 658 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G); 659 if (cck < 0 && ofdm < 0) { 660 if (ignore_tssi == 0) 661 return (BWN_TXPWR_RES_DONE); 662 cck = 0; 663 ofdm = 0; 664 } 665 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2); 666 if (pg->pg_avgtssi != 0xff) 667 tssi = (tssi + pg->pg_avgtssi) / 2; 668 pg->pg_avgtssi = tssi; 669 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__)); 670 671 max = pg->pg_pa0maxpwr; 672 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) 673 max -= 3; 674 if (max >= 120) { 675 device_printf(sc->sc_dev, "invalid max TX-power value\n"); 676 max = 80; 677 pg->pg_pa0maxpwr = max; 678 } 679 680 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) - 681 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi + 682 tssi, 0x00), 0x3f)]); 683 if (power == 0) 684 return (BWN_TXPWR_RES_DONE); 685 686 rfatt = -((power + 7) / 8); 687 bbatt = (-(power / 2)) - (4 * rfatt); 688 if ((rfatt == 0) && (bbatt == 0)) 689 return (BWN_TXPWR_RES_DONE); 690 pg->pg_bbatt_delta = bbatt; 691 pg->pg_rfatt_delta = rfatt; 692 return (BWN_TXPWR_RES_NEED_ADJUST); 693 } 694 695 void 696 bwn_phy_g_set_txpwr(struct bwn_mac *mac) 697 { 698 struct bwn_phy *phy = &mac->mac_phy; 699 struct bwn_phy_g *pg = &phy->phy_g; 700 struct bwn_softc *sc = mac->mac_sc; 701 int rfatt, bbatt; 702 uint8_t txctl; 703 704 bwn_mac_suspend(mac); 705 706 BWN_ASSERT_LOCKED(sc); 707 708 bbatt = pg->pg_bbatt.att; 709 bbatt += pg->pg_bbatt_delta; 710 rfatt = pg->pg_rfatt.att; 711 rfatt += pg->pg_rfatt_delta; 712 713 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 714 txctl = pg->pg_txctl; 715 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) { 716 if (rfatt <= 1) { 717 if (txctl == 0) { 718 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX; 719 rfatt += 2; 720 bbatt += 2; 721 } else if (sc->sc_board_info.board_flags & 722 BHND_BFL_PACTRL) { 723 bbatt += 4 * (rfatt - 2); 724 rfatt = 2; 725 } 726 } else if (rfatt > 4 && txctl) { 727 txctl = 0; 728 if (bbatt < 3) { 729 rfatt -= 3; 730 bbatt += 2; 731 } else { 732 rfatt -= 2; 733 bbatt -= 2; 734 } 735 } 736 } 737 pg->pg_txctl = txctl; 738 bwn_phy_g_setatt(mac, &bbatt, &rfatt); 739 pg->pg_rfatt.att = rfatt; 740 pg->pg_bbatt.att = bbatt; 741 742 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__); 743 744 bwn_phy_lock(mac); 745 bwn_rf_lock(mac); 746 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 747 pg->pg_txctl); 748 bwn_rf_unlock(mac); 749 bwn_phy_unlock(mac); 750 751 bwn_mac_enable(mac); 752 } 753 754 void 755 bwn_phy_g_task_15s(struct bwn_mac *mac) 756 { 757 struct bwn_phy *phy = &mac->mac_phy; 758 struct bwn_phy_g *pg = &phy->phy_g; 759 struct bwn_softc *sc = mac->mac_sc; 760 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 761 unsigned long expire, now; 762 struct bwn_lo_calib *cal, *tmp; 763 uint8_t expired = 0; 764 765 bwn_mac_suspend(mac); 766 767 if (lo == NULL) 768 goto fail; 769 770 BWN_GETTIME(now); 771 if (bwn_has_hwpctl(mac)) { 772 expire = now - BWN_LO_PWRVEC_EXPIRE; 773 if (ieee80211_time_before(lo->pwr_vec_read_time, expire)) { 774 bwn_lo_get_powervector(mac); 775 bwn_phy_g_dc_lookup_init(mac, 0); 776 } 777 goto fail; 778 } 779 780 expire = now - BWN_LO_CALIB_EXPIRE; 781 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) { 782 if (!ieee80211_time_before(cal->calib_time, expire)) 783 continue; 784 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) && 785 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) { 786 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__)); 787 expired = 1; 788 } 789 790 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n", 791 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix, 792 cal->ctl.i, cal->ctl.q); 793 794 TAILQ_REMOVE(&lo->calib_list, cal, list); 795 free(cal, M_DEVBUF); 796 } 797 if (expired || TAILQ_EMPTY(&lo->calib_list)) { 798 cal = bwn_lo_calibset(mac, &pg->pg_bbatt, 799 &pg->pg_rfatt); 800 if (cal == NULL) { 801 device_printf(sc->sc_dev, 802 "failed to recalibrate LO\n"); 803 goto fail; 804 } 805 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list); 806 bwn_lo_write(mac, &cal->ctl); 807 } 808 809 fail: 810 bwn_mac_enable(mac); 811 } 812 813 void 814 bwn_phy_g_task_60s(struct bwn_mac *mac) 815 { 816 struct bwn_phy *phy = &mac->mac_phy; 817 struct bwn_softc *sc = mac->mac_sc; 818 uint8_t old = phy->chan; 819 820 if (!(sc->sc_board_info.board_flags & BHND_BFL_ADCDIV)) 821 return; 822 823 bwn_mac_suspend(mac); 824 bwn_nrssi_slope_11g(mac); 825 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) { 826 bwn_switch_channel(mac, (old >= 8) ? 1 : 13); 827 bwn_switch_channel(mac, old); 828 } 829 bwn_mac_enable(mac); 830 } 831 832 void 833 bwn_phy_switch_analog(struct bwn_mac *mac, int on) 834 { 835 836 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4); 837 } 838 839 static void 840 bwn_phy_g_init_sub(struct bwn_mac *mac) 841 { 842 struct bwn_phy *phy = &mac->mac_phy; 843 struct bwn_phy_g *pg = &phy->phy_g; 844 struct bwn_softc *sc = mac->mac_sc; 845 uint16_t i, tmp; 846 847 if (phy->rev == 1) 848 bwn_phy_init_b5(mac); 849 else 850 bwn_phy_init_b6(mac); 851 852 if (phy->rev >= 2 || phy->gmode) 853 bwn_phy_init_a(mac); 854 855 if (phy->rev >= 2) { 856 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0); 857 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0); 858 } 859 if (phy->rev == 2) { 860 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 861 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 862 } 863 if (phy->rev > 5) { 864 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400); 865 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0); 866 } 867 if (phy->gmode || phy->rev >= 2) { 868 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 869 tmp &= BWN_PHYVER_VERSION; 870 if (tmp == 3 || tmp == 5) { 871 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816); 872 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006); 873 } 874 if (tmp == 5) { 875 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff, 876 0x1f00); 877 } 878 } 879 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) 880 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78); 881 if (phy->rf_rev == 8) { 882 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80); 883 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4); 884 } 885 if (BWN_HAS_LOOPBACK(phy)) 886 bwn_loopback_calcgain(mac); 887 888 if (phy->rf_rev != 8) { 889 if (pg->pg_initval == 0xffff) 890 pg->pg_initval = bwn_rf_init_bcm2050(mac); 891 else 892 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval); 893 } 894 bwn_lo_g_init(mac); 895 if (BWN_HAS_TXMAG(phy)) { 896 BWN_RF_WRITE(mac, 0x52, 897 (BWN_RF_READ(mac, 0x52) & 0xff00) 898 | pg->pg_loctl.tx_bias | 899 pg->pg_loctl.tx_magn); 900 } else { 901 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias); 902 } 903 if (phy->rev >= 6) { 904 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff, 905 (pg->pg_loctl.tx_bias << 12)); 906 } 907 if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) 908 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075); 909 else 910 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f); 911 if (phy->rev < 2) 912 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101); 913 else 914 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202); 915 if (phy->gmode || phy->rev >= 2) { 916 bwn_lo_g_adjust(mac); 917 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 918 } 919 920 if (!(sc->sc_board_info.board_flags & BHND_BFL_ADCDIV)) { 921 for (i = 0; i < 64; i++) { 922 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i); 923 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA, 924 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff, 925 -32), 31)); 926 } 927 bwn_nrssi_threshold(mac); 928 } else if (phy->gmode || phy->rev >= 2) { 929 if (pg->pg_nrssi[0] == -1000) { 930 KASSERT(pg->pg_nrssi[1] == -1000, 931 ("%s:%d: fail", __func__, __LINE__)); 932 bwn_nrssi_slope_11g(mac); 933 } else 934 bwn_nrssi_threshold(mac); 935 } 936 if (phy->rf_rev == 8) 937 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230); 938 bwn_phy_hwpctl_init(mac); 939 if ((sc->sc_cid.chip_id == BHND_CHIPID_BCM4306 940 && sc->sc_cid.chip_pkg == 2) || 0) { 941 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff); 942 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff); 943 } 944 } 945 946 static void 947 bwn_phy_init_b5(struct bwn_mac *mac) 948 { 949 struct bwn_phy *phy = &mac->mac_phy; 950 struct bwn_phy_g *pg = &phy->phy_g; 951 struct bwn_softc *sc = mac->mac_sc; 952 uint16_t offset, value; 953 uint8_t old_channel; 954 955 if (phy->analog == 1) 956 BWN_RF_SET(mac, 0x007a, 0x0050); 957 if ((sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM) && 958 (sc->sc_board_info.board_type != BHND_BOARD_BU4306)) { 959 value = 0x2120; 960 for (offset = 0x00a8; offset < 0x00c7; offset++) { 961 BWN_PHY_WRITE(mac, offset, value); 962 value += 0x202; 963 } 964 } 965 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700); 966 if (phy->rf_ver == 0x2050) 967 BWN_PHY_WRITE(mac, 0x0038, 0x0667); 968 969 if (phy->gmode || phy->rev >= 2) { 970 if (phy->rf_ver == 0x2050) { 971 BWN_RF_SET(mac, 0x007a, 0x0020); 972 BWN_RF_SET(mac, 0x0051, 0x0004); 973 } 974 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000); 975 976 BWN_PHY_SET(mac, 0x0802, 0x0100); 977 BWN_PHY_SET(mac, 0x042b, 0x2000); 978 979 BWN_PHY_WRITE(mac, 0x001c, 0x186a); 980 981 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900); 982 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064); 983 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a); 984 } 985 986 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP) 987 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11)); 988 989 if (phy->analog == 1) { 990 BWN_PHY_WRITE(mac, 0x0026, 0xce00); 991 BWN_PHY_WRITE(mac, 0x0021, 0x3763); 992 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3); 993 BWN_PHY_WRITE(mac, 0x0023, 0x06f9); 994 BWN_PHY_WRITE(mac, 0x0024, 0x037e); 995 } else 996 BWN_PHY_WRITE(mac, 0x0026, 0xcc00); 997 BWN_PHY_WRITE(mac, 0x0030, 0x00c6); 998 BWN_WRITE_2(mac, 0x03ec, 0x3f22); 999 1000 if (phy->analog == 1) 1001 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c); 1002 else 1003 BWN_PHY_WRITE(mac, 0x0020, 0x301c); 1004 1005 if (phy->analog == 0) 1006 BWN_WRITE_2(mac, 0x03e4, 0x3000); 1007 1008 old_channel = phy->chan; 1009 bwn_phy_g_switch_chan(mac, 7, 0); 1010 1011 if (phy->rf_ver != 0x2050) { 1012 BWN_RF_WRITE(mac, 0x0075, 0x0080); 1013 BWN_RF_WRITE(mac, 0x0079, 0x0081); 1014 } 1015 1016 BWN_RF_WRITE(mac, 0x0050, 0x0020); 1017 BWN_RF_WRITE(mac, 0x0050, 0x0023); 1018 1019 if (phy->rf_ver == 0x2050) { 1020 BWN_RF_WRITE(mac, 0x0050, 0x0020); 1021 BWN_RF_WRITE(mac, 0x005a, 0x0070); 1022 } 1023 1024 BWN_RF_WRITE(mac, 0x005b, 0x007b); 1025 BWN_RF_WRITE(mac, 0x005c, 0x00b0); 1026 BWN_RF_SET(mac, 0x007a, 0x0007); 1027 1028 bwn_phy_g_switch_chan(mac, old_channel, 0); 1029 BWN_PHY_WRITE(mac, 0x0014, 0x0080); 1030 BWN_PHY_WRITE(mac, 0x0032, 0x00ca); 1031 BWN_PHY_WRITE(mac, 0x002a, 0x88a3); 1032 1033 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 1034 pg->pg_txctl); 1035 1036 if (phy->rf_ver == 0x2050) 1037 BWN_RF_WRITE(mac, 0x005d, 0x000d); 1038 1039 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004); 1040 } 1041 1042 static void 1043 bwn_loopback_calcgain(struct bwn_mac *mac) 1044 { 1045 struct bwn_phy *phy = &mac->mac_phy; 1046 struct bwn_phy_g *pg = &phy->phy_g; 1047 struct bwn_softc *sc = mac->mac_sc; 1048 uint16_t backup_phy[16] = { 0 }; 1049 uint16_t backup_radio[3]; 1050 uint16_t backup_bband; 1051 uint16_t i, j, loop_i_max; 1052 uint16_t trsw_rx; 1053 uint16_t loop1_outer_done, loop1_inner_done; 1054 1055 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0); 1056 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG); 1057 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 1058 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 1059 if (phy->rev != 1) { 1060 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 1061 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 1062 } 1063 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 1064 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 1065 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 1066 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a)); 1067 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03)); 1068 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 1069 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 1070 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b)); 1071 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 1072 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 1073 backup_bband = pg->pg_bbatt.att; 1074 backup_radio[0] = BWN_RF_READ(mac, 0x52); 1075 backup_radio[1] = BWN_RF_READ(mac, 0x43); 1076 backup_radio[2] = BWN_RF_READ(mac, 0x7a); 1077 1078 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff); 1079 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000); 1080 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002); 1081 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd); 1082 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001); 1083 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe); 1084 if (phy->rev != 1) { 1085 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001); 1086 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe); 1087 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002); 1088 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd); 1089 } 1090 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c); 1091 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c); 1092 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030); 1093 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10); 1094 1095 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780); 1096 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 1097 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 1098 1099 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000); 1100 if (phy->rev != 1) { 1101 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004); 1102 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb); 1103 } 1104 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40); 1105 1106 if (phy->rf_rev == 8) 1107 BWN_RF_WRITE(mac, 0x43, 0x000f); 1108 else { 1109 BWN_RF_WRITE(mac, 0x52, 0); 1110 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9); 1111 } 1112 bwn_phy_g_set_bbatt(mac, 11); 1113 1114 if (phy->rev >= 3) 1115 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 1116 else 1117 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 1118 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 1119 1120 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01); 1121 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800); 1122 1123 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100); 1124 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff); 1125 1126 if (sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) { 1127 if (phy->rev >= 7) { 1128 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800); 1129 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000); 1130 } 1131 } 1132 BWN_RF_MASK(mac, 0x7a, 0x00f7); 1133 1134 j = 0; 1135 loop_i_max = (phy->rf_rev == 8) ? 15 : 9; 1136 for (i = 0; i < loop_i_max; i++) { 1137 for (j = 0; j < 16; j++) { 1138 BWN_RF_WRITE(mac, 0x43, i); 1139 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, 1140 (j << 8)); 1141 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 1142 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 1143 DELAY(20); 1144 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 1145 goto done0; 1146 } 1147 } 1148 done0: 1149 loop1_outer_done = i; 1150 loop1_inner_done = j; 1151 if (j >= 8) { 1152 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30); 1153 trsw_rx = 0x1b; 1154 for (j = j - 8; j < 16; j++) { 1155 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8); 1156 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000); 1157 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000); 1158 DELAY(20); 1159 trsw_rx -= 3; 1160 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc) 1161 goto done1; 1162 } 1163 } else 1164 trsw_rx = 0x18; 1165 done1: 1166 1167 if (phy->rev != 1) { 1168 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]); 1169 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]); 1170 } 1171 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]); 1172 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]); 1173 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]); 1174 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]); 1175 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]); 1176 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]); 1177 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]); 1178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]); 1179 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]); 1180 1181 bwn_phy_g_set_bbatt(mac, backup_bband); 1182 1183 BWN_RF_WRITE(mac, 0x52, backup_radio[0]); 1184 BWN_RF_WRITE(mac, 0x43, backup_radio[1]); 1185 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]); 1186 1187 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003); 1188 DELAY(10); 1189 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]); 1190 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]); 1191 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]); 1192 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]); 1193 1194 pg->pg_max_lb_gain = 1195 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; 1196 pg->pg_trsw_rx_gain = trsw_rx * 2; 1197 } 1198 1199 static uint16_t 1200 bwn_rf_init_bcm2050(struct bwn_mac *mac) 1201 { 1202 struct bwn_phy *phy = &mac->mac_phy; 1203 uint32_t tmp1 = 0, tmp2 = 0; 1204 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval, 1205 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl, 1206 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index; 1207 static const uint8_t rcc_table[] = { 1208 0x02, 0x03, 0x01, 0x0f, 1209 0x06, 0x07, 0x05, 0x0f, 1210 0x0a, 0x0b, 0x09, 0x0f, 1211 0x0e, 0x0f, 0x0d, 0x0f, 1212 }; 1213 1214 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover = 1215 rfoverval = rfover = cck3 = 0; 1216 radio0 = BWN_RF_READ(mac, 0x43); 1217 radio1 = BWN_RF_READ(mac, 0x51); 1218 radio2 = BWN_RF_READ(mac, 0x52); 1219 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 1220 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a)); 1221 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59)); 1222 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58)); 1223 1224 if (phy->type == BWN_PHYTYPE_B) { 1225 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 1226 reg0 = BWN_READ_2(mac, 0x3ec); 1227 1228 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff); 1229 BWN_WRITE_2(mac, 0x3ec, 0x3f3f); 1230 } else if (phy->gmode || phy->rev >= 2) { 1231 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 1232 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 1233 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 1234 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 1235 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 1236 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 1237 1238 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 1239 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 1240 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 1241 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 1242 if (BWN_HAS_LOOPBACK(phy)) { 1243 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 1244 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL); 1245 if (phy->rev >= 3) 1246 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020); 1247 else 1248 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020); 1249 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0); 1250 } 1251 1252 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1253 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 1254 BWN_LPD(0, 1, 1))); 1255 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 1256 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0)); 1257 } 1258 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000); 1259 1260 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 1261 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f); 1262 reg1 = BWN_READ_2(mac, 0x3e6); 1263 reg2 = BWN_READ_2(mac, 0x3f4); 1264 1265 if (phy->analog == 0) 1266 BWN_WRITE_2(mac, 0x03e6, 0x0122); 1267 else { 1268 if (phy->analog >= 2) 1269 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40); 1270 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 1271 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000)); 1272 } 1273 1274 reg = BWN_RF_READ(mac, 0x60); 1275 index = (reg & 0x001e) >> 1; 1276 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020); 1277 1278 if (phy->type == BWN_PHYTYPE_B) 1279 BWN_RF_WRITE(mac, 0x78, 0x26); 1280 if (phy->gmode || phy->rev >= 2) { 1281 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1282 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 1283 BWN_LPD(0, 1, 1))); 1284 } 1285 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf); 1286 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403); 1287 if (phy->gmode || phy->rev >= 2) { 1288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1289 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL, 1290 BWN_LPD(0, 0, 1))); 1291 } 1292 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0); 1293 BWN_RF_SET(mac, 0x51, 0x0004); 1294 if (phy->rf_rev == 8) 1295 BWN_RF_WRITE(mac, 0x43, 0x1f); 1296 else { 1297 BWN_RF_WRITE(mac, 0x52, 0); 1298 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009); 1299 } 1300 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 1301 1302 for (i = 0; i < 16; i++) { 1303 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480); 1304 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 1305 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 1306 if (phy->gmode || phy->rev >= 2) { 1307 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1308 bwn_rf_2050_rfoverval(mac, 1309 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1310 } 1311 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 1312 DELAY(10); 1313 if (phy->gmode || phy->rev >= 2) { 1314 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1315 bwn_rf_2050_rfoverval(mac, 1316 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1317 } 1318 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 1319 DELAY(10); 1320 if (phy->gmode || phy->rev >= 2) { 1321 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1322 bwn_rf_2050_rfoverval(mac, 1323 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 1324 } 1325 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 1326 DELAY(20); 1327 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 1328 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 1329 if (phy->gmode || phy->rev >= 2) { 1330 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1331 bwn_rf_2050_rfoverval(mac, 1332 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1333 } 1334 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 1335 } 1336 DELAY(10); 1337 1338 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 1339 tmp1++; 1340 tmp1 >>= 9; 1341 1342 for (i = 0; i < 16; i++) { 1343 radio78 = (BWN_BITREV4(i) << 1) | 0x0020; 1344 BWN_RF_WRITE(mac, 0x78, radio78); 1345 DELAY(10); 1346 for (j = 0; j < 16; j++) { 1347 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80); 1348 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810); 1349 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d); 1350 if (phy->gmode || phy->rev >= 2) { 1351 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1352 bwn_rf_2050_rfoverval(mac, 1353 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1354 } 1355 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 1356 DELAY(10); 1357 if (phy->gmode || phy->rev >= 2) { 1358 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1359 bwn_rf_2050_rfoverval(mac, 1360 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1361 } 1362 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0); 1363 DELAY(10); 1364 if (phy->gmode || phy->rev >= 2) { 1365 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1366 bwn_rf_2050_rfoverval(mac, 1367 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0))); 1368 } 1369 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0); 1370 DELAY(10); 1371 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 1372 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0); 1373 if (phy->gmode || phy->rev >= 2) { 1374 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, 1375 bwn_rf_2050_rfoverval(mac, 1376 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1))); 1377 } 1378 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0); 1379 } 1380 tmp2++; 1381 tmp2 >>= 8; 1382 if (tmp1 < tmp2) 1383 break; 1384 } 1385 1386 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl); 1387 BWN_RF_WRITE(mac, 0x51, radio1); 1388 BWN_RF_WRITE(mac, 0x52, radio2); 1389 BWN_RF_WRITE(mac, 0x43, radio0); 1390 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0); 1391 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1); 1392 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2); 1393 BWN_WRITE_2(mac, 0x3e6, reg1); 1394 if (phy->analog != 0) 1395 BWN_WRITE_2(mac, 0x3f4, reg2); 1396 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl); 1397 bwn_spu_workaround(mac, phy->chan); 1398 if (phy->type == BWN_PHYTYPE_B) { 1399 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3); 1400 BWN_WRITE_2(mac, 0x3ec, reg0); 1401 } else if (phy->gmode) { 1402 BWN_WRITE_2(mac, BWN_PHY_RADIO, 1403 BWN_READ_2(mac, BWN_PHY_RADIO) 1404 & 0x7fff); 1405 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover); 1406 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval); 1407 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover); 1408 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 1409 analogoverval); 1410 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0); 1411 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl); 1412 if (BWN_HAS_LOOPBACK(phy)) { 1413 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask); 1414 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl); 1415 } 1416 } 1417 1418 return ((i > 15) ? radio78 : rcc); 1419 } 1420 1421 static void 1422 bwn_phy_init_b6(struct bwn_mac *mac) 1423 { 1424 struct bwn_phy *phy = &mac->mac_phy; 1425 struct bwn_phy_g *pg = &phy->phy_g; 1426 struct bwn_softc *sc = mac->mac_sc; 1427 uint16_t offset, val; 1428 uint8_t old_channel; 1429 1430 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7), 1431 ("%s:%d: fail", __func__, __LINE__)); 1432 1433 BWN_PHY_WRITE(mac, 0x003e, 0x817a); 1434 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058); 1435 if (phy->rf_rev == 4 || phy->rf_rev == 5) { 1436 BWN_RF_WRITE(mac, 0x51, 0x37); 1437 BWN_RF_WRITE(mac, 0x52, 0x70); 1438 BWN_RF_WRITE(mac, 0x53, 0xb3); 1439 BWN_RF_WRITE(mac, 0x54, 0x9b); 1440 BWN_RF_WRITE(mac, 0x5a, 0x88); 1441 BWN_RF_WRITE(mac, 0x5b, 0x88); 1442 BWN_RF_WRITE(mac, 0x5d, 0x88); 1443 BWN_RF_WRITE(mac, 0x5e, 0x88); 1444 BWN_RF_WRITE(mac, 0x7d, 0x88); 1445 bwn_hf_write(mac, 1446 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN); 1447 } 1448 if (phy->rf_rev == 8) { 1449 BWN_RF_WRITE(mac, 0x51, 0); 1450 BWN_RF_WRITE(mac, 0x52, 0x40); 1451 BWN_RF_WRITE(mac, 0x53, 0xb7); 1452 BWN_RF_WRITE(mac, 0x54, 0x98); 1453 BWN_RF_WRITE(mac, 0x5a, 0x88); 1454 BWN_RF_WRITE(mac, 0x5b, 0x6b); 1455 BWN_RF_WRITE(mac, 0x5c, 0x0f); 1456 if (sc->sc_board_info.board_flags & BHND_BFL_ALTIQ) { 1457 BWN_RF_WRITE(mac, 0x5d, 0xfa); 1458 BWN_RF_WRITE(mac, 0x5e, 0xd8); 1459 } else { 1460 BWN_RF_WRITE(mac, 0x5d, 0xf5); 1461 BWN_RF_WRITE(mac, 0x5e, 0xb8); 1462 } 1463 BWN_RF_WRITE(mac, 0x0073, 0x0003); 1464 BWN_RF_WRITE(mac, 0x007d, 0x00a8); 1465 BWN_RF_WRITE(mac, 0x007c, 0x0001); 1466 BWN_RF_WRITE(mac, 0x007e, 0x0008); 1467 } 1468 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) { 1469 BWN_PHY_WRITE(mac, offset, val); 1470 val -= 0x0202; 1471 } 1472 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) { 1473 BWN_PHY_WRITE(mac, offset, val); 1474 val -= 0x0202; 1475 } 1476 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) { 1477 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f)); 1478 val += 0x0202; 1479 } 1480 if (phy->type == BWN_PHYTYPE_G) { 1481 BWN_RF_SET(mac, 0x007a, 0x0020); 1482 BWN_RF_SET(mac, 0x0051, 0x0004); 1483 BWN_PHY_SET(mac, 0x0802, 0x0100); 1484 BWN_PHY_SET(mac, 0x042b, 0x2000); 1485 BWN_PHY_WRITE(mac, 0x5b, 0); 1486 BWN_PHY_WRITE(mac, 0x5c, 0); 1487 } 1488 1489 old_channel = phy->chan; 1490 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0); 1491 1492 BWN_RF_WRITE(mac, 0x0050, 0x0020); 1493 BWN_RF_WRITE(mac, 0x0050, 0x0023); 1494 DELAY(40); 1495 if (phy->rf_rev < 6 || phy->rf_rev == 8) { 1496 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002); 1497 BWN_RF_WRITE(mac, 0x50, 0x20); 1498 } 1499 if (phy->rf_rev <= 2) { 1500 BWN_RF_WRITE(mac, 0x7c, 0x20); 1501 BWN_RF_WRITE(mac, 0x5a, 0x70); 1502 BWN_RF_WRITE(mac, 0x5b, 0x7b); 1503 BWN_RF_WRITE(mac, 0x5c, 0xb0); 1504 } 1505 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007); 1506 1507 bwn_phy_g_switch_chan(mac, old_channel, 0); 1508 1509 BWN_PHY_WRITE(mac, 0x0014, 0x0200); 1510 if (phy->rf_rev >= 6) 1511 BWN_PHY_WRITE(mac, 0x2a, 0x88c2); 1512 else 1513 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0); 1514 BWN_PHY_WRITE(mac, 0x0038, 0x0668); 1515 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt, 1516 pg->pg_txctl); 1517 if (phy->rf_rev <= 5) 1518 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003); 1519 if (phy->rf_rev <= 2) 1520 BWN_RF_WRITE(mac, 0x005d, 0x000d); 1521 1522 if (phy->analog == 4) { 1523 BWN_WRITE_2(mac, 0x3e4, 9); 1524 BWN_PHY_MASK(mac, 0x61, 0x0fff); 1525 } else 1526 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004); 1527 if (phy->type == BWN_PHYTYPE_B) 1528 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1529 else if (phy->type == BWN_PHYTYPE_G) 1530 BWN_WRITE_2(mac, 0x03e6, 0x0); 1531 } 1532 1533 static void 1534 bwn_phy_init_a(struct bwn_mac *mac) 1535 { 1536 struct bwn_phy *phy = &mac->mac_phy; 1537 struct bwn_softc *sc = mac->mac_sc; 1538 1539 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G, 1540 ("%s:%d: fail", __func__, __LINE__)); 1541 1542 if (phy->rev >= 6) { 1543 if (phy->type == BWN_PHYTYPE_A) 1544 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000); 1545 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN) 1546 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010); 1547 else 1548 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010); 1549 } 1550 1551 bwn_wa_init(mac); 1552 1553 if (phy->type == BWN_PHYTYPE_G && 1554 (sc->sc_board_info.board_flags & BHND_BFL_PACTRL)) 1555 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf); 1556 } 1557 1558 static void 1559 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst) 1560 { 1561 int i; 1562 1563 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++) 1564 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]); 1565 } 1566 1567 static void 1568 bwn_wa_agc(struct bwn_mac *mac) 1569 { 1570 struct bwn_phy *phy = &mac->mac_phy; 1571 1572 if (phy->rev == 1) { 1573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254); 1574 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13); 1575 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19); 1576 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25); 1577 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710); 1578 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83); 1579 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83); 1580 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d); 1581 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4); 1582 } else { 1583 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254); 1584 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13); 1585 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19); 1586 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25); 1587 } 1588 1589 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00, 1590 0x5700); 1591 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f); 1592 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80); 1593 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300); 1594 BWN_RF_SET(mac, 0x7a, 0x0008); 1595 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008); 1596 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600); 1597 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700); 1598 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100); 1599 if (phy->rev == 1) 1600 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007); 1601 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c); 1602 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200); 1603 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c); 1604 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020); 1605 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200); 1606 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e); 1607 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00); 1608 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028); 1609 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00); 1610 if (phy->rev == 1) { 1611 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b); 1612 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002); 1613 } else { 1614 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e); 1615 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a); 1616 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004); 1617 if (phy->rev >= 6) { 1618 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a); 1619 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, 1620 (uint16_t)~0xf000, 0x3000); 1621 } 1622 } 1623 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874); 1624 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00); 1625 if (phy->rev == 1) { 1626 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600); 1627 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e); 1628 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e); 1629 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002); 1630 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0); 1631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7); 1632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16); 1633 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28); 1634 } else { 1635 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0); 1636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7); 1637 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16); 1638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28); 1639 } 1640 if (phy->rev >= 6) { 1641 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003); 1642 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000); 1643 } 1644 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM); 1645 } 1646 1647 static void 1648 bwn_wa_grev1(struct bwn_mac *mac) 1649 { 1650 struct bwn_phy *phy = &mac->mac_phy; 1651 int i; 1652 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G; 1653 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD; 1654 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR; 1655 1656 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 1657 1658 /* init CRSTHRES and ANTDWELL */ 1659 if (phy->rev == 1) { 1660 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 1661 } else if (phy->rev == 2) { 1662 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 1663 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 1664 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 1665 } else { 1666 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 1667 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 1668 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 1669 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 1670 } 1671 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000); 1672 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a); 1673 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026); 1674 1675 /* XXX support PHY-A??? */ 1676 for (i = 0; i < N(bwn_tab_finefreqg); i++) 1677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i, 1678 bwn_tab_finefreqg[i]); 1679 1680 /* XXX support PHY-A??? */ 1681 if (phy->rev == 1) 1682 for (i = 0; i < N(bwn_tab_noise_g1); i++) 1683 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 1684 bwn_tab_noise_g1[i]); 1685 else 1686 for (i = 0; i < N(bwn_tab_noise_g2); i++) 1687 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 1688 bwn_tab_noise_g2[i]); 1689 1690 for (i = 0; i < N(bwn_tab_rotor); i++) 1691 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i, 1692 bwn_tab_rotor[i]); 1693 1694 /* XXX support PHY-A??? */ 1695 if (phy->rev >= 6) { 1696 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 1697 BWN_PHY_ENCORE_EN) 1698 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 1699 else 1700 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 1701 } else 1702 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 1703 1704 for (i = 0; i < N(bwn_tab_retard); i++) 1705 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i, 1706 bwn_tab_retard[i]); 1707 1708 if (phy->rev == 1) { 1709 for (i = 0; i < 16; i++) 1710 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, 1711 i, 0x0020); 1712 } else { 1713 for (i = 0; i < 32; i++) 1714 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 1715 } 1716 1717 bwn_wa_agc(mac); 1718 } 1719 1720 static void 1721 bwn_wa_grev26789(struct bwn_mac *mac) 1722 { 1723 struct bwn_phy *phy = &mac->mac_phy; 1724 int i; 1725 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2; 1726 uint16_t ofdmrev; 1727 1728 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 1729 1730 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480); 1731 1732 /* init CRSTHRES and ANTDWELL */ 1733 if (phy->rev == 1) 1734 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19); 1735 else if (phy->rev == 2) { 1736 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861); 1737 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271); 1738 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 1739 } else { 1740 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098); 1741 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070); 1742 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080); 1743 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800); 1744 } 1745 1746 for (i = 0; i < 64; i++) 1747 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i); 1748 1749 /* XXX support PHY-A??? */ 1750 if (phy->rev == 1) 1751 for (i = 0; i < N(bwn_tab_noise_g1); i++) 1752 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 1753 bwn_tab_noise_g1[i]); 1754 else 1755 for (i = 0; i < N(bwn_tab_noise_g2); i++) 1756 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i, 1757 bwn_tab_noise_g2[i]); 1758 1759 /* XXX support PHY-A??? */ 1760 if (phy->rev >= 6) { 1761 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & 1762 BWN_PHY_ENCORE_EN) 1763 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3); 1764 else 1765 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2); 1766 } else 1767 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1); 1768 1769 for (i = 0; i < N(bwn_tab_sigmasqr2); i++) 1770 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i, 1771 bwn_tab_sigmasqr2[i]); 1772 1773 if (phy->rev == 1) { 1774 for (i = 0; i < 16; i++) 1775 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i, 1776 0x0020); 1777 } else { 1778 for (i = 0; i < 32; i++) 1779 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820); 1780 } 1781 1782 bwn_wa_agc(mac); 1783 1784 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION; 1785 if (ofdmrev > 2) { 1786 if (phy->type == BWN_PHYTYPE_A) 1787 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808); 1788 else 1789 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000); 1790 } else { 1791 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044); 1792 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201); 1793 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040); 1794 } 1795 1796 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15); 1797 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20); 1798 } 1799 1800 static void 1801 bwn_wa_init(struct bwn_mac *mac) 1802 { 1803 struct bwn_phy *phy = &mac->mac_phy; 1804 struct bwn_softc *sc = mac->mac_sc; 1805 1806 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__)); 1807 1808 switch (phy->rev) { 1809 case 1: 1810 bwn_wa_grev1(mac); 1811 break; 1812 case 2: 1813 case 6: 1814 case 7: 1815 case 8: 1816 case 9: 1817 bwn_wa_grev26789(mac); 1818 break; 1819 default: 1820 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1821 } 1822 1823 if (sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM || 1824 sc->sc_board_info.board_type != BHND_BOARD_BU4306 || 1825 sc->sc_board_info.board_rev != 0x17) { 1826 if (phy->rev < 2) { 1827 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1, 1828 0x0002); 1829 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2, 1830 0x0001); 1831 } else { 1832 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002); 1833 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001); 1834 if ((sc->sc_board_info.board_flags & 1835 BHND_BFL_EXTLNA) && 1836 (phy->rev >= 7)) { 1837 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff); 1838 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1839 0x0020, 0x0001); 1840 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1841 0x0021, 0x0001); 1842 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1843 0x0022, 0x0001); 1844 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1845 0x0023, 0x0000); 1846 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1847 0x0000, 0x0000); 1848 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1849 0x0003, 0x0002); 1850 } 1851 } 1852 } 1853 if (sc->sc_board_info.board_flags & BHND_BFL_FEM) { 1854 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120); 1855 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480); 1856 } 1857 1858 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0); 1859 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0); 1860 } 1861 1862 static void 1863 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset, 1864 uint16_t value) 1865 { 1866 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 1867 uint16_t addr; 1868 1869 addr = table + offset; 1870 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 1871 (addr - 1 != pg->pg_ofdmtab_addr)) { 1872 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 1873 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 1874 } 1875 pg->pg_ofdmtab_addr = addr; 1876 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 1877 } 1878 1879 static void 1880 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset, 1881 uint32_t value) 1882 { 1883 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 1884 uint16_t addr; 1885 1886 addr = table + offset; 1887 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) || 1888 (addr - 1 != pg->pg_ofdmtab_addr)) { 1889 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr); 1890 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE; 1891 } 1892 pg->pg_ofdmtab_addr = addr; 1893 1894 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value); 1895 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16)); 1896 } 1897 1898 static void 1899 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset, 1900 uint16_t value) 1901 { 1902 1903 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset); 1904 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value); 1905 } 1906 1907 static void 1908 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl) 1909 { 1910 uint16_t value; 1911 1912 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G, 1913 ("%s:%d: fail", __func__, __LINE__)); 1914 1915 value = (uint8_t) (ctl->q); 1916 value |= ((uint8_t) (ctl->i)) << 8; 1917 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value); 1918 } 1919 1920 static uint16_t 1921 bwn_lo_calcfeed(struct bwn_mac *mac, 1922 uint16_t lna, uint16_t pga, uint16_t trsw_rx) 1923 { 1924 struct bwn_phy *phy = &mac->mac_phy; 1925 struct bwn_softc *sc = mac->mac_sc; 1926 uint16_t rfover; 1927 uint16_t feedthrough; 1928 1929 if (phy->gmode) { 1930 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT; 1931 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT; 1932 1933 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0, 1934 ("%s:%d: fail", __func__, __LINE__)); 1935 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0, 1936 ("%s:%d: fail", __func__, __LINE__)); 1937 1938 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW); 1939 1940 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx; 1941 if ((sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) && 1942 phy->rev > 6) 1943 rfover |= BWN_PHY_RFOVERVAL_EXTLNA; 1944 1945 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 1946 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 1947 DELAY(10); 1948 rfover |= BWN_PHY_RFOVERVAL_BW_LBW; 1949 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 1950 DELAY(10); 1951 rfover |= BWN_PHY_RFOVERVAL_BW_LPF; 1952 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover); 1953 DELAY(10); 1954 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300); 1955 } else { 1956 pga |= BWN_PHY_PGACTL_UNKNOWN; 1957 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 1958 DELAY(10); 1959 pga |= BWN_PHY_PGACTL_LOWBANDW; 1960 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 1961 DELAY(10); 1962 pga |= BWN_PHY_PGACTL_LPF; 1963 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga); 1964 } 1965 DELAY(21); 1966 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE); 1967 1968 return (feedthrough); 1969 } 1970 1971 static uint16_t 1972 bwn_lo_txctl_regtable(struct bwn_mac *mac, 1973 uint16_t *value, uint16_t *pad_mix_gain) 1974 { 1975 struct bwn_phy *phy = &mac->mac_phy; 1976 uint16_t reg, v, padmix; 1977 1978 if (phy->type == BWN_PHYTYPE_B) { 1979 v = 0x30; 1980 if (phy->rf_rev <= 5) { 1981 reg = 0x43; 1982 padmix = 0; 1983 } else { 1984 reg = 0x52; 1985 padmix = 5; 1986 } 1987 } else { 1988 if (phy->rev >= 2 && phy->rf_rev == 8) { 1989 reg = 0x43; 1990 v = 0x10; 1991 padmix = 2; 1992 } else { 1993 reg = 0x52; 1994 v = 0x30; 1995 padmix = 5; 1996 } 1997 } 1998 if (value) 1999 *value = v; 2000 if (pad_mix_gain) 2001 *pad_mix_gain = padmix; 2002 2003 return (reg); 2004 } 2005 2006 static void 2007 bwn_lo_measure_txctl_values(struct bwn_mac *mac) 2008 { 2009 struct bwn_phy *phy = &mac->mac_phy; 2010 struct bwn_phy_g *pg = &phy->phy_g; 2011 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2012 uint16_t reg, mask; 2013 uint16_t trsw_rx, pga; 2014 uint16_t rf_pctl_reg; 2015 2016 static const uint8_t tx_bias_values[] = { 2017 0x09, 0x08, 0x0a, 0x01, 0x00, 2018 0x02, 0x05, 0x04, 0x06, 2019 }; 2020 static const uint8_t tx_magn_values[] = { 2021 0x70, 0x40, 2022 }; 2023 2024 if (!BWN_HAS_LOOPBACK(phy)) { 2025 rf_pctl_reg = 6; 2026 trsw_rx = 2; 2027 pga = 0; 2028 } else { 2029 int lb_gain; 2030 2031 trsw_rx = 0; 2032 lb_gain = pg->pg_max_lb_gain / 2; 2033 if (lb_gain > 10) { 2034 rf_pctl_reg = 0; 2035 pga = abs(10 - lb_gain) / 6; 2036 pga = MIN(MAX(pga, 0), 15); 2037 } else { 2038 int cmp_val; 2039 int tmp; 2040 2041 pga = 0; 2042 cmp_val = 0x24; 2043 if ((phy->rev >= 2) && 2044 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) 2045 cmp_val = 0x3c; 2046 tmp = lb_gain; 2047 if ((10 - lb_gain) < cmp_val) 2048 tmp = (10 - lb_gain); 2049 if (tmp < 0) 2050 tmp += 6; 2051 else 2052 tmp += 3; 2053 cmp_val /= 4; 2054 tmp /= 4; 2055 if (tmp >= cmp_val) 2056 rf_pctl_reg = cmp_val; 2057 else 2058 rf_pctl_reg = tmp; 2059 } 2060 } 2061 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg); 2062 bwn_phy_g_set_bbatt(mac, 2); 2063 2064 reg = bwn_lo_txctl_regtable(mac, &mask, NULL); 2065 mask = ~mask; 2066 BWN_RF_MASK(mac, reg, mask); 2067 2068 if (BWN_HAS_TXMAG(phy)) { 2069 int i, j; 2070 int feedthrough; 2071 int min_feedth = 0xffff; 2072 uint8_t tx_magn, tx_bias; 2073 2074 for (i = 0; i < N(tx_magn_values); i++) { 2075 tx_magn = tx_magn_values[i]; 2076 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn); 2077 for (j = 0; j < N(tx_bias_values); j++) { 2078 tx_bias = tx_bias_values[j]; 2079 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias); 2080 feedthrough = bwn_lo_calcfeed(mac, 0, pga, 2081 trsw_rx); 2082 if (feedthrough < min_feedth) { 2083 lo->tx_bias = tx_bias; 2084 lo->tx_magn = tx_magn; 2085 min_feedth = feedthrough; 2086 } 2087 if (lo->tx_bias == 0) 2088 break; 2089 } 2090 BWN_RF_WRITE(mac, 0x52, 2091 (BWN_RF_READ(mac, 0x52) 2092 & 0xff00) | lo->tx_bias | lo-> 2093 tx_magn); 2094 } 2095 } else { 2096 lo->tx_magn = 0; 2097 lo->tx_bias = 0; 2098 BWN_RF_MASK(mac, 0x52, 0xfff0); 2099 } 2100 2101 BWN_GETTIME(lo->txctl_measured_time); 2102 } 2103 2104 static void 2105 bwn_lo_get_powervector(struct bwn_mac *mac) 2106 { 2107 struct bwn_phy *phy = &mac->mac_phy; 2108 struct bwn_phy_g *pg = &phy->phy_g; 2109 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2110 int i; 2111 uint64_t tmp; 2112 uint64_t power_vector = 0; 2113 2114 for (i = 0; i < 8; i += 2) { 2115 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i); 2116 power_vector |= (tmp << (i * 8)); 2117 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0); 2118 } 2119 if (power_vector) 2120 lo->power_vector = power_vector; 2121 2122 BWN_GETTIME(lo->pwr_vec_read_time); 2123 } 2124 2125 static void 2126 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain, 2127 int use_trsw_rx) 2128 { 2129 struct bwn_phy *phy = &mac->mac_phy; 2130 struct bwn_phy_g *pg = &phy->phy_g; 2131 uint16_t tmp; 2132 2133 if (max_rx_gain < 0) 2134 max_rx_gain = 0; 2135 2136 if (BWN_HAS_LOOPBACK(phy)) { 2137 int trsw_rx_gain; 2138 2139 if (use_trsw_rx) { 2140 trsw_rx_gain = pg->pg_trsw_rx_gain / 2; 2141 if (max_rx_gain >= trsw_rx_gain) { 2142 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 2143 } 2144 } else 2145 trsw_rx_gain = max_rx_gain; 2146 if (trsw_rx_gain < 9) { 2147 pg->pg_lna_lod_gain = 0; 2148 } else { 2149 pg->pg_lna_lod_gain = 1; 2150 trsw_rx_gain -= 8; 2151 } 2152 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d); 2153 pg->pg_pga_gain = trsw_rx_gain / 3; 2154 if (pg->pg_pga_gain >= 5) { 2155 pg->pg_pga_gain -= 5; 2156 pg->pg_lna_gain = 2; 2157 } else 2158 pg->pg_lna_gain = 0; 2159 } else { 2160 pg->pg_lna_gain = 0; 2161 pg->pg_trsw_rx_gain = 0x20; 2162 if (max_rx_gain >= 0x14) { 2163 pg->pg_lna_lod_gain = 1; 2164 pg->pg_pga_gain = 2; 2165 } else if (max_rx_gain >= 0x12) { 2166 pg->pg_lna_lod_gain = 1; 2167 pg->pg_pga_gain = 1; 2168 } else if (max_rx_gain >= 0xf) { 2169 pg->pg_lna_lod_gain = 1; 2170 pg->pg_pga_gain = 0; 2171 } else { 2172 pg->pg_lna_lod_gain = 0; 2173 pg->pg_pga_gain = 0; 2174 } 2175 } 2176 2177 tmp = BWN_RF_READ(mac, 0x7a); 2178 if (pg->pg_lna_lod_gain == 0) 2179 tmp &= ~0x0008; 2180 else 2181 tmp |= 0x0008; 2182 BWN_RF_WRITE(mac, 0x7a, tmp); 2183 } 2184 2185 static void 2186 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 2187 { 2188 struct bwn_phy *phy = &mac->mac_phy; 2189 struct bwn_phy_g *pg = &phy->phy_g; 2190 struct bwn_softc *sc = mac->mac_sc; 2191 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2192 struct timespec ts; 2193 uint16_t tmp; 2194 2195 if (bwn_has_hwpctl(mac)) { 2196 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK); 2197 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01)); 2198 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 2199 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14)); 2200 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL); 2201 2202 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100); 2203 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40); 2204 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40); 2205 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200); 2206 } 2207 if (phy->type == BWN_PHYTYPE_B && 2208 phy->rf_ver == 0x2050 && phy->rf_rev < 6) { 2209 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410); 2210 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820); 2211 } 2212 if (phy->rev >= 2) { 2213 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER); 2214 sav->phy_analogoverval = 2215 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL); 2216 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER); 2217 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL); 2218 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL); 2219 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e)); 2220 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0); 2221 2222 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc); 2223 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff); 2224 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003); 2225 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc); 2226 if (phy->type == BWN_PHYTYPE_G) { 2227 if ((phy->rev >= 7) && 2228 (sc->sc_board_info.board_flags & 2229 BHND_BFL_EXTLNA)) { 2230 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933); 2231 } else { 2232 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133); 2233 } 2234 } else { 2235 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0); 2236 } 2237 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0); 2238 } 2239 sav->reg0 = BWN_READ_2(mac, 0x3f4); 2240 sav->reg1 = BWN_READ_2(mac, 0x3e2); 2241 sav->rf0 = BWN_RF_READ(mac, 0x43); 2242 sav->rf1 = BWN_RF_READ(mac, 0x7a); 2243 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL); 2244 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a)); 2245 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL); 2246 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL); 2247 2248 if (!BWN_HAS_TXMAG(phy)) { 2249 sav->rf2 = BWN_RF_READ(mac, 0x52); 2250 sav->rf2 &= 0x00f0; 2251 } 2252 if (phy->type == BWN_PHYTYPE_B) { 2253 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30)); 2254 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06)); 2255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff); 2256 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f); 2257 } else { 2258 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) 2259 | 0x8000); 2260 } 2261 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4) 2262 & 0xf000); 2263 2264 tmp = 2265 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e); 2266 BWN_PHY_WRITE(mac, tmp, 0x007f); 2267 2268 tmp = sav->phy_syncctl; 2269 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f); 2270 tmp = sav->rf1; 2271 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0); 2272 2273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3); 2274 if (phy->type == BWN_PHYTYPE_G || 2275 (phy->type == BWN_PHYTYPE_B && 2276 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) { 2277 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003); 2278 } else 2279 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802); 2280 if (phy->rev >= 2) 2281 bwn_dummy_transmission(mac, 0, 1); 2282 bwn_phy_g_switch_chan(mac, 6, 0); 2283 BWN_RF_READ(mac, 0x51); 2284 if (phy->type == BWN_PHYTYPE_G) 2285 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0); 2286 2287 nanouptime(&ts); 2288 if (ieee80211_time_before(lo->txctl_measured_time, 2289 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE)) 2290 bwn_lo_measure_txctl_values(mac); 2291 2292 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3) 2293 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078); 2294 else { 2295 if (phy->type == BWN_PHYTYPE_B) 2296 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 2297 else 2298 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078); 2299 } 2300 } 2301 2302 static void 2303 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav) 2304 { 2305 struct bwn_phy *phy = &mac->mac_phy; 2306 struct bwn_phy_g *pg = &phy->phy_g; 2307 uint16_t tmp; 2308 2309 if (phy->rev >= 2) { 2310 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300); 2311 tmp = (pg->pg_pga_gain << 8); 2312 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0); 2313 DELAY(5); 2314 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2); 2315 DELAY(2); 2316 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3); 2317 } else { 2318 tmp = (pg->pg_pga_gain | 0xefa0); 2319 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp); 2320 } 2321 if (phy->type == BWN_PHYTYPE_G) { 2322 if (phy->rev >= 3) 2323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078); 2324 else 2325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078); 2326 if (phy->rev >= 2) 2327 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202); 2328 else 2329 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101); 2330 } 2331 BWN_WRITE_2(mac, 0x3f4, sav->reg0); 2332 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl); 2333 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2); 2334 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl); 2335 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl); 2336 BWN_RF_WRITE(mac, 0x43, sav->rf0); 2337 BWN_RF_WRITE(mac, 0x7a, sav->rf1); 2338 if (!BWN_HAS_TXMAG(phy)) { 2339 tmp = sav->rf2; 2340 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp); 2341 } 2342 BWN_WRITE_2(mac, 0x3e2, sav->reg1); 2343 if (phy->type == BWN_PHYTYPE_B && 2344 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) { 2345 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0); 2346 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1); 2347 } 2348 if (phy->rev >= 2) { 2349 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover); 2350 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 2351 sav->phy_analogoverval); 2352 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl); 2353 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover); 2354 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval); 2355 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3); 2356 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0); 2357 } 2358 if (bwn_has_hwpctl(mac)) { 2359 tmp = (sav->phy_lomask & 0xbfff); 2360 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp); 2361 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg); 2362 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl); 2363 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4); 2364 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 2365 } 2366 bwn_phy_g_switch_chan(mac, sav->old_channel, 1); 2367 } 2368 2369 static int 2370 bwn_lo_probe_loctl(struct bwn_mac *mac, 2371 struct bwn_loctl *probe, struct bwn_lo_g_sm *d) 2372 { 2373 struct bwn_phy *phy = &mac->mac_phy; 2374 struct bwn_phy_g *pg = &phy->phy_g; 2375 struct bwn_loctl orig, test; 2376 struct bwn_loctl prev = { -100, -100 }; 2377 static const struct bwn_loctl modifiers[] = { 2378 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,}, 2379 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,} 2380 }; 2381 int begin, end, lower = 0, i; 2382 uint16_t feedth; 2383 2384 if (d->curstate == 0) { 2385 begin = 1; 2386 end = 8; 2387 } else if (d->curstate % 2 == 0) { 2388 begin = d->curstate - 1; 2389 end = d->curstate + 1; 2390 } else { 2391 begin = d->curstate - 2; 2392 end = d->curstate + 2; 2393 } 2394 if (begin < 1) 2395 begin += 8; 2396 if (end > 8) 2397 end -= 8; 2398 2399 memcpy(&orig, probe, sizeof(struct bwn_loctl)); 2400 i = begin; 2401 d->curstate = i; 2402 while (1) { 2403 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__)); 2404 memcpy(&test, &orig, sizeof(struct bwn_loctl)); 2405 test.i += modifiers[i - 1].i * d->multipler; 2406 test.q += modifiers[i - 1].q * d->multipler; 2407 if ((test.i != prev.i || test.q != prev.q) && 2408 (abs(test.i) <= 16 && abs(test.q) <= 16)) { 2409 bwn_lo_write(mac, &test); 2410 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 2411 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 2412 if (feedth < d->feedth) { 2413 memcpy(probe, &test, 2414 sizeof(struct bwn_loctl)); 2415 lower = 1; 2416 d->feedth = feedth; 2417 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy)) 2418 break; 2419 } 2420 } 2421 memcpy(&prev, &test, sizeof(prev)); 2422 if (i == end) 2423 break; 2424 if (i == 8) 2425 i = 1; 2426 else 2427 i++; 2428 d->curstate = i; 2429 } 2430 2431 return (lower); 2432 } 2433 2434 static void 2435 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain) 2436 { 2437 struct bwn_phy *phy = &mac->mac_phy; 2438 struct bwn_phy_g *pg = &phy->phy_g; 2439 struct bwn_lo_g_sm d; 2440 struct bwn_loctl probe; 2441 int lower, repeat, cnt = 0; 2442 uint16_t feedth; 2443 2444 d.nmeasure = 0; 2445 d.multipler = 1; 2446 if (BWN_HAS_LOOPBACK(phy)) 2447 d.multipler = 3; 2448 2449 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl)); 2450 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1; 2451 2452 do { 2453 bwn_lo_write(mac, &d.loctl); 2454 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 2455 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 2456 if (feedth < 0x258) { 2457 if (feedth >= 0x12c) 2458 *rxgain += 6; 2459 else 2460 *rxgain += 3; 2461 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain, 2462 pg->pg_pga_gain, pg->pg_trsw_rx_gain); 2463 } 2464 d.feedth = feedth; 2465 d.curstate = 0; 2466 do { 2467 KASSERT(d.curstate >= 0 && d.curstate <= 8, 2468 ("%s:%d: fail", __func__, __LINE__)); 2469 memcpy(&probe, &d.loctl, 2470 sizeof(struct bwn_loctl)); 2471 lower = bwn_lo_probe_loctl(mac, &probe, &d); 2472 if (!lower) 2473 break; 2474 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q)) 2475 break; 2476 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl)); 2477 d.nmeasure++; 2478 } while (d.nmeasure < 24); 2479 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl)); 2480 2481 if (BWN_HAS_LOOPBACK(phy)) { 2482 if (d.feedth > 0x1194) 2483 *rxgain -= 6; 2484 else if (d.feedth < 0x5dc) 2485 *rxgain += 3; 2486 if (cnt == 0) { 2487 if (d.feedth <= 0x5dc) { 2488 d.multipler = 1; 2489 cnt++; 2490 } else 2491 d.multipler = 2; 2492 } else if (cnt == 2) 2493 d.multipler = 1; 2494 } 2495 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy)); 2496 } while (++cnt < repeat); 2497 } 2498 2499 static struct bwn_lo_calib * 2500 bwn_lo_calibset(struct bwn_mac *mac, 2501 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt) 2502 { 2503 struct bwn_phy *phy = &mac->mac_phy; 2504 struct bwn_phy_g *pg = &phy->phy_g; 2505 struct bwn_loctl loctl = { 0, 0 }; 2506 struct bwn_lo_calib *cal; 2507 struct bwn_lo_g_value sval = { 0 }; 2508 int rxgain; 2509 uint16_t pad, reg, value; 2510 2511 sval.old_channel = phy->chan; 2512 bwn_mac_suspend(mac); 2513 bwn_lo_save(mac, &sval); 2514 2515 reg = bwn_lo_txctl_regtable(mac, &value, &pad); 2516 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att); 2517 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0)); 2518 2519 rxgain = (rfatt->att * 2) + (bbatt->att / 2); 2520 if (rfatt->padmix) 2521 rxgain -= pad; 2522 if (BWN_HAS_LOOPBACK(phy)) 2523 rxgain += pg->pg_max_lb_gain; 2524 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy)); 2525 bwn_phy_g_set_bbatt(mac, bbatt->att); 2526 bwn_lo_probe_sm(mac, &loctl, &rxgain); 2527 2528 bwn_lo_restore(mac, &sval); 2529 bwn_mac_enable(mac); 2530 2531 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO); 2532 if (!cal) { 2533 device_printf(mac->mac_sc->sc_dev, "out of memory\n"); 2534 return (NULL); 2535 } 2536 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt)); 2537 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt)); 2538 memcpy(&cal->ctl, &loctl, sizeof(loctl)); 2539 2540 BWN_GETTIME(cal->calib_time); 2541 2542 return (cal); 2543 } 2544 2545 static struct bwn_lo_calib * 2546 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 2547 const struct bwn_rfatt *rfatt) 2548 { 2549 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 2550 struct bwn_lo_calib *c; 2551 2552 TAILQ_FOREACH(c, &lo->calib_list, list) { 2553 if (!BWN_BBATTCMP(&c->bbatt, bbatt)) 2554 continue; 2555 if (!BWN_RFATTCMP(&c->rfatt, rfatt)) 2556 continue; 2557 return (c); 2558 } 2559 2560 c = bwn_lo_calibset(mac, bbatt, rfatt); 2561 if (!c) 2562 return (NULL); 2563 TAILQ_INSERT_TAIL(&lo->calib_list, c, list); 2564 2565 return (c); 2566 } 2567 2568 static void 2569 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update) 2570 { 2571 struct bwn_phy *phy = &mac->mac_phy; 2572 struct bwn_phy_g *pg = &phy->phy_g; 2573 struct bwn_softc *sc = mac->mac_sc; 2574 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 2575 const struct bwn_rfatt *rfatt; 2576 const struct bwn_bbatt *bbatt; 2577 uint64_t pvector; 2578 int i; 2579 int rf_offset, bb_offset; 2580 uint8_t changed = 0; 2581 2582 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__)); 2583 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64, 2584 ("%s:%d: fail", __func__, __LINE__)); 2585 2586 pvector = lo->power_vector; 2587 if (!update && !pvector) 2588 return; 2589 2590 bwn_mac_suspend(mac); 2591 2592 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) { 2593 struct bwn_lo_calib *cal; 2594 int idx; 2595 uint16_t val; 2596 2597 if (!update && !(pvector & (((uint64_t)1ULL) << i))) 2598 continue; 2599 bb_offset = i / lo->rfatt.len; 2600 rf_offset = i % lo->rfatt.len; 2601 bbatt = &(lo->bbatt.array[bb_offset]); 2602 rfatt = &(lo->rfatt.array[rf_offset]); 2603 2604 cal = bwn_lo_calibset(mac, bbatt, rfatt); 2605 if (!cal) { 2606 device_printf(sc->sc_dev, "LO: Could not " 2607 "calibrate DC table entry\n"); 2608 continue; 2609 } 2610 val = (uint8_t)(cal->ctl.q); 2611 val |= ((uint8_t)(cal->ctl.i)) << 4; 2612 free(cal, M_DEVBUF); 2613 2614 idx = i / 2; 2615 if (i % 2) 2616 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff) 2617 | ((val & 0x00ff) << 8); 2618 else 2619 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00) 2620 | (val & 0x00ff); 2621 changed = 1; 2622 } 2623 if (changed) { 2624 for (i = 0; i < BWN_DC_LT_SIZE; i++) 2625 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]); 2626 } 2627 bwn_mac_enable(mac); 2628 } 2629 2630 static void 2631 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf) 2632 { 2633 2634 if (!rf->padmix) 2635 return; 2636 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3)) 2637 rf->att = 4; 2638 } 2639 2640 static void 2641 bwn_lo_g_adjust(struct bwn_mac *mac) 2642 { 2643 struct bwn_phy_g *pg = &mac->mac_phy.phy_g; 2644 struct bwn_lo_calib *cal; 2645 struct bwn_rfatt rf; 2646 2647 memcpy(&rf, &pg->pg_rfatt, sizeof(rf)); 2648 bwn_lo_fixup_rfatt(&rf); 2649 2650 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf); 2651 if (!cal) 2652 return; 2653 bwn_lo_write(mac, &cal->ctl); 2654 } 2655 2656 static void 2657 bwn_lo_g_init(struct bwn_mac *mac) 2658 { 2659 2660 if (!bwn_has_hwpctl(mac)) 2661 return; 2662 2663 bwn_lo_get_powervector(mac); 2664 bwn_phy_g_dc_lookup_init(mac, 1); 2665 } 2666 2667 static int16_t 2668 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset) 2669 { 2670 2671 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset); 2672 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA)); 2673 } 2674 2675 static void 2676 bwn_nrssi_threshold(struct bwn_mac *mac) 2677 { 2678 struct bwn_phy *phy = &mac->mac_phy; 2679 struct bwn_phy_g *pg = &phy->phy_g; 2680 struct bwn_softc *sc = mac->mac_sc; 2681 int32_t a, b; 2682 int16_t tmp16; 2683 uint16_t tmpu16; 2684 2685 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__)); 2686 2687 if (phy->gmode && (sc->sc_board_info.board_flags & BHND_BFL_ADCDIV)) { 2688 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) { 2689 a = 0x13; 2690 b = 0x12; 2691 } else { 2692 a = 0xe; 2693 b = 0x11; 2694 } 2695 2696 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 2697 a += (pg->pg_nrssi[0] << 6); 2698 a += (a < 32) ? 31 : 32; 2699 a = a >> 6; 2700 a = MIN(MAX(a, -31), 31); 2701 2702 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]); 2703 b += (pg->pg_nrssi[0] << 6); 2704 if (b < 32) 2705 b += 31; 2706 else 2707 b += 32; 2708 b = b >> 6; 2709 b = MIN(MAX(b, -31), 31); 2710 2711 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000; 2712 tmpu16 |= ((uint32_t)b & 0x0000003f); 2713 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6); 2714 BWN_PHY_WRITE(mac, 0x048a, tmpu16); 2715 return; 2716 } 2717 2718 tmp16 = bwn_nrssi_read(mac, 0x20); 2719 if (tmp16 >= 0x20) 2720 tmp16 -= 0x40; 2721 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed); 2722 } 2723 2724 static void 2725 bwn_nrssi_slope_11g(struct bwn_mac *mac) 2726 { 2727 #define SAVE_RF_MAX 3 2728 #define SAVE_PHY_COMM_MAX 4 2729 #define SAVE_PHY3_MAX 8 2730 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 2731 { 0x7a, 0x52, 0x43 }; 2732 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = 2733 { 0x15, 0x5a, 0x59, 0x58 }; 2734 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { 2735 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL, 2736 0x0801, 0x0060, 0x0014, 0x0478 2737 }; 2738 struct bwn_phy *phy = &mac->mac_phy; 2739 struct bwn_phy_g *pg = &phy->phy_g; 2740 int32_t i, tmp32, phy3_idx = 0; 2741 uint16_t delta, tmp; 2742 uint16_t save_rf[SAVE_RF_MAX]; 2743 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 2744 uint16_t save_phy3[SAVE_PHY3_MAX]; 2745 uint16_t ant_div, phy0, chan_ex; 2746 int16_t nrssi0, nrssi1; 2747 2748 KASSERT(phy->type == BWN_PHYTYPE_G, 2749 ("%s:%d: fail", __func__, __LINE__)); 2750 2751 if (phy->rf_rev >= 9) 2752 return; 2753 if (phy->rf_rev == 8) 2754 bwn_nrssi_offset(mac); 2755 2756 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff); 2757 BWN_PHY_MASK(mac, 0x0802, 0xfffc); 2758 2759 /* 2760 * Save RF/PHY registers for later restoration 2761 */ 2762 ant_div = BWN_READ_2(mac, 0x03e2); 2763 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000); 2764 for (i = 0; i < SAVE_RF_MAX; ++i) 2765 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 2766 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 2767 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 2768 2769 phy0 = BWN_READ_2(mac, BWN_PHY0); 2770 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT); 2771 if (phy->rev >= 3) { 2772 for (i = 0; i < SAVE_PHY3_MAX; ++i) 2773 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]); 2774 BWN_PHY_WRITE(mac, 0x002e, 0); 2775 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0); 2776 switch (phy->rev) { 2777 case 4: 2778 case 6: 2779 case 7: 2780 BWN_PHY_SET(mac, 0x0478, 0x0100); 2781 BWN_PHY_SET(mac, 0x0801, 0x0040); 2782 break; 2783 case 3: 2784 case 5: 2785 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 2786 break; 2787 } 2788 BWN_PHY_SET(mac, 0x0060, 0x0040); 2789 BWN_PHY_SET(mac, 0x0014, 0x0200); 2790 } 2791 /* 2792 * Calculate nrssi0 2793 */ 2794 BWN_RF_SET(mac, 0x007a, 0x0070); 2795 bwn_set_all_gains(mac, 0, 8, 0); 2796 BWN_RF_MASK(mac, 0x007a, 0x00f7); 2797 if (phy->rev >= 2) { 2798 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030); 2799 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010); 2800 } 2801 BWN_RF_SET(mac, 0x007a, 0x0080); 2802 DELAY(20); 2803 2804 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 2805 if (nrssi0 >= 0x0020) 2806 nrssi0 -= 0x0040; 2807 2808 /* 2809 * Calculate nrssi1 2810 */ 2811 BWN_RF_MASK(mac, 0x007a, 0x007f); 2812 if (phy->rev >= 2) 2813 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 2814 2815 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 2816 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000); 2817 BWN_RF_SET(mac, 0x007a, 0x000f); 2818 BWN_PHY_WRITE(mac, 0x0015, 0xf330); 2819 if (phy->rev >= 2) { 2820 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020); 2821 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020); 2822 } 2823 2824 bwn_set_all_gains(mac, 3, 0, 1); 2825 if (phy->rf_rev == 8) { 2826 BWN_RF_WRITE(mac, 0x0043, 0x001f); 2827 } else { 2828 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f; 2829 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060); 2830 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0; 2831 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009); 2832 } 2833 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 2834 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 2835 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 2836 DELAY(20); 2837 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 2838 2839 /* 2840 * Install calculated narrow RSSI values 2841 */ 2842 if (nrssi1 >= 0x0020) 2843 nrssi1 -= 0x0040; 2844 if (nrssi0 == nrssi1) 2845 pg->pg_nrssi_slope = 0x00010000; 2846 else 2847 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1); 2848 if (nrssi0 >= -4) { 2849 pg->pg_nrssi[0] = nrssi1; 2850 pg->pg_nrssi[1] = nrssi0; 2851 } 2852 2853 /* 2854 * Restore saved RF/PHY registers 2855 */ 2856 if (phy->rev >= 3) { 2857 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { 2858 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 2859 save_phy3[phy3_idx]); 2860 } 2861 } 2862 if (phy->rev >= 2) { 2863 BWN_PHY_MASK(mac, 0x0812, 0xffcf); 2864 BWN_PHY_MASK(mac, 0x0811, 0xffcf); 2865 } 2866 2867 for (i = 0; i < SAVE_RF_MAX; ++i) 2868 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 2869 2870 BWN_WRITE_2(mac, 0x03e2, ant_div); 2871 BWN_WRITE_2(mac, 0x03e6, phy0); 2872 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex); 2873 2874 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 2875 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 2876 2877 bwn_spu_workaround(mac, phy->chan); 2878 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002)); 2879 bwn_set_original_gains(mac); 2880 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000); 2881 if (phy->rev >= 3) { 2882 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { 2883 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx], 2884 save_phy3[phy3_idx]); 2885 } 2886 } 2887 2888 delta = 0x1f - pg->pg_nrssi[0]; 2889 for (i = 0; i < 64; i++) { 2890 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a; 2891 tmp32 = MIN(MAX(tmp32, 0), 0x3f); 2892 pg->pg_nrssi_lt[i] = tmp32; 2893 } 2894 2895 bwn_nrssi_threshold(mac); 2896 #undef SAVE_RF_MAX 2897 #undef SAVE_PHY_COMM_MAX 2898 #undef SAVE_PHY3_MAX 2899 } 2900 2901 static void 2902 bwn_nrssi_offset(struct bwn_mac *mac) 2903 { 2904 #define SAVE_RF_MAX 2 2905 #define SAVE_PHY_COMM_MAX 10 2906 #define SAVE_PHY6_MAX 8 2907 static const uint16_t save_rf_regs[SAVE_RF_MAX] = 2908 { 0x7a, 0x43 }; 2909 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { 2910 0x0001, 0x0811, 0x0812, 0x0814, 2911 0x0815, 0x005a, 0x0059, 0x0058, 2912 0x000a, 0x0003 2913 }; 2914 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { 2915 0x002e, 0x002f, 0x080f, 0x0810, 2916 0x0801, 0x0060, 0x0014, 0x0478 2917 }; 2918 struct bwn_phy *phy = &mac->mac_phy; 2919 int i, phy6_idx = 0; 2920 uint16_t save_rf[SAVE_RF_MAX]; 2921 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; 2922 uint16_t save_phy6[SAVE_PHY6_MAX]; 2923 int16_t nrssi; 2924 uint16_t saved = 0xffff; 2925 2926 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) 2927 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]); 2928 for (i = 0; i < SAVE_RF_MAX; ++i) 2929 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]); 2930 2931 BWN_PHY_MASK(mac, 0x0429, 0x7fff); 2932 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000); 2933 BWN_PHY_SET(mac, 0x0811, 0x000c); 2934 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004); 2935 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2)); 2936 if (phy->rev >= 6) { 2937 for (i = 0; i < SAVE_PHY6_MAX; ++i) 2938 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]); 2939 2940 BWN_PHY_WRITE(mac, 0x002e, 0); 2941 BWN_PHY_WRITE(mac, 0x002f, 0); 2942 BWN_PHY_WRITE(mac, 0x080f, 0); 2943 BWN_PHY_WRITE(mac, 0x0810, 0); 2944 BWN_PHY_SET(mac, 0x0478, 0x0100); 2945 BWN_PHY_SET(mac, 0x0801, 0x0040); 2946 BWN_PHY_SET(mac, 0x0060, 0x0040); 2947 BWN_PHY_SET(mac, 0x0014, 0x0200); 2948 } 2949 BWN_RF_SET(mac, 0x007a, 0x0070); 2950 BWN_RF_SET(mac, 0x007a, 0x0080); 2951 DELAY(30); 2952 2953 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 2954 if (nrssi >= 0x20) 2955 nrssi -= 0x40; 2956 if (nrssi == 31) { 2957 for (i = 7; i >= 4; i--) { 2958 BWN_RF_WRITE(mac, 0x007b, i); 2959 DELAY(20); 2960 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 2961 0x003f); 2962 if (nrssi >= 0x20) 2963 nrssi -= 0x40; 2964 if (nrssi < 31 && saved == 0xffff) 2965 saved = i; 2966 } 2967 if (saved == 0xffff) 2968 saved = 4; 2969 } else { 2970 BWN_RF_MASK(mac, 0x007a, 0x007f); 2971 if (phy->rev != 1) { 2972 BWN_PHY_SET(mac, 0x0814, 0x0001); 2973 BWN_PHY_MASK(mac, 0x0815, 0xfffe); 2974 } 2975 BWN_PHY_SET(mac, 0x0811, 0x000c); 2976 BWN_PHY_SET(mac, 0x0812, 0x000c); 2977 BWN_PHY_SET(mac, 0x0811, 0x0030); 2978 BWN_PHY_SET(mac, 0x0812, 0x0030); 2979 BWN_PHY_WRITE(mac, 0x005a, 0x0480); 2980 BWN_PHY_WRITE(mac, 0x0059, 0x0810); 2981 BWN_PHY_WRITE(mac, 0x0058, 0x000d); 2982 if (phy->rev == 0) 2983 BWN_PHY_WRITE(mac, 0x0003, 0x0122); 2984 else 2985 BWN_PHY_SET(mac, 0x000a, 0x2000); 2986 if (phy->rev != 1) { 2987 BWN_PHY_SET(mac, 0x0814, 0x0004); 2988 BWN_PHY_MASK(mac, 0x0815, 0xfffb); 2989 } 2990 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040); 2991 BWN_RF_SET(mac, 0x007a, 0x000f); 2992 bwn_set_all_gains(mac, 3, 0, 1); 2993 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f); 2994 DELAY(30); 2995 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f); 2996 if (nrssi >= 0x20) 2997 nrssi -= 0x40; 2998 if (nrssi == -32) { 2999 for (i = 0; i < 4; i++) { 3000 BWN_RF_WRITE(mac, 0x007b, i); 3001 DELAY(20); 3002 nrssi = (int16_t)((BWN_PHY_READ(mac, 3003 0x047f) >> 8) & 0x003f); 3004 if (nrssi >= 0x20) 3005 nrssi -= 0x40; 3006 if (nrssi > -31 && saved == 0xffff) 3007 saved = i; 3008 } 3009 if (saved == 0xffff) 3010 saved = 3; 3011 } else 3012 saved = 0; 3013 } 3014 BWN_RF_WRITE(mac, 0x007b, saved); 3015 3016 /* 3017 * Restore saved RF/PHY registers 3018 */ 3019 if (phy->rev >= 6) { 3020 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { 3021 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 3022 save_phy6[phy6_idx]); 3023 } 3024 } 3025 if (phy->rev != 1) { 3026 for (i = 3; i < 5; i++) 3027 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], 3028 save_phy_comm[i]); 3029 } 3030 for (i = 5; i < SAVE_PHY_COMM_MAX; i++) 3031 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]); 3032 3033 for (i = SAVE_RF_MAX - 1; i >= 0; --i) 3034 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]); 3035 3036 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2); 3037 BWN_PHY_SET(mac, 0x0429, 0x8000); 3038 bwn_set_original_gains(mac); 3039 if (phy->rev >= 6) { 3040 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { 3041 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx], 3042 save_phy6[phy6_idx]); 3043 } 3044 } 3045 3046 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]); 3047 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]); 3048 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]); 3049 } 3050 3051 static void 3052 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second, 3053 int16_t third) 3054 { 3055 struct bwn_phy *phy = &mac->mac_phy; 3056 uint16_t i; 3057 uint16_t start = 0x08, end = 0x18; 3058 uint16_t tmp; 3059 uint16_t table; 3060 3061 if (phy->rev <= 1) { 3062 start = 0x10; 3063 end = 0x20; 3064 } 3065 3066 table = BWN_OFDMTAB_GAINX; 3067 if (phy->rev <= 1) 3068 table = BWN_OFDMTAB_GAINX_R1; 3069 for (i = 0; i < 4; i++) 3070 bwn_ofdmtab_write_2(mac, table, i, first); 3071 3072 for (i = start; i < end; i++) 3073 bwn_ofdmtab_write_2(mac, table, i, second); 3074 3075 if (third != -1) { 3076 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6); 3077 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp); 3078 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp); 3079 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp); 3080 } 3081 bwn_dummy_transmission(mac, 0, 1); 3082 } 3083 3084 static void 3085 bwn_set_original_gains(struct bwn_mac *mac) 3086 { 3087 struct bwn_phy *phy = &mac->mac_phy; 3088 uint16_t i, tmp; 3089 uint16_t table; 3090 uint16_t start = 0x0008, end = 0x0018; 3091 3092 if (phy->rev <= 1) { 3093 start = 0x0010; 3094 end = 0x0020; 3095 } 3096 3097 table = BWN_OFDMTAB_GAINX; 3098 if (phy->rev <= 1) 3099 table = BWN_OFDMTAB_GAINX_R1; 3100 for (i = 0; i < 4; i++) { 3101 tmp = (i & 0xfffc); 3102 tmp |= (i & 0x0001) << 1; 3103 tmp |= (i & 0x0002) >> 1; 3104 3105 bwn_ofdmtab_write_2(mac, table, i, tmp); 3106 } 3107 3108 for (i = start; i < end; i++) 3109 bwn_ofdmtab_write_2(mac, table, i, i - start); 3110 3111 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040); 3112 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040); 3113 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000); 3114 bwn_dummy_transmission(mac, 0, 1); 3115 } 3116 3117 static void 3118 bwn_phy_hwpctl_init(struct bwn_mac *mac) 3119 { 3120 struct bwn_phy *phy = &mac->mac_phy; 3121 struct bwn_phy_g *pg = &phy->phy_g; 3122 struct bwn_rfatt old_rfatt, rfatt; 3123 struct bwn_bbatt old_bbatt, bbatt; 3124 struct bwn_softc *sc = mac->mac_sc; 3125 uint8_t old_txctl = 0; 3126 3127 KASSERT(phy->type == BWN_PHYTYPE_G, 3128 ("%s:%d: fail", __func__, __LINE__)); 3129 3130 if ((sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM) && 3131 (sc->sc_board_info.board_type == BHND_BOARD_BU4306)) 3132 return; 3133 3134 BWN_PHY_WRITE(mac, 0x0028, 0x8018); 3135 3136 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf); 3137 3138 if (!phy->gmode) 3139 return; 3140 bwn_hwpctl_early_init(mac); 3141 if (pg->pg_curtssi == 0) { 3142 if (phy->rf_ver == 0x2050 && phy->analog == 0) { 3143 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084); 3144 } else { 3145 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt)); 3146 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt)); 3147 old_txctl = pg->pg_txctl; 3148 3149 bbatt.att = 11; 3150 if (phy->rf_rev == 8) { 3151 rfatt.att = 15; 3152 rfatt.padmix = 1; 3153 } else { 3154 rfatt.att = 9; 3155 rfatt.padmix = 0; 3156 } 3157 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0); 3158 } 3159 bwn_dummy_transmission(mac, 0, 1); 3160 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI); 3161 if (phy->rf_ver == 0x2050 && phy->analog == 0) 3162 BWN_RF_MASK(mac, 0x0076, 0xff7b); 3163 else 3164 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt, 3165 &old_rfatt, old_txctl); 3166 } 3167 bwn_hwpctl_init_gphy(mac); 3168 3169 /* clear TSSI */ 3170 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f); 3171 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f); 3172 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f); 3173 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f); 3174 } 3175 3176 static void 3177 bwn_hwpctl_early_init(struct bwn_mac *mac) 3178 { 3179 struct bwn_phy *phy = &mac->mac_phy; 3180 3181 if (!bwn_has_hwpctl(mac)) { 3182 BWN_PHY_WRITE(mac, 0x047a, 0xc111); 3183 return; 3184 } 3185 3186 BWN_PHY_MASK(mac, 0x0036, 0xfeff); 3187 BWN_PHY_WRITE(mac, 0x002f, 0x0202); 3188 BWN_PHY_SET(mac, 0x047c, 0x0002); 3189 BWN_PHY_SET(mac, 0x047a, 0xf000); 3190 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) { 3191 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 3192 BWN_PHY_SET(mac, 0x005d, 0x8000); 3193 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 3194 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 3195 BWN_PHY_SET(mac, 0x0036, 0x0400); 3196 } else { 3197 BWN_PHY_SET(mac, 0x0036, 0x0200); 3198 BWN_PHY_SET(mac, 0x0036, 0x0400); 3199 BWN_PHY_MASK(mac, 0x005d, 0x7fff); 3200 BWN_PHY_MASK(mac, 0x004f, 0xfffe); 3201 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010); 3202 BWN_PHY_WRITE(mac, 0x002e, 0xc07f); 3203 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010); 3204 } 3205 } 3206 3207 static void 3208 bwn_hwpctl_init_gphy(struct bwn_mac *mac) 3209 { 3210 struct bwn_phy *phy = &mac->mac_phy; 3211 struct bwn_phy_g *pg = &phy->phy_g; 3212 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 3213 int i; 3214 uint16_t nr_written = 0, tmp, value; 3215 uint8_t rf, bb; 3216 3217 if (!bwn_has_hwpctl(mac)) { 3218 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL); 3219 return; 3220 } 3221 3222 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0, 3223 (pg->pg_idletssi - pg->pg_curtssi)); 3224 BWN_PHY_SETMASK(mac, 0x0478, 0xff00, 3225 (pg->pg_idletssi - pg->pg_curtssi)); 3226 3227 for (i = 0; i < 32; i++) 3228 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]); 3229 for (i = 32; i < 64; i++) 3230 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]); 3231 for (i = 0; i < 64; i += 2) { 3232 value = (uint16_t) pg->pg_tssi2dbm[i]; 3233 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8; 3234 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value); 3235 } 3236 3237 for (rf = 0; rf < lo->rfatt.len; rf++) { 3238 for (bb = 0; bb < lo->bbatt.len; bb++) { 3239 if (nr_written >= 0x40) 3240 return; 3241 tmp = lo->bbatt.array[bb].att; 3242 tmp <<= 8; 3243 if (phy->rf_rev == 8) 3244 tmp |= 0x50; 3245 else 3246 tmp |= 0x40; 3247 tmp |= lo->rfatt.array[rf].att; 3248 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp); 3249 nr_written++; 3250 } 3251 } 3252 3253 BWN_PHY_MASK(mac, 0x0060, 0xffbf); 3254 BWN_PHY_WRITE(mac, 0x0014, 0x0000); 3255 3256 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__)); 3257 BWN_PHY_SET(mac, 0x0478, 0x0800); 3258 BWN_PHY_MASK(mac, 0x0478, 0xfeff); 3259 BWN_PHY_MASK(mac, 0x0801, 0xffbf); 3260 3261 bwn_phy_g_dc_lookup_init(mac, 1); 3262 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL); 3263 } 3264 3265 static void 3266 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu) 3267 { 3268 struct bwn_softc *sc = mac->mac_sc; 3269 int error; 3270 3271 if (spu != 0) 3272 bwn_spu_workaround(mac, channel); 3273 3274 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 3275 3276 if (channel == 14) { 3277 uint8_t cc; 3278 3279 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_CC, &cc); 3280 if (error) { 3281 device_printf(sc->sc_dev, "error reading country code " 3282 "from NVRAM, assuming channel 14 unavailable: %d\n", 3283 error); 3284 cc = BWN_SPROM1_CC_WORLDWIDE; 3285 } 3286 3287 if (cc == BWN_SPROM1_CC_JP) 3288 bwn_hf_write(mac, 3289 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF); 3290 else 3291 bwn_hf_write(mac, 3292 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF); 3293 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 3294 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11)); 3295 return; 3296 } 3297 3298 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, 3299 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf); 3300 } 3301 3302 static uint16_t 3303 bwn_phy_g_chan2freq(uint8_t channel) 3304 { 3305 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS; 3306 3307 KASSERT(channel >= 1 && channel <= 14, 3308 ("%s:%d: fail", __func__, __LINE__)); 3309 3310 return (bwn_phy_g_rf_channels[channel - 1]); 3311 } 3312 3313 static void 3314 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt, 3315 const struct bwn_rfatt *rfatt, uint8_t txctl) 3316 { 3317 struct bwn_phy *phy = &mac->mac_phy; 3318 struct bwn_phy_g *pg = &phy->phy_g; 3319 struct bwn_txpwr_loctl *lo = &pg->pg_loctl; 3320 uint16_t bb, rf; 3321 uint16_t tx_bias, tx_magn; 3322 3323 bb = bbatt->att; 3324 rf = rfatt->att; 3325 tx_bias = lo->tx_bias; 3326 tx_magn = lo->tx_magn; 3327 if (tx_bias == 0xff) 3328 tx_bias = 0; 3329 3330 pg->pg_txctl = txctl; 3331 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt)); 3332 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0; 3333 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt)); 3334 bwn_phy_g_set_bbatt(mac, bb); 3335 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf); 3336 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) 3337 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070)); 3338 else { 3339 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f)); 3340 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070)); 3341 } 3342 if (BWN_HAS_TXMAG(phy)) 3343 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias); 3344 else 3345 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f)); 3346 bwn_lo_g_adjust(mac); 3347 } 3348 3349 static void 3350 bwn_phy_g_set_bbatt(struct bwn_mac *mac, 3351 uint16_t bbatt) 3352 { 3353 struct bwn_phy *phy = &mac->mac_phy; 3354 3355 if (phy->analog == 0) { 3356 BWN_WRITE_2(mac, BWN_PHY0, 3357 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt); 3358 return; 3359 } 3360 if (phy->analog > 1) { 3361 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2); 3362 return; 3363 } 3364 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3); 3365 } 3366 3367 static uint16_t 3368 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd) 3369 { 3370 struct bwn_phy *phy = &mac->mac_phy; 3371 struct bwn_phy_g *pg = &phy->phy_g; 3372 struct bwn_softc *sc = mac->mac_sc; 3373 int max_lb_gain; 3374 uint16_t extlna; 3375 uint16_t i; 3376 3377 if (phy->gmode == 0) 3378 return (0); 3379 3380 if (BWN_HAS_LOOPBACK(phy)) { 3381 max_lb_gain = pg->pg_max_lb_gain; 3382 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26; 3383 if (max_lb_gain >= 0x46) { 3384 extlna = 0x3000; 3385 max_lb_gain -= 0x46; 3386 } else if (max_lb_gain >= 0x3a) { 3387 extlna = 0x1000; 3388 max_lb_gain -= 0x3a; 3389 } else if (max_lb_gain >= 0x2e) { 3390 extlna = 0x2000; 3391 max_lb_gain -= 0x2e; 3392 } else { 3393 extlna = 0; 3394 max_lb_gain -= 0x10; 3395 } 3396 3397 for (i = 0; i < 16; i++) { 3398 max_lb_gain -= (i * 6); 3399 if (max_lb_gain < 6) 3400 break; 3401 } 3402 3403 if ((phy->rev < 7) || 3404 !(sc->sc_board_info.board_flags & BHND_BFL_EXTLNA)) { 3405 if (reg == BWN_PHY_RFOVER) { 3406 return (0x1b3); 3407 } else if (reg == BWN_PHY_RFOVERVAL) { 3408 extlna |= (i << 8); 3409 switch (lpd) { 3410 case BWN_LPD(0, 1, 1): 3411 return (0x0f92); 3412 case BWN_LPD(0, 0, 1): 3413 case BWN_LPD(1, 0, 1): 3414 return (0x0092 | extlna); 3415 case BWN_LPD(1, 0, 0): 3416 return (0x0093 | extlna); 3417 } 3418 KASSERT(0 == 1, 3419 ("%s:%d: fail", __func__, __LINE__)); 3420 } 3421 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3422 } else { 3423 if (reg == BWN_PHY_RFOVER) 3424 return (0x9b3); 3425 if (reg == BWN_PHY_RFOVERVAL) { 3426 if (extlna) 3427 extlna |= 0x8000; 3428 extlna |= (i << 8); 3429 switch (lpd) { 3430 case BWN_LPD(0, 1, 1): 3431 return (0x8f92); 3432 case BWN_LPD(0, 0, 1): 3433 return (0x8092 | extlna); 3434 case BWN_LPD(1, 0, 1): 3435 return (0x2092 | extlna); 3436 case BWN_LPD(1, 0, 0): 3437 return (0x2093 | extlna); 3438 } 3439 KASSERT(0 == 1, 3440 ("%s:%d: fail", __func__, __LINE__)); 3441 } 3442 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3443 } 3444 return (0); 3445 } 3446 3447 if ((phy->rev < 7) || 3448 !(sc->sc_board_info.board_flags & BHND_BFL_EXTLNA)) { 3449 if (reg == BWN_PHY_RFOVER) { 3450 return (0x1b3); 3451 } else if (reg == BWN_PHY_RFOVERVAL) { 3452 switch (lpd) { 3453 case BWN_LPD(0, 1, 1): 3454 return (0x0fb2); 3455 case BWN_LPD(0, 0, 1): 3456 return (0x00b2); 3457 case BWN_LPD(1, 0, 1): 3458 return (0x30b2); 3459 case BWN_LPD(1, 0, 0): 3460 return (0x30b3); 3461 } 3462 KASSERT(0 == 1, 3463 ("%s:%d: fail", __func__, __LINE__)); 3464 } 3465 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3466 } else { 3467 if (reg == BWN_PHY_RFOVER) { 3468 return (0x9b3); 3469 } else if (reg == BWN_PHY_RFOVERVAL) { 3470 switch (lpd) { 3471 case BWN_LPD(0, 1, 1): 3472 return (0x8fb2); 3473 case BWN_LPD(0, 0, 1): 3474 return (0x80b2); 3475 case BWN_LPD(1, 0, 1): 3476 return (0x20b2); 3477 case BWN_LPD(1, 0, 0): 3478 return (0x20b3); 3479 } 3480 KASSERT(0 == 1, 3481 ("%s:%d: fail", __func__, __LINE__)); 3482 } 3483 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3484 } 3485 return (0); 3486 } 3487 3488 static void 3489 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel) 3490 { 3491 3492 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6) 3493 return; 3494 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ? 3495 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1)); 3496 DELAY(1000); 3497 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel)); 3498 } 3499 3500 static int 3501 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset) 3502 { 3503 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK); 3504 unsigned int a, b, c, d; 3505 unsigned int avg; 3506 uint32_t tmp; 3507 3508 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset); 3509 a = tmp & 0xff; 3510 b = (tmp >> 8) & 0xff; 3511 c = (tmp >> 16) & 0xff; 3512 d = (tmp >> 24) & 0xff; 3513 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX || 3514 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX) 3515 return (ENOENT); 3516 bwn_shm_write_4(mac, BWN_SHARED, shm_offset, 3517 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) | 3518 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24)); 3519 3520 if (ofdm) { 3521 a = (a + 32) & 0x3f; 3522 b = (b + 32) & 0x3f; 3523 c = (c + 32) & 0x3f; 3524 d = (d + 32) & 0x3f; 3525 } 3526 3527 avg = (a + b + c + d + 2) / 4; 3528 if (ofdm) { 3529 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO) 3530 & BWN_HF_4DB_CCK_POWERBOOST) 3531 avg = (avg >= 13) ? (avg - 13) : 0; 3532 } 3533 return (avg); 3534 } 3535 3536 static void 3537 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp) 3538 { 3539 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl; 3540 int rfatt = *rfattp; 3541 int bbatt = *bbattp; 3542 3543 while (1) { 3544 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4) 3545 break; 3546 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4) 3547 break; 3548 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1) 3549 break; 3550 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1) 3551 break; 3552 if (bbatt > lo->bbatt.max) { 3553 bbatt -= 4; 3554 rfatt += 1; 3555 continue; 3556 } 3557 if (bbatt < lo->bbatt.min) { 3558 bbatt += 4; 3559 rfatt -= 1; 3560 continue; 3561 } 3562 if (rfatt > lo->rfatt.max) { 3563 rfatt -= 1; 3564 bbatt += 4; 3565 continue; 3566 } 3567 if (rfatt < lo->rfatt.min) { 3568 rfatt += 1; 3569 bbatt -= 4; 3570 continue; 3571 } 3572 break; 3573 } 3574 3575 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max); 3576 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max); 3577 } 3578 3579 static void 3580 bwn_phy_lock(struct bwn_mac *mac) 3581 { 3582 struct bwn_softc *sc = mac->mac_sc; 3583 struct ieee80211com *ic = &sc->sc_ic; 3584 3585 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 3, 3586 ("%s: unsupported rev %d", __func__, bhnd_get_hwrev(sc->sc_dev))); 3587 3588 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 3589 bwn_psctl(mac, BWN_PS_AWAKE); 3590 } 3591 3592 static void 3593 bwn_phy_unlock(struct bwn_mac *mac) 3594 { 3595 struct bwn_softc *sc = mac->mac_sc; 3596 struct ieee80211com *ic = &sc->sc_ic; 3597 3598 KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 3, 3599 ("%s: unsupported rev %d", __func__, bhnd_get_hwrev(sc->sc_dev))); 3600 3601 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 3602 bwn_psctl(mac, 0); 3603 } 3604 3605 static void 3606 bwn_rf_lock(struct bwn_mac *mac) 3607 { 3608 3609 BWN_WRITE_4(mac, BWN_MACCTL, 3610 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK); 3611 BWN_READ_4(mac, BWN_MACCTL); 3612 DELAY(10); 3613 } 3614 3615 static void 3616 bwn_rf_unlock(struct bwn_mac *mac) 3617 { 3618 3619 BWN_READ_2(mac, BWN_PHYVER); 3620 BWN_WRITE_4(mac, BWN_MACCTL, 3621 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK); 3622 } 3623