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