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