1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 5 * 6 * This code is derived from software contributed to The DragonFly Project 7 * by Sepherosa Ziehau <sepherosa@gmail.com> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 3. Neither the name of The DragonFly Project nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific, prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $DragonFly: src/sys/dev/netif/bwi/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $ 37 */ 38 39 #include <sys/cdefs.h> 40 #include "opt_inet.h" 41 #include "opt_wlan.h" 42 43 #include <sys/param.h> 44 #include <sys/endian.h> 45 #include <sys/kernel.h> 46 #include <sys/bus.h> 47 #include <sys/malloc.h> 48 #include <sys/proc.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 #include <sys/sysctl.h> 53 #include <sys/systm.h> 54 55 #include <net/if.h> 56 #include <net/if_var.h> 57 #include <net/if_dl.h> 58 #include <net/if_media.h> 59 #include <net/if_types.h> 60 #include <net/if_arp.h> 61 #include <net/ethernet.h> 62 #include <net/if_llc.h> 63 64 #include <net80211/ieee80211_var.h> 65 #include <net80211/ieee80211_radiotap.h> 66 #include <net80211/ieee80211_amrr.h> 67 68 #include <machine/bus.h> 69 70 #include <dev/bwi/bitops.h> 71 #include <dev/bwi/if_bwireg.h> 72 #include <dev/bwi/if_bwivar.h> 73 #include <dev/bwi/bwimac.h> 74 #include <dev/bwi/bwirf.h> 75 #include <dev/bwi/bwiphy.h> 76 77 static void bwi_phy_init_11a(struct bwi_mac *); 78 static void bwi_phy_init_11g(struct bwi_mac *); 79 static void bwi_phy_init_11b_rev2(struct bwi_mac *); 80 static void bwi_phy_init_11b_rev4(struct bwi_mac *); 81 static void bwi_phy_init_11b_rev5(struct bwi_mac *); 82 static void bwi_phy_init_11b_rev6(struct bwi_mac *); 83 84 static void bwi_phy_config_11g(struct bwi_mac *); 85 static void bwi_phy_config_agc(struct bwi_mac *); 86 87 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); 88 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); 89 #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num } 90 91 static const struct { 92 uint8_t rev; 93 void (*init)(struct bwi_mac *); 94 } bwi_sup_bphy[] = { 95 SUP_BPHY(2), 96 SUP_BPHY(4), 97 SUP_BPHY(5), 98 SUP_BPHY(6) 99 }; 100 101 #undef SUP_BPHY 102 103 #define BWI_PHYTBL_WRSSI 0x1000 104 #define BWI_PHYTBL_NOISE_SCALE 0x1400 105 #define BWI_PHYTBL_NOISE 0x1800 106 #define BWI_PHYTBL_ROTOR 0x2000 107 #define BWI_PHYTBL_DELAY 0x2400 108 #define BWI_PHYTBL_RSSI 0x4000 109 #define BWI_PHYTBL_SIGMA_SQ 0x5000 110 #define BWI_PHYTBL_WRSSI_REV1 0x5400 111 #define BWI_PHYTBL_FREQ 0x5800 112 113 static const uint16_t bwi_phy_freq_11g_rev1[] = 114 { BWI_PHY_FREQ_11G_REV1 }; 115 static const uint16_t bwi_phy_noise_11g_rev1[] = 116 { BWI_PHY_NOISE_11G_REV1 }; 117 static const uint16_t bwi_phy_noise_11g[] = 118 { BWI_PHY_NOISE_11G }; 119 static const uint32_t bwi_phy_rotor_11g_rev1[] = 120 { BWI_PHY_ROTOR_11G_REV1 }; 121 static const uint16_t bwi_phy_noise_scale_11g_rev2[] = 122 { BWI_PHY_NOISE_SCALE_11G_REV2 }; 123 static const uint16_t bwi_phy_noise_scale_11g_rev7[] = 124 { BWI_PHY_NOISE_SCALE_11G_REV7 }; 125 static const uint16_t bwi_phy_noise_scale_11g[] = 126 { BWI_PHY_NOISE_SCALE_11G }; 127 static const uint16_t bwi_phy_sigma_sq_11g_rev2[] = 128 { BWI_PHY_SIGMA_SQ_11G_REV2 }; 129 static const uint16_t bwi_phy_sigma_sq_11g_rev7[] = 130 { BWI_PHY_SIGMA_SQ_11G_REV7 }; 131 static const uint32_t bwi_phy_delay_11g_rev1[] = 132 { BWI_PHY_DELAY_11G_REV1 }; 133 134 void 135 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) 136 { 137 struct bwi_softc *sc = mac->mac_sc; 138 139 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); 140 CSR_WRITE_2(sc, BWI_PHY_DATA, data); 141 } 142 143 uint16_t 144 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl) 145 { 146 struct bwi_softc *sc = mac->mac_sc; 147 148 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); 149 return CSR_READ_2(sc, BWI_PHY_DATA); 150 } 151 152 int 153 bwi_phy_attach(struct bwi_mac *mac) 154 { 155 struct bwi_softc *sc = mac->mac_sc; 156 struct bwi_phy *phy = &mac->mac_phy; 157 uint8_t phyrev, phytype, phyver; 158 uint16_t val; 159 int i; 160 161 /* Get PHY type/revision/version */ 162 val = CSR_READ_2(sc, BWI_PHYINFO); 163 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK); 164 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK); 165 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK); 166 device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n", 167 phytype, phyrev, phyver); 168 169 /* 170 * Verify whether the revision of the PHY type is supported 171 * Convert PHY type to ieee80211_phymode 172 */ 173 switch (phytype) { 174 case BWI_PHYINFO_TYPE_11A: 175 if (phyrev >= 4) { 176 device_printf(sc->sc_dev, "unsupported 11A PHY, " 177 "rev %u\n", phyrev); 178 return ENXIO; 179 } 180 phy->phy_init = bwi_phy_init_11a; 181 phy->phy_mode = IEEE80211_MODE_11A; 182 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A; 183 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A; 184 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A; 185 break; 186 case BWI_PHYINFO_TYPE_11B: 187 for (i = 0; i < nitems(bwi_sup_bphy); ++i) { 188 if (phyrev == bwi_sup_bphy[i].rev) { 189 phy->phy_init = bwi_sup_bphy[i].init; 190 break; 191 } 192 } 193 if (i == nitems(bwi_sup_bphy)) { 194 device_printf(sc->sc_dev, "unsupported 11B PHY, " 195 "rev %u\n", phyrev); 196 return ENXIO; 197 } 198 phy->phy_mode = IEEE80211_MODE_11B; 199 break; 200 case BWI_PHYINFO_TYPE_11G: 201 if (phyrev > 8) { 202 device_printf(sc->sc_dev, "unsupported 11G PHY, " 203 "rev %u\n", phyrev); 204 return ENXIO; 205 } 206 phy->phy_init = bwi_phy_init_11g; 207 phy->phy_mode = IEEE80211_MODE_11G; 208 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G; 209 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G; 210 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G; 211 break; 212 default: 213 device_printf(sc->sc_dev, "unsupported PHY type %d\n", 214 phytype); 215 return ENXIO; 216 } 217 phy->phy_rev = phyrev; 218 phy->phy_version = phyver; 219 return 0; 220 } 221 222 void 223 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten) 224 { 225 struct bwi_phy *phy = &mac->mac_phy; 226 uint16_t mask = __BITS(3, 0); 227 228 if (phy->phy_version == 0) { 229 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask, 230 __SHIFTIN(bbp_atten, mask)); 231 } else { 232 if (phy->phy_version > 1) 233 mask <<= 2; 234 else 235 mask <<= 3; 236 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask, 237 __SHIFTIN(bbp_atten, mask)); 238 } 239 } 240 241 int 242 bwi_phy_calibrate(struct bwi_mac *mac) 243 { 244 struct bwi_phy *phy = &mac->mac_phy; 245 246 /* Dummy read */ 247 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS); 248 249 /* Don't re-init */ 250 if (phy->phy_flags & BWI_PHY_F_CALIBRATED) 251 return 0; 252 253 if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) { 254 bwi_mac_reset(mac, 0); 255 bwi_phy_init_11g(mac); 256 bwi_mac_reset(mac, 1); 257 } 258 259 phy->phy_flags |= BWI_PHY_F_CALIBRATED; 260 return 0; 261 } 262 263 static void 264 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data) 265 { 266 struct bwi_phy *phy = &mac->mac_phy; 267 268 KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0, 269 ("phy_tbl_ctrl %d phy_tbl_data_lo %d", 270 phy->phy_tbl_ctrl, phy->phy_tbl_data_lo)); 271 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 272 PHY_WRITE(mac, phy->phy_tbl_data_lo, data); 273 } 274 275 static void 276 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data) 277 { 278 struct bwi_phy *phy = &mac->mac_phy; 279 280 KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && 281 phy->phy_tbl_ctrl != 0, 282 ("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d", 283 phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl)); 284 285 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 286 PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16); 287 PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff); 288 } 289 290 void 291 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data) 292 { 293 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 294 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data); 295 } 296 297 int16_t 298 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs) 299 { 300 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 301 return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA); 302 } 303 304 static void 305 bwi_phy_init_11a(struct bwi_mac *mac) 306 { 307 /* TODO:11A */ 308 } 309 310 static void 311 bwi_phy_init_11g(struct bwi_mac *mac) 312 { 313 struct bwi_softc *sc = mac->mac_sc; 314 struct bwi_phy *phy = &mac->mac_phy; 315 struct bwi_rf *rf = &mac->mac_rf; 316 const struct bwi_tpctl *tpctl = &mac->mac_tpctl; 317 318 if (phy->phy_rev == 1) 319 bwi_phy_init_11b_rev5(mac); 320 else 321 bwi_phy_init_11b_rev6(mac); 322 323 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) 324 bwi_phy_config_11g(mac); 325 326 if (phy->phy_rev >= 2) { 327 PHY_WRITE(mac, 0x814, 0); 328 PHY_WRITE(mac, 0x815, 0); 329 330 if (phy->phy_rev == 2) { 331 PHY_WRITE(mac, 0x811, 0); 332 PHY_WRITE(mac, 0x15, 0xc0); 333 } else if (phy->phy_rev > 5) { 334 PHY_WRITE(mac, 0x811, 0x400); 335 PHY_WRITE(mac, 0x15, 0xc0); 336 } 337 } 338 339 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) { 340 uint16_t val; 341 342 val = PHY_READ(mac, 0x400) & 0xff; 343 if (val == 3 || val == 5) { 344 PHY_WRITE(mac, 0x4c2, 0x1816); 345 PHY_WRITE(mac, 0x4c3, 0x8006); 346 if (val == 5) { 347 PHY_FILT_SETBITS(mac, 0x4cc, 348 0xff, 0x1f00); 349 } 350 } 351 } 352 353 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) || 354 phy->phy_rev >= 2) 355 PHY_WRITE(mac, 0x47e, 0x78); 356 357 if (rf->rf_rev == 8) { 358 PHY_SETBITS(mac, 0x801, 0x80); 359 PHY_SETBITS(mac, 0x43e, 0x4); 360 } 361 362 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) 363 bwi_rf_get_gains(mac); 364 365 if (rf->rf_rev != 8) 366 bwi_rf_init(mac); 367 368 if (tpctl->tp_ctrl2 == 0xffff) { 369 bwi_rf_lo_update(mac); 370 } else { 371 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) { 372 RF_WRITE(mac, 0x52, 373 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2); 374 } else { 375 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2); 376 } 377 378 if (phy->phy_rev >= 6) { 379 PHY_FILT_SETBITS(mac, 0x36, 0xfff, 380 tpctl->tp_ctrl2 << 12); 381 } 382 383 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 384 PHY_WRITE(mac, 0x2e, 0x8075); 385 else 386 PHY_WRITE(mac, 0x2e, 0x807f); 387 388 if (phy->phy_rev < 2) 389 PHY_WRITE(mac, 0x2f, 0x101); 390 else 391 PHY_WRITE(mac, 0x2f, 0x202); 392 } 393 394 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 395 bwi_rf_lo_adjust(mac, tpctl); 396 PHY_WRITE(mac, 0x80f, 0x8078); 397 } 398 399 if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) { 400 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */); 401 bwi_rf_set_nrssi_thr(mac); 402 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 403 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) { 404 KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI, 405 ("rf_nrssi[1] %d", rf->rf_nrssi[1])); 406 bwi_rf_calc_nrssi_slope(mac); 407 } else { 408 KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI, 409 ("rf_nrssi[1] %d", rf->rf_nrssi[1])); 410 bwi_rf_set_nrssi_thr(mac); 411 } 412 } 413 414 if (rf->rf_rev == 8) 415 PHY_WRITE(mac, 0x805, 0x3230); 416 417 bwi_mac_init_tpctl_11bg(mac); 418 419 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) { 420 PHY_CLRBITS(mac, 0x429, 0x4000); 421 PHY_CLRBITS(mac, 0x4c3, 0x8000); 422 } 423 } 424 425 static void 426 bwi_phy_init_11b_rev2(struct bwi_mac *mac) 427 { 428 /* TODO:11B */ 429 device_printf(mac->mac_sc->sc_dev, 430 "%s is not implemented yet\n", __func__); 431 } 432 433 static void 434 bwi_phy_init_11b_rev4(struct bwi_mac *mac) 435 { 436 struct bwi_softc *sc = mac->mac_sc; 437 struct bwi_rf *rf = &mac->mac_rf; 438 uint16_t val, ofs; 439 u_int chan; 440 441 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 442 443 PHY_WRITE(mac, 0x20, 0x301c); 444 PHY_WRITE(mac, 0x26, 0); 445 PHY_WRITE(mac, 0x30, 0xc6); 446 PHY_WRITE(mac, 0x88, 0x3e00); 447 448 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202) 449 PHY_WRITE(mac, 0x89 + ofs, val); 450 451 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 452 453 chan = rf->rf_curchan; 454 if (chan == IEEE80211_CHAN_ANY) 455 chan = 6; /* Force to channel 6 */ 456 bwi_rf_set_chan(mac, chan, 0); 457 458 if (rf->rf_type != BWI_RF_T_BCM2050) { 459 RF_WRITE(mac, 0x75, 0x80); 460 RF_WRITE(mac, 0x79, 0x81); 461 } 462 463 RF_WRITE(mac, 0x50, 0x20); 464 RF_WRITE(mac, 0x50, 0x23); 465 466 if (rf->rf_type == BWI_RF_T_BCM2050) { 467 RF_WRITE(mac, 0x50, 0x20); 468 RF_WRITE(mac, 0x5a, 0x70); 469 RF_WRITE(mac, 0x5b, 0x7b); 470 RF_WRITE(mac, 0x5c, 0xb0); 471 RF_WRITE(mac, 0x7a, 0xf); 472 PHY_WRITE(mac, 0x38, 0x677); 473 bwi_rf_init_bcm2050(mac); 474 } 475 476 PHY_WRITE(mac, 0x14, 0x80); 477 PHY_WRITE(mac, 0x32, 0xca); 478 if (rf->rf_type == BWI_RF_T_BCM2050) 479 PHY_WRITE(mac, 0x32, 0xe0); 480 PHY_WRITE(mac, 0x35, 0x7c2); 481 482 bwi_rf_lo_update(mac); 483 484 PHY_WRITE(mac, 0x26, 0xcc00); 485 if (rf->rf_type == BWI_RF_T_BCM2050) 486 PHY_WRITE(mac, 0x26, 0xce00); 487 488 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100); 489 490 PHY_WRITE(mac, 0x2a, 0x88a3); 491 if (rf->rf_type == BWI_RF_T_BCM2050) 492 PHY_WRITE(mac, 0x2a, 0x88c2); 493 494 bwi_mac_set_tpctl_11bg(mac, NULL); 495 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 496 bwi_rf_calc_nrssi_slope(mac); 497 bwi_rf_set_nrssi_thr(mac); 498 } 499 bwi_mac_init_tpctl_11bg(mac); 500 } 501 502 static void 503 bwi_phy_init_11b_rev5(struct bwi_mac *mac) 504 { 505 struct bwi_softc *sc = mac->mac_sc; 506 struct bwi_rf *rf = &mac->mac_rf; 507 struct bwi_phy *phy = &mac->mac_phy; 508 u_int orig_chan; 509 510 if (phy->phy_version == 1) 511 RF_SETBITS(mac, 0x7a, 0x50); 512 513 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM && 514 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) { 515 uint16_t ofs, val; 516 517 val = 0x2120; 518 for (ofs = 0xa8; ofs < 0xc7; ++ofs) { 519 PHY_WRITE(mac, ofs, val); 520 val += 0x202; 521 } 522 } 523 524 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700); 525 526 if (rf->rf_type == BWI_RF_T_BCM2050) 527 PHY_WRITE(mac, 0x38, 0x667); 528 529 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 530 if (rf->rf_type == BWI_RF_T_BCM2050) { 531 RF_SETBITS(mac, 0x7a, 0x20); 532 RF_SETBITS(mac, 0x51, 0x4); 533 } 534 535 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0); 536 537 PHY_SETBITS(mac, 0x802, 0x100); 538 PHY_SETBITS(mac, 0x42b, 0x2000); 539 PHY_WRITE(mac, 0x1c, 0x186a); 540 541 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900); 542 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64); 543 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa); 544 } 545 546 /* TODO: bad_frame_preempt? */ 547 548 if (phy->phy_version == 1) { 549 PHY_WRITE(mac, 0x26, 0xce00); 550 PHY_WRITE(mac, 0x21, 0x3763); 551 PHY_WRITE(mac, 0x22, 0x1bc3); 552 PHY_WRITE(mac, 0x23, 0x6f9); 553 PHY_WRITE(mac, 0x24, 0x37e); 554 } else { 555 PHY_WRITE(mac, 0x26, 0xcc00); 556 } 557 PHY_WRITE(mac, 0x30, 0xc6); 558 559 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 560 561 if (phy->phy_version == 1) 562 PHY_WRITE(mac, 0x20, 0x3e1c); 563 else 564 PHY_WRITE(mac, 0x20, 0x301c); 565 566 if (phy->phy_version == 0) 567 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 568 569 /* Force to channel 7 */ 570 orig_chan = rf->rf_curchan; 571 bwi_rf_set_chan(mac, 7, 0); 572 573 if (rf->rf_type != BWI_RF_T_BCM2050) { 574 RF_WRITE(mac, 0x75, 0x80); 575 RF_WRITE(mac, 0x79, 0x81); 576 } 577 578 RF_WRITE(mac, 0x50, 0x20); 579 RF_WRITE(mac, 0x50, 0x23); 580 581 if (rf->rf_type == BWI_RF_T_BCM2050) { 582 RF_WRITE(mac, 0x50, 0x20); 583 RF_WRITE(mac, 0x5a, 0x70); 584 } 585 586 RF_WRITE(mac, 0x5b, 0x7b); 587 RF_WRITE(mac, 0x5c, 0xb0); 588 RF_SETBITS(mac, 0x7a, 0x7); 589 590 bwi_rf_set_chan(mac, orig_chan, 0); 591 592 PHY_WRITE(mac, 0x14, 0x80); 593 PHY_WRITE(mac, 0x32, 0xca); 594 PHY_WRITE(mac, 0x2a, 0x88a3); 595 596 bwi_mac_set_tpctl_11bg(mac, NULL); 597 598 if (rf->rf_type == BWI_RF_T_BCM2050) 599 RF_WRITE(mac, 0x5d, 0xd); 600 601 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4); 602 } 603 604 static void 605 bwi_phy_init_11b_rev6(struct bwi_mac *mac) 606 { 607 struct bwi_softc *sc = mac->mac_sc; 608 struct bwi_rf *rf = &mac->mac_rf; 609 struct bwi_phy *phy = &mac->mac_phy; 610 uint16_t val, ofs; 611 u_int orig_chan; 612 613 PHY_WRITE(mac, 0x3e, 0x817a); 614 RF_SETBITS(mac, 0x7a, 0x58); 615 616 if (rf->rf_rev == 4 || rf->rf_rev == 5) { 617 RF_WRITE(mac, 0x51, 0x37); 618 RF_WRITE(mac, 0x52, 0x70); 619 RF_WRITE(mac, 0x53, 0xb3); 620 RF_WRITE(mac, 0x54, 0x9b); 621 RF_WRITE(mac, 0x5a, 0x88); 622 RF_WRITE(mac, 0x5b, 0x88); 623 RF_WRITE(mac, 0x5d, 0x88); 624 RF_WRITE(mac, 0x5e, 0x88); 625 RF_WRITE(mac, 0x7d, 0x88); 626 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1); 627 } else if (rf->rf_rev == 8) { 628 RF_WRITE(mac, 0x51, 0); 629 RF_WRITE(mac, 0x52, 0x40); 630 RF_WRITE(mac, 0x53, 0xb7); 631 RF_WRITE(mac, 0x54, 0x98); 632 RF_WRITE(mac, 0x5a, 0x88); 633 RF_WRITE(mac, 0x5b, 0x6b); 634 RF_WRITE(mac, 0x5c, 0xf); 635 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) { 636 RF_WRITE(mac, 0x5d, 0xfa); 637 RF_WRITE(mac, 0x5e, 0xd8); 638 } else { 639 RF_WRITE(mac, 0x5d, 0xf5); 640 RF_WRITE(mac, 0x5e, 0xb8); 641 } 642 RF_WRITE(mac, 0x73, 0x3); 643 RF_WRITE(mac, 0x7d, 0xa8); 644 RF_WRITE(mac, 0x7c, 0x1); 645 RF_WRITE(mac, 0x7e, 0x8); 646 } 647 648 val = 0x1e1f; 649 for (ofs = 0x88; ofs < 0x98; ++ofs) { 650 PHY_WRITE(mac, ofs, val); 651 val -= 0x202; 652 } 653 654 val = 0x3e3f; 655 for (ofs = 0x98; ofs < 0xa8; ++ofs) { 656 PHY_WRITE(mac, ofs, val); 657 val -= 0x202; 658 } 659 660 val = 0x2120; 661 for (ofs = 0xa8; ofs < 0xc8; ++ofs) { 662 PHY_WRITE(mac, ofs, (val & 0x3f3f)); 663 val += 0x202; 664 665 /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */ 666 DELAY(10); 667 } 668 669 if (phy->phy_mode == IEEE80211_MODE_11G) { 670 RF_SETBITS(mac, 0x7a, 0x20); 671 RF_SETBITS(mac, 0x51, 0x4); 672 PHY_SETBITS(mac, 0x802, 0x100); 673 PHY_SETBITS(mac, 0x42b, 0x2000); 674 PHY_WRITE(mac, 0x5b, 0); 675 PHY_WRITE(mac, 0x5c, 0); 676 } 677 678 /* Force to channel 7 */ 679 orig_chan = rf->rf_curchan; 680 if (orig_chan >= 8) 681 bwi_rf_set_chan(mac, 1, 0); 682 else 683 bwi_rf_set_chan(mac, 13, 0); 684 685 RF_WRITE(mac, 0x50, 0x20); 686 RF_WRITE(mac, 0x50, 0x23); 687 688 DELAY(40); 689 690 if (rf->rf_rev < 6 || rf->rf_rev == 8) { 691 RF_SETBITS(mac, 0x7c, 0x2); 692 RF_WRITE(mac, 0x50, 0x20); 693 } 694 if (rf->rf_rev <= 2) { 695 RF_WRITE(mac, 0x7c, 0x20); 696 RF_WRITE(mac, 0x5a, 0x70); 697 RF_WRITE(mac, 0x5b, 0x7b); 698 RF_WRITE(mac, 0x5c, 0xb0); 699 } 700 701 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7); 702 703 bwi_rf_set_chan(mac, orig_chan, 0); 704 705 PHY_WRITE(mac, 0x14, 0x200); 706 if (rf->rf_rev >= 6) 707 PHY_WRITE(mac, 0x2a, 0x88c2); 708 else 709 PHY_WRITE(mac, 0x2a, 0x8ac0); 710 PHY_WRITE(mac, 0x38, 0x668); 711 712 bwi_mac_set_tpctl_11bg(mac, NULL); 713 714 if (rf->rf_rev <= 5) { 715 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3); 716 if (rf->rf_rev <= 2) 717 RF_WRITE(mac, 0x5d, 0xd); 718 } 719 720 if (phy->phy_version == 4) { 721 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2); 722 PHY_CLRBITS(mac, 0x61, 0xf000); 723 } else { 724 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4); 725 } 726 727 if (phy->phy_mode == IEEE80211_MODE_11B) { 728 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2); 729 PHY_WRITE(mac, 0x16, 0x410); 730 PHY_WRITE(mac, 0x17, 0x820); 731 PHY_WRITE(mac, 0x62, 0x7); 732 733 bwi_rf_init_bcm2050(mac); 734 bwi_rf_lo_update(mac); 735 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 736 bwi_rf_calc_nrssi_slope(mac); 737 bwi_rf_set_nrssi_thr(mac); 738 } 739 bwi_mac_init_tpctl_11bg(mac); 740 } else { 741 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 742 } 743 } 744 745 static void 746 bwi_phy_config_11g(struct bwi_mac *mac) 747 { 748 struct bwi_softc *sc = mac->mac_sc; 749 struct bwi_phy *phy = &mac->mac_phy; 750 const uint16_t *tbl; 751 uint16_t wrd_ofs1, wrd_ofs2; 752 int i, n; 753 754 if (phy->phy_rev == 1) { 755 PHY_WRITE(mac, 0x406, 0x4f19); 756 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340); 757 PHY_WRITE(mac, 0x42c, 0x5a); 758 PHY_WRITE(mac, 0x427, 0x1a); 759 760 /* Fill frequency table */ 761 for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) { 762 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i, 763 bwi_phy_freq_11g_rev1[i]); 764 } 765 766 /* Fill noise table */ 767 for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) { 768 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 769 bwi_phy_noise_11g_rev1[i]); 770 } 771 772 /* Fill rotor table */ 773 for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) { 774 /* NB: data length is 4 bytes */ 775 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i, 776 bwi_phy_rotor_11g_rev1[i]); 777 } 778 } else { 779 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */ 780 781 if (phy->phy_rev == 2) { 782 PHY_WRITE(mac, 0x4c0, 0x1861); 783 PHY_WRITE(mac, 0x4c1, 0x271); 784 } else if (phy->phy_rev > 2) { 785 PHY_WRITE(mac, 0x4c0, 0x98); 786 PHY_WRITE(mac, 0x4c1, 0x70); 787 PHY_WRITE(mac, 0x4c9, 0x80); 788 } 789 PHY_SETBITS(mac, 0x42b, 0x800); 790 791 /* Fill RSSI table */ 792 for (i = 0; i < 64; ++i) 793 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i); 794 795 /* Fill noise table */ 796 for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) { 797 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 798 bwi_phy_noise_11g[i]); 799 } 800 } 801 802 /* 803 * Fill noise scale table 804 */ 805 if (phy->phy_rev <= 2) { 806 tbl = bwi_phy_noise_scale_11g_rev2; 807 n = nitems(bwi_phy_noise_scale_11g_rev2); 808 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) { 809 tbl = bwi_phy_noise_scale_11g_rev7; 810 n = nitems(bwi_phy_noise_scale_11g_rev7); 811 } else { 812 tbl = bwi_phy_noise_scale_11g; 813 n = nitems(bwi_phy_noise_scale_11g); 814 } 815 for (i = 0; i < n; ++i) 816 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]); 817 818 /* 819 * Fill sigma square table 820 */ 821 if (phy->phy_rev == 2) { 822 tbl = bwi_phy_sigma_sq_11g_rev2; 823 n = nitems(bwi_phy_sigma_sq_11g_rev2); 824 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) { 825 tbl = bwi_phy_sigma_sq_11g_rev7; 826 n = nitems(bwi_phy_sigma_sq_11g_rev7); 827 } else { 828 tbl = NULL; 829 n = 0; 830 } 831 for (i = 0; i < n; ++i) 832 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]); 833 834 if (phy->phy_rev == 1) { 835 /* Fill delay table */ 836 for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) { 837 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i, 838 bwi_phy_delay_11g_rev1[i]); 839 } 840 841 /* Fill WRSSI (Wide-Band RSSI) table */ 842 for (i = 4; i < 20; ++i) 843 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20); 844 845 bwi_phy_config_agc(mac); 846 847 wrd_ofs1 = 0x5001; 848 wrd_ofs2 = 0x5002; 849 } else { 850 /* Fill WRSSI (Wide-Band RSSI) table */ 851 for (i = 0; i < 0x20; ++i) 852 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820); 853 854 bwi_phy_config_agc(mac); 855 856 PHY_READ(mac, 0x400); /* Dummy read */ 857 PHY_WRITE(mac, 0x403, 0x1000); 858 bwi_tbl_write_2(mac, 0x3c02, 0xf); 859 bwi_tbl_write_2(mac, 0x3c03, 0x14); 860 861 wrd_ofs1 = 0x401; 862 wrd_ofs2 = 0x402; 863 } 864 865 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) { 866 bwi_tbl_write_2(mac, wrd_ofs1, 0x2); 867 bwi_tbl_write_2(mac, wrd_ofs2, 0x1); 868 } 869 870 /* phy->phy_flags & BWI_PHY_F_LINKED ? */ 871 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 872 PHY_WRITE(mac, 0x46e, 0x3cf); 873 } 874 875 /* 876 * Configure Automatic Gain Controller 877 */ 878 static void 879 bwi_phy_config_agc(struct bwi_mac *mac) 880 { 881 struct bwi_phy *phy = &mac->mac_phy; 882 uint16_t ofs; 883 884 ofs = phy->phy_rev == 1 ? 0x4c00 : 0; 885 886 bwi_tbl_write_2(mac, ofs, 0xfe); 887 bwi_tbl_write_2(mac, ofs + 1, 0xd); 888 bwi_tbl_write_2(mac, ofs + 2, 0x13); 889 bwi_tbl_write_2(mac, ofs + 3, 0x19); 890 891 if (phy->phy_rev == 1) { 892 bwi_tbl_write_2(mac, 0x1800, 0x2710); 893 bwi_tbl_write_2(mac, 0x1801, 0x9b83); 894 bwi_tbl_write_2(mac, 0x1802, 0x9b83); 895 bwi_tbl_write_2(mac, 0x1803, 0xf8d); 896 PHY_WRITE(mac, 0x455, 0x4); 897 } 898 899 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700); 900 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf); 901 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80); 902 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300); 903 904 RF_SETBITS(mac, 0x7a, 0x8); 905 906 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8); 907 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600); 908 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700); 909 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100); 910 911 if (phy->phy_rev == 1) 912 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7); 913 914 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c); 915 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200); 916 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c); 917 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20); 918 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200); 919 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e); 920 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00); 921 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28); 922 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00); 923 924 if (phy->phy_rev == 1) { 925 PHY_WRITE(mac, 0x430, 0x92b); 926 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2); 927 } else { 928 PHY_CLRBITS(mac, 0x41b, 0x1e); 929 PHY_WRITE(mac, 0x41f, 0x287a); 930 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4); 931 932 if (phy->phy_rev >= 6) { 933 PHY_WRITE(mac, 0x422, 0x287a); 934 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000); 935 } 936 } 937 938 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874); 939 PHY_WRITE(mac, 0x48e, 0x1c00); 940 941 if (phy->phy_rev == 1) { 942 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600); 943 PHY_WRITE(mac, 0x48b, 0x5e); 944 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e); 945 PHY_WRITE(mac, 0x48d, 0x2); 946 } 947 948 bwi_tbl_write_2(mac, ofs + 0x800, 0); 949 bwi_tbl_write_2(mac, ofs + 0x801, 7); 950 bwi_tbl_write_2(mac, ofs + 0x802, 16); 951 bwi_tbl_write_2(mac, ofs + 0x803, 28); 952 953 if (phy->phy_rev >= 6) { 954 PHY_CLRBITS(mac, 0x426, 0x3); 955 PHY_CLRBITS(mac, 0x426, 0x1000); 956 } 957 } 958 959 void 960 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains) 961 { 962 struct bwi_phy *phy = &mac->mac_phy; 963 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain; 964 int i; 965 966 if (phy->phy_rev <= 1) { 967 tbl_gain_ofs1 = 0x5000; 968 tbl_gain_ofs2 = tbl_gain_ofs1 + 16; 969 } else { 970 tbl_gain_ofs1 = 0x400; 971 tbl_gain_ofs2 = tbl_gain_ofs1 + 8; 972 } 973 974 for (i = 0; i < 4; ++i) { 975 if (gains != NULL) { 976 tbl_gain = gains->tbl_gain1; 977 } else { 978 /* Bit swap */ 979 tbl_gain = (i & 0x1) << 1; 980 tbl_gain |= (i & 0x2) >> 1; 981 } 982 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain); 983 } 984 985 for (i = 0; i < 16; ++i) { 986 if (gains != NULL) 987 tbl_gain = gains->tbl_gain2; 988 else 989 tbl_gain = i; 990 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain); 991 } 992 993 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) { 994 uint16_t phy_gain1, phy_gain2; 995 996 if (gains != NULL) { 997 phy_gain1 = 998 ((uint16_t)gains->phy_gain << 14) | 999 ((uint16_t)gains->phy_gain << 6); 1000 phy_gain2 = phy_gain1; 1001 } else { 1002 phy_gain1 = 0x4040; 1003 phy_gain2 = 0x4000; 1004 } 1005 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1); 1006 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1); 1007 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2); 1008 } 1009 bwi_mac_dummy_xmit(mac); 1010 } 1011 1012 void 1013 bwi_phy_clear_state(struct bwi_phy *phy) 1014 { 1015 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS; 1016 } 1017