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