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