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