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