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_dl.h> 57 #include <net/if_media.h> 58 #include <net/if_types.h> 59 #include <net/if_arp.h> 60 #include <net/ethernet.h> 61 #include <net/if_llc.h> 62 63 #include <net80211/ieee80211_var.h> 64 #include <net80211/ieee80211_radiotap.h> 65 #include <net80211/ieee80211_amrr.h> 66 67 #include <machine/bus.h> 68 69 #include <dev/bwi/bitops.h> 70 #include <dev/bwi/if_bwireg.h> 71 #include <dev/bwi/if_bwivar.h> 72 #include <dev/bwi/bwimac.h> 73 #include <dev/bwi/bwirf.h> 74 #include <dev/bwi/bwiphy.h> 75 76 static void bwi_phy_init_11a(struct bwi_mac *); 77 static void bwi_phy_init_11g(struct bwi_mac *); 78 static void bwi_phy_init_11b_rev2(struct bwi_mac *); 79 static void bwi_phy_init_11b_rev4(struct bwi_mac *); 80 static void bwi_phy_init_11b_rev5(struct bwi_mac *); 81 static void bwi_phy_init_11b_rev6(struct bwi_mac *); 82 83 static void bwi_phy_config_11g(struct bwi_mac *); 84 static void bwi_phy_config_agc(struct bwi_mac *); 85 86 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); 87 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); 88 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 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 188 for (i = 0; i < N(bwi_sup_bphy); ++i) { 189 if (phyrev == bwi_sup_bphy[i].rev) { 190 phy->phy_init = bwi_sup_bphy[i].init; 191 break; 192 } 193 } 194 if (i == N(bwi_sup_bphy)) { 195 device_printf(sc->sc_dev, "unsupported 11B PHY, " 196 "rev %u\n", phyrev); 197 return ENXIO; 198 } 199 #undef N 200 phy->phy_mode = IEEE80211_MODE_11B; 201 break; 202 case BWI_PHYINFO_TYPE_11G: 203 if (phyrev > 8) { 204 device_printf(sc->sc_dev, "unsupported 11G PHY, " 205 "rev %u\n", phyrev); 206 return ENXIO; 207 } 208 phy->phy_init = bwi_phy_init_11g; 209 phy->phy_mode = IEEE80211_MODE_11G; 210 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G; 211 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G; 212 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G; 213 break; 214 default: 215 device_printf(sc->sc_dev, "unsupported PHY type %d\n", 216 phytype); 217 return ENXIO; 218 } 219 phy->phy_rev = phyrev; 220 phy->phy_version = phyver; 221 return 0; 222 } 223 224 void 225 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten) 226 { 227 struct bwi_phy *phy = &mac->mac_phy; 228 uint16_t mask = __BITS(3, 0); 229 230 if (phy->phy_version == 0) { 231 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask, 232 __SHIFTIN(bbp_atten, mask)); 233 } else { 234 if (phy->phy_version > 1) 235 mask <<= 2; 236 else 237 mask <<= 3; 238 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask, 239 __SHIFTIN(bbp_atten, mask)); 240 } 241 } 242 243 int 244 bwi_phy_calibrate(struct bwi_mac *mac) 245 { 246 struct bwi_phy *phy = &mac->mac_phy; 247 248 /* Dummy read */ 249 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS); 250 251 /* Don't re-init */ 252 if (phy->phy_flags & BWI_PHY_F_CALIBRATED) 253 return 0; 254 255 if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) { 256 bwi_mac_reset(mac, 0); 257 bwi_phy_init_11g(mac); 258 bwi_mac_reset(mac, 1); 259 } 260 261 phy->phy_flags |= BWI_PHY_F_CALIBRATED; 262 return 0; 263 } 264 265 static void 266 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data) 267 { 268 struct bwi_phy *phy = &mac->mac_phy; 269 270 KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0, 271 ("phy_tbl_ctrl %d phy_tbl_data_lo %d", 272 phy->phy_tbl_ctrl, phy->phy_tbl_data_lo)); 273 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 274 PHY_WRITE(mac, phy->phy_tbl_data_lo, data); 275 } 276 277 static void 278 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data) 279 { 280 struct bwi_phy *phy = &mac->mac_phy; 281 282 KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && 283 phy->phy_tbl_ctrl != 0, 284 ("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d", 285 phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl)); 286 287 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs); 288 PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16); 289 PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff); 290 } 291 292 void 293 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data) 294 { 295 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 296 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data); 297 } 298 299 int16_t 300 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs) 301 { 302 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs); 303 return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA); 304 } 305 306 static void 307 bwi_phy_init_11a(struct bwi_mac *mac) 308 { 309 /* TODO:11A */ 310 } 311 312 static void 313 bwi_phy_init_11g(struct bwi_mac *mac) 314 { 315 struct bwi_softc *sc = mac->mac_sc; 316 struct bwi_phy *phy = &mac->mac_phy; 317 struct bwi_rf *rf = &mac->mac_rf; 318 const struct bwi_tpctl *tpctl = &mac->mac_tpctl; 319 320 if (phy->phy_rev == 1) 321 bwi_phy_init_11b_rev5(mac); 322 else 323 bwi_phy_init_11b_rev6(mac); 324 325 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) 326 bwi_phy_config_11g(mac); 327 328 if (phy->phy_rev >= 2) { 329 PHY_WRITE(mac, 0x814, 0); 330 PHY_WRITE(mac, 0x815, 0); 331 332 if (phy->phy_rev == 2) { 333 PHY_WRITE(mac, 0x811, 0); 334 PHY_WRITE(mac, 0x15, 0xc0); 335 } else if (phy->phy_rev > 5) { 336 PHY_WRITE(mac, 0x811, 0x400); 337 PHY_WRITE(mac, 0x15, 0xc0); 338 } 339 } 340 341 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) { 342 uint16_t val; 343 344 val = PHY_READ(mac, 0x400) & 0xff; 345 if (val == 3 || val == 5) { 346 PHY_WRITE(mac, 0x4c2, 0x1816); 347 PHY_WRITE(mac, 0x4c3, 0x8006); 348 if (val == 5) { 349 PHY_FILT_SETBITS(mac, 0x4cc, 350 0xff, 0x1f00); 351 } 352 } 353 } 354 355 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) || 356 phy->phy_rev >= 2) 357 PHY_WRITE(mac, 0x47e, 0x78); 358 359 if (rf->rf_rev == 8) { 360 PHY_SETBITS(mac, 0x801, 0x80); 361 PHY_SETBITS(mac, 0x43e, 0x4); 362 } 363 364 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) 365 bwi_rf_get_gains(mac); 366 367 if (rf->rf_rev != 8) 368 bwi_rf_init(mac); 369 370 if (tpctl->tp_ctrl2 == 0xffff) { 371 bwi_rf_lo_update(mac); 372 } else { 373 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) { 374 RF_WRITE(mac, 0x52, 375 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2); 376 } else { 377 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2); 378 } 379 380 if (phy->phy_rev >= 6) { 381 PHY_FILT_SETBITS(mac, 0x36, 0xfff, 382 tpctl->tp_ctrl2 << 12); 383 } 384 385 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 386 PHY_WRITE(mac, 0x2e, 0x8075); 387 else 388 PHY_WRITE(mac, 0x2e, 0x807f); 389 390 if (phy->phy_rev < 2) 391 PHY_WRITE(mac, 0x2f, 0x101); 392 else 393 PHY_WRITE(mac, 0x2f, 0x202); 394 } 395 396 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 397 bwi_rf_lo_adjust(mac, tpctl); 398 PHY_WRITE(mac, 0x80f, 0x8078); 399 } 400 401 if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) { 402 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */); 403 bwi_rf_set_nrssi_thr(mac); 404 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 405 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) { 406 KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI, 407 ("rf_nrssi[1] %d", rf->rf_nrssi[1])); 408 bwi_rf_calc_nrssi_slope(mac); 409 } else { 410 KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI, 411 ("rf_nrssi[1] %d", rf->rf_nrssi[1])); 412 bwi_rf_set_nrssi_thr(mac); 413 } 414 } 415 416 if (rf->rf_rev == 8) 417 PHY_WRITE(mac, 0x805, 0x3230); 418 419 bwi_mac_init_tpctl_11bg(mac); 420 421 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) { 422 PHY_CLRBITS(mac, 0x429, 0x4000); 423 PHY_CLRBITS(mac, 0x4c3, 0x8000); 424 } 425 } 426 427 static void 428 bwi_phy_init_11b_rev2(struct bwi_mac *mac) 429 { 430 /* TODO:11B */ 431 if_printf(mac->mac_sc->sc_ifp, 432 "%s is not implemented yet\n", __func__); 433 } 434 435 static void 436 bwi_phy_init_11b_rev4(struct bwi_mac *mac) 437 { 438 struct bwi_softc *sc = mac->mac_sc; 439 struct bwi_rf *rf = &mac->mac_rf; 440 uint16_t val, ofs; 441 u_int chan; 442 443 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 444 445 PHY_WRITE(mac, 0x20, 0x301c); 446 PHY_WRITE(mac, 0x26, 0); 447 PHY_WRITE(mac, 0x30, 0xc6); 448 PHY_WRITE(mac, 0x88, 0x3e00); 449 450 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202) 451 PHY_WRITE(mac, 0x89 + ofs, val); 452 453 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 454 455 chan = rf->rf_curchan; 456 if (chan == IEEE80211_CHAN_ANY) 457 chan = 6; /* Force to channel 6 */ 458 bwi_rf_set_chan(mac, chan, 0); 459 460 if (rf->rf_type != BWI_RF_T_BCM2050) { 461 RF_WRITE(mac, 0x75, 0x80); 462 RF_WRITE(mac, 0x79, 0x81); 463 } 464 465 RF_WRITE(mac, 0x50, 0x20); 466 RF_WRITE(mac, 0x50, 0x23); 467 468 if (rf->rf_type == BWI_RF_T_BCM2050) { 469 RF_WRITE(mac, 0x50, 0x20); 470 RF_WRITE(mac, 0x5a, 0x70); 471 RF_WRITE(mac, 0x5b, 0x7b); 472 RF_WRITE(mac, 0x5c, 0xb0); 473 RF_WRITE(mac, 0x7a, 0xf); 474 PHY_WRITE(mac, 0x38, 0x677); 475 bwi_rf_init_bcm2050(mac); 476 } 477 478 PHY_WRITE(mac, 0x14, 0x80); 479 PHY_WRITE(mac, 0x32, 0xca); 480 if (rf->rf_type == BWI_RF_T_BCM2050) 481 PHY_WRITE(mac, 0x32, 0xe0); 482 PHY_WRITE(mac, 0x35, 0x7c2); 483 484 bwi_rf_lo_update(mac); 485 486 PHY_WRITE(mac, 0x26, 0xcc00); 487 if (rf->rf_type == BWI_RF_T_BCM2050) 488 PHY_WRITE(mac, 0x26, 0xce00); 489 490 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100); 491 492 PHY_WRITE(mac, 0x2a, 0x88a3); 493 if (rf->rf_type == BWI_RF_T_BCM2050) 494 PHY_WRITE(mac, 0x2a, 0x88c2); 495 496 bwi_mac_set_tpctl_11bg(mac, NULL); 497 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 498 bwi_rf_calc_nrssi_slope(mac); 499 bwi_rf_set_nrssi_thr(mac); 500 } 501 bwi_mac_init_tpctl_11bg(mac); 502 } 503 504 static void 505 bwi_phy_init_11b_rev5(struct bwi_mac *mac) 506 { 507 struct bwi_softc *sc = mac->mac_sc; 508 struct bwi_rf *rf = &mac->mac_rf; 509 struct bwi_phy *phy = &mac->mac_phy; 510 u_int orig_chan; 511 512 if (phy->phy_version == 1) 513 RF_SETBITS(mac, 0x7a, 0x50); 514 515 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM && 516 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) { 517 uint16_t ofs, val; 518 519 val = 0x2120; 520 for (ofs = 0xa8; ofs < 0xc7; ++ofs) { 521 PHY_WRITE(mac, ofs, val); 522 val += 0x202; 523 } 524 } 525 526 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700); 527 528 if (rf->rf_type == BWI_RF_T_BCM2050) 529 PHY_WRITE(mac, 0x38, 0x667); 530 531 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) { 532 if (rf->rf_type == BWI_RF_T_BCM2050) { 533 RF_SETBITS(mac, 0x7a, 0x20); 534 RF_SETBITS(mac, 0x51, 0x4); 535 } 536 537 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0); 538 539 PHY_SETBITS(mac, 0x802, 0x100); 540 PHY_SETBITS(mac, 0x42b, 0x2000); 541 PHY_WRITE(mac, 0x1c, 0x186a); 542 543 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900); 544 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64); 545 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa); 546 } 547 548 /* TODO: bad_frame_preempt? */ 549 550 if (phy->phy_version == 1) { 551 PHY_WRITE(mac, 0x26, 0xce00); 552 PHY_WRITE(mac, 0x21, 0x3763); 553 PHY_WRITE(mac, 0x22, 0x1bc3); 554 PHY_WRITE(mac, 0x23, 0x6f9); 555 PHY_WRITE(mac, 0x24, 0x37e); 556 } else { 557 PHY_WRITE(mac, 0x26, 0xcc00); 558 } 559 PHY_WRITE(mac, 0x30, 0xc6); 560 561 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT); 562 563 if (phy->phy_version == 1) 564 PHY_WRITE(mac, 0x20, 0x3e1c); 565 else 566 PHY_WRITE(mac, 0x20, 0x301c); 567 568 if (phy->phy_version == 0) 569 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1); 570 571 /* Force to channel 7 */ 572 orig_chan = rf->rf_curchan; 573 bwi_rf_set_chan(mac, 7, 0); 574 575 if (rf->rf_type != BWI_RF_T_BCM2050) { 576 RF_WRITE(mac, 0x75, 0x80); 577 RF_WRITE(mac, 0x79, 0x81); 578 } 579 580 RF_WRITE(mac, 0x50, 0x20); 581 RF_WRITE(mac, 0x50, 0x23); 582 583 if (rf->rf_type == BWI_RF_T_BCM2050) { 584 RF_WRITE(mac, 0x50, 0x20); 585 RF_WRITE(mac, 0x5a, 0x70); 586 } 587 588 RF_WRITE(mac, 0x5b, 0x7b); 589 RF_WRITE(mac, 0x5c, 0xb0); 590 RF_SETBITS(mac, 0x7a, 0x7); 591 592 bwi_rf_set_chan(mac, orig_chan, 0); 593 594 PHY_WRITE(mac, 0x14, 0x80); 595 PHY_WRITE(mac, 0x32, 0xca); 596 PHY_WRITE(mac, 0x2a, 0x88a3); 597 598 bwi_mac_set_tpctl_11bg(mac, NULL); 599 600 if (rf->rf_type == BWI_RF_T_BCM2050) 601 RF_WRITE(mac, 0x5d, 0xd); 602 603 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4); 604 } 605 606 static void 607 bwi_phy_init_11b_rev6(struct bwi_mac *mac) 608 { 609 struct bwi_softc *sc = mac->mac_sc; 610 struct bwi_rf *rf = &mac->mac_rf; 611 struct bwi_phy *phy = &mac->mac_phy; 612 uint16_t val, ofs; 613 u_int orig_chan; 614 615 PHY_WRITE(mac, 0x3e, 0x817a); 616 RF_SETBITS(mac, 0x7a, 0x58); 617 618 if (rf->rf_rev == 4 || rf->rf_rev == 5) { 619 RF_WRITE(mac, 0x51, 0x37); 620 RF_WRITE(mac, 0x52, 0x70); 621 RF_WRITE(mac, 0x53, 0xb3); 622 RF_WRITE(mac, 0x54, 0x9b); 623 RF_WRITE(mac, 0x5a, 0x88); 624 RF_WRITE(mac, 0x5b, 0x88); 625 RF_WRITE(mac, 0x5d, 0x88); 626 RF_WRITE(mac, 0x5e, 0x88); 627 RF_WRITE(mac, 0x7d, 0x88); 628 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1); 629 } else if (rf->rf_rev == 8) { 630 RF_WRITE(mac, 0x51, 0); 631 RF_WRITE(mac, 0x52, 0x40); 632 RF_WRITE(mac, 0x53, 0xb7); 633 RF_WRITE(mac, 0x54, 0x98); 634 RF_WRITE(mac, 0x5a, 0x88); 635 RF_WRITE(mac, 0x5b, 0x6b); 636 RF_WRITE(mac, 0x5c, 0xf); 637 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) { 638 RF_WRITE(mac, 0x5d, 0xfa); 639 RF_WRITE(mac, 0x5e, 0xd8); 640 } else { 641 RF_WRITE(mac, 0x5d, 0xf5); 642 RF_WRITE(mac, 0x5e, 0xb8); 643 } 644 RF_WRITE(mac, 0x73, 0x3); 645 RF_WRITE(mac, 0x7d, 0xa8); 646 RF_WRITE(mac, 0x7c, 0x1); 647 RF_WRITE(mac, 0x7e, 0x8); 648 } 649 650 val = 0x1e1f; 651 for (ofs = 0x88; ofs < 0x98; ++ofs) { 652 PHY_WRITE(mac, ofs, val); 653 val -= 0x202; 654 } 655 656 val = 0x3e3f; 657 for (ofs = 0x98; ofs < 0xa8; ++ofs) { 658 PHY_WRITE(mac, ofs, val); 659 val -= 0x202; 660 } 661 662 val = 0x2120; 663 for (ofs = 0xa8; ofs < 0xc8; ++ofs) { 664 PHY_WRITE(mac, ofs, (val & 0x3f3f)); 665 val += 0x202; 666 667 /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */ 668 DELAY(10); 669 } 670 671 if (phy->phy_mode == IEEE80211_MODE_11G) { 672 RF_SETBITS(mac, 0x7a, 0x20); 673 RF_SETBITS(mac, 0x51, 0x4); 674 PHY_SETBITS(mac, 0x802, 0x100); 675 PHY_SETBITS(mac, 0x42b, 0x2000); 676 PHY_WRITE(mac, 0x5b, 0); 677 PHY_WRITE(mac, 0x5c, 0); 678 } 679 680 /* Force to channel 7 */ 681 orig_chan = rf->rf_curchan; 682 if (orig_chan >= 8) 683 bwi_rf_set_chan(mac, 1, 0); 684 else 685 bwi_rf_set_chan(mac, 13, 0); 686 687 RF_WRITE(mac, 0x50, 0x20); 688 RF_WRITE(mac, 0x50, 0x23); 689 690 DELAY(40); 691 692 if (rf->rf_rev < 6 || rf->rf_rev == 8) { 693 RF_SETBITS(mac, 0x7c, 0x2); 694 RF_WRITE(mac, 0x50, 0x20); 695 } 696 if (rf->rf_rev <= 2) { 697 RF_WRITE(mac, 0x7c, 0x20); 698 RF_WRITE(mac, 0x5a, 0x70); 699 RF_WRITE(mac, 0x5b, 0x7b); 700 RF_WRITE(mac, 0x5c, 0xb0); 701 } 702 703 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7); 704 705 bwi_rf_set_chan(mac, orig_chan, 0); 706 707 PHY_WRITE(mac, 0x14, 0x200); 708 if (rf->rf_rev >= 6) 709 PHY_WRITE(mac, 0x2a, 0x88c2); 710 else 711 PHY_WRITE(mac, 0x2a, 0x8ac0); 712 PHY_WRITE(mac, 0x38, 0x668); 713 714 bwi_mac_set_tpctl_11bg(mac, NULL); 715 716 if (rf->rf_rev <= 5) { 717 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3); 718 if (rf->rf_rev <= 2) 719 RF_WRITE(mac, 0x5d, 0xd); 720 } 721 722 if (phy->phy_version == 4) { 723 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2); 724 PHY_CLRBITS(mac, 0x61, 0xf000); 725 } else { 726 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4); 727 } 728 729 if (phy->phy_mode == IEEE80211_MODE_11B) { 730 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2); 731 PHY_WRITE(mac, 0x16, 0x410); 732 PHY_WRITE(mac, 0x17, 0x820); 733 PHY_WRITE(mac, 0x62, 0x7); 734 735 bwi_rf_init_bcm2050(mac); 736 bwi_rf_lo_update(mac); 737 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) { 738 bwi_rf_calc_nrssi_slope(mac); 739 bwi_rf_set_nrssi_thr(mac); 740 } 741 bwi_mac_init_tpctl_11bg(mac); 742 } else { 743 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); 744 } 745 } 746 747 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 748 749 static void 750 bwi_phy_config_11g(struct bwi_mac *mac) 751 { 752 struct bwi_softc *sc = mac->mac_sc; 753 struct bwi_phy *phy = &mac->mac_phy; 754 const uint16_t *tbl; 755 uint16_t wrd_ofs1, wrd_ofs2; 756 int i, n; 757 758 if (phy->phy_rev == 1) { 759 PHY_WRITE(mac, 0x406, 0x4f19); 760 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340); 761 PHY_WRITE(mac, 0x42c, 0x5a); 762 PHY_WRITE(mac, 0x427, 0x1a); 763 764 /* Fill frequency table */ 765 for (i = 0; i < N(bwi_phy_freq_11g_rev1); ++i) { 766 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i, 767 bwi_phy_freq_11g_rev1[i]); 768 } 769 770 /* Fill noise table */ 771 for (i = 0; i < N(bwi_phy_noise_11g_rev1); ++i) { 772 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 773 bwi_phy_noise_11g_rev1[i]); 774 } 775 776 /* Fill rotor table */ 777 for (i = 0; i < N(bwi_phy_rotor_11g_rev1); ++i) { 778 /* NB: data length is 4 bytes */ 779 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i, 780 bwi_phy_rotor_11g_rev1[i]); 781 } 782 } else { 783 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */ 784 785 if (phy->phy_rev == 2) { 786 PHY_WRITE(mac, 0x4c0, 0x1861); 787 PHY_WRITE(mac, 0x4c1, 0x271); 788 } else if (phy->phy_rev > 2) { 789 PHY_WRITE(mac, 0x4c0, 0x98); 790 PHY_WRITE(mac, 0x4c1, 0x70); 791 PHY_WRITE(mac, 0x4c9, 0x80); 792 } 793 PHY_SETBITS(mac, 0x42b, 0x800); 794 795 /* Fill RSSI table */ 796 for (i = 0; i < 64; ++i) 797 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i); 798 799 /* Fill noise table */ 800 for (i = 0; i < N(bwi_phy_noise_11g); ++i) { 801 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, 802 bwi_phy_noise_11g[i]); 803 } 804 } 805 806 /* 807 * Fill noise scale table 808 */ 809 if (phy->phy_rev <= 2) { 810 tbl = bwi_phy_noise_scale_11g_rev2; 811 n = N(bwi_phy_noise_scale_11g_rev2); 812 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) { 813 tbl = bwi_phy_noise_scale_11g_rev7; 814 n = N(bwi_phy_noise_scale_11g_rev7); 815 } else { 816 tbl = bwi_phy_noise_scale_11g; 817 n = N(bwi_phy_noise_scale_11g); 818 } 819 for (i = 0; i < n; ++i) 820 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]); 821 822 /* 823 * Fill sigma square table 824 */ 825 if (phy->phy_rev == 2) { 826 tbl = bwi_phy_sigma_sq_11g_rev2; 827 n = N(bwi_phy_sigma_sq_11g_rev2); 828 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) { 829 tbl = bwi_phy_sigma_sq_11g_rev7; 830 n = N(bwi_phy_sigma_sq_11g_rev7); 831 } else { 832 tbl = NULL; 833 n = 0; 834 } 835 for (i = 0; i < n; ++i) 836 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]); 837 838 if (phy->phy_rev == 1) { 839 /* Fill delay table */ 840 for (i = 0; i < N(bwi_phy_delay_11g_rev1); ++i) { 841 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i, 842 bwi_phy_delay_11g_rev1[i]); 843 } 844 845 /* Fill WRSSI (Wide-Band RSSI) table */ 846 for (i = 4; i < 20; ++i) 847 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20); 848 849 bwi_phy_config_agc(mac); 850 851 wrd_ofs1 = 0x5001; 852 wrd_ofs2 = 0x5002; 853 } else { 854 /* Fill WRSSI (Wide-Band RSSI) table */ 855 for (i = 0; i < 0x20; ++i) 856 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820); 857 858 bwi_phy_config_agc(mac); 859 860 PHY_READ(mac, 0x400); /* Dummy read */ 861 PHY_WRITE(mac, 0x403, 0x1000); 862 bwi_tbl_write_2(mac, 0x3c02, 0xf); 863 bwi_tbl_write_2(mac, 0x3c03, 0x14); 864 865 wrd_ofs1 = 0x401; 866 wrd_ofs2 = 0x402; 867 } 868 869 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) { 870 bwi_tbl_write_2(mac, wrd_ofs1, 0x2); 871 bwi_tbl_write_2(mac, wrd_ofs2, 0x1); 872 } 873 874 /* phy->phy_flags & BWI_PHY_F_LINKED ? */ 875 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) 876 PHY_WRITE(mac, 0x46e, 0x3cf); 877 } 878 879 #undef N 880 881 /* 882 * Configure Automatic Gain Controller 883 */ 884 static void 885 bwi_phy_config_agc(struct bwi_mac *mac) 886 { 887 struct bwi_phy *phy = &mac->mac_phy; 888 uint16_t ofs; 889 890 ofs = phy->phy_rev == 1 ? 0x4c00 : 0; 891 892 bwi_tbl_write_2(mac, ofs, 0xfe); 893 bwi_tbl_write_2(mac, ofs + 1, 0xd); 894 bwi_tbl_write_2(mac, ofs + 2, 0x13); 895 bwi_tbl_write_2(mac, ofs + 3, 0x19); 896 897 if (phy->phy_rev == 1) { 898 bwi_tbl_write_2(mac, 0x1800, 0x2710); 899 bwi_tbl_write_2(mac, 0x1801, 0x9b83); 900 bwi_tbl_write_2(mac, 0x1802, 0x9b83); 901 bwi_tbl_write_2(mac, 0x1803, 0xf8d); 902 PHY_WRITE(mac, 0x455, 0x4); 903 } 904 905 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700); 906 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf); 907 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80); 908 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300); 909 910 RF_SETBITS(mac, 0x7a, 0x8); 911 912 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8); 913 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600); 914 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700); 915 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100); 916 917 if (phy->phy_rev == 1) 918 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7); 919 920 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c); 921 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200); 922 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c); 923 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20); 924 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200); 925 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e); 926 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00); 927 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28); 928 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00); 929 930 if (phy->phy_rev == 1) { 931 PHY_WRITE(mac, 0x430, 0x92b); 932 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2); 933 } else { 934 PHY_CLRBITS(mac, 0x41b, 0x1e); 935 PHY_WRITE(mac, 0x41f, 0x287a); 936 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4); 937 938 if (phy->phy_rev >= 6) { 939 PHY_WRITE(mac, 0x422, 0x287a); 940 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000); 941 } 942 } 943 944 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874); 945 PHY_WRITE(mac, 0x48e, 0x1c00); 946 947 if (phy->phy_rev == 1) { 948 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600); 949 PHY_WRITE(mac, 0x48b, 0x5e); 950 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e); 951 PHY_WRITE(mac, 0x48d, 0x2); 952 } 953 954 bwi_tbl_write_2(mac, ofs + 0x800, 0); 955 bwi_tbl_write_2(mac, ofs + 0x801, 7); 956 bwi_tbl_write_2(mac, ofs + 0x802, 16); 957 bwi_tbl_write_2(mac, ofs + 0x803, 28); 958 959 if (phy->phy_rev >= 6) { 960 PHY_CLRBITS(mac, 0x426, 0x3); 961 PHY_CLRBITS(mac, 0x426, 0x1000); 962 } 963 } 964 965 void 966 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains) 967 { 968 struct bwi_phy *phy = &mac->mac_phy; 969 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain; 970 int i; 971 972 if (phy->phy_rev <= 1) { 973 tbl_gain_ofs1 = 0x5000; 974 tbl_gain_ofs2 = tbl_gain_ofs1 + 16; 975 } else { 976 tbl_gain_ofs1 = 0x400; 977 tbl_gain_ofs2 = tbl_gain_ofs1 + 8; 978 } 979 980 for (i = 0; i < 4; ++i) { 981 if (gains != NULL) { 982 tbl_gain = gains->tbl_gain1; 983 } else { 984 /* Bit swap */ 985 tbl_gain = (i & 0x1) << 1; 986 tbl_gain |= (i & 0x2) >> 1; 987 } 988 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain); 989 } 990 991 for (i = 0; i < 16; ++i) { 992 if (gains != NULL) 993 tbl_gain = gains->tbl_gain2; 994 else 995 tbl_gain = i; 996 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain); 997 } 998 999 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) { 1000 uint16_t phy_gain1, phy_gain2; 1001 1002 if (gains != NULL) { 1003 phy_gain1 = 1004 ((uint16_t)gains->phy_gain << 14) | 1005 ((uint16_t)gains->phy_gain << 6); 1006 phy_gain2 = phy_gain1; 1007 } else { 1008 phy_gain1 = 0x4040; 1009 phy_gain2 = 0x4000; 1010 } 1011 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1); 1012 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1); 1013 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2); 1014 } 1015 bwi_mac_dummy_xmit(mac); 1016 } 1017 1018 void 1019 bwi_phy_clear_state(struct bwi_phy *phy) 1020 { 1021 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS; 1022 } 1023