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