2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
6 * This code is derived from software contributed to The DragonFly Project
7 * by Sepherosa Ziehau <sepherosa@gmail.com>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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.
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
36 * $DragonFly: src/sys/dev/netif/bwi/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
45 #include <sys/param.h>
46 #include <sys/endian.h>
47 #include <sys/kernel.h>
49 #include <sys/malloc.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/sysctl.h>
55 #include <sys/systm.h>
58 #include <net/if_var.h>
59 #include <net/if_dl.h>
60 #include <net/if_media.h>
61 #include <net/if_types.h>
62 #include <net/if_arp.h>
63 #include <net/ethernet.h>
64 #include <net/if_llc.h>
66 #include <net80211/ieee80211_var.h>
67 #include <net80211/ieee80211_radiotap.h>
68 #include <net80211/ieee80211_amrr.h>
70 #include <machine/bus.h>
72 #include <dev/bwi/bitops.h>
73 #include <dev/bwi/if_bwireg.h>
74 #include <dev/bwi/if_bwivar.h>
75 #include <dev/bwi/bwimac.h>
76 #include <dev/bwi/bwirf.h>
77 #include <dev/bwi/bwiphy.h>
79 static void bwi_phy_init_11a(struct bwi_mac *);
80 static void bwi_phy_init_11g(struct bwi_mac *);
81 static void bwi_phy_init_11b_rev2(struct bwi_mac *);
82 static void bwi_phy_init_11b_rev4(struct bwi_mac *);
83 static void bwi_phy_init_11b_rev5(struct bwi_mac *);
84 static void bwi_phy_init_11b_rev6(struct bwi_mac *);
86 static void bwi_phy_config_11g(struct bwi_mac *);
87 static void bwi_phy_config_agc(struct bwi_mac *);
89 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
90 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
91 #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
95 void (*init)(struct bwi_mac *);
105 #define BWI_PHYTBL_WRSSI 0x1000
106 #define BWI_PHYTBL_NOISE_SCALE 0x1400
107 #define BWI_PHYTBL_NOISE 0x1800
108 #define BWI_PHYTBL_ROTOR 0x2000
109 #define BWI_PHYTBL_DELAY 0x2400
110 #define BWI_PHYTBL_RSSI 0x4000
111 #define BWI_PHYTBL_SIGMA_SQ 0x5000
112 #define BWI_PHYTBL_WRSSI_REV1 0x5400
113 #define BWI_PHYTBL_FREQ 0x5800
115 static const uint16_t bwi_phy_freq_11g_rev1[] =
116 { BWI_PHY_FREQ_11G_REV1 };
117 static const uint16_t bwi_phy_noise_11g_rev1[] =
118 { BWI_PHY_NOISE_11G_REV1 };
119 static const uint16_t bwi_phy_noise_11g[] =
120 { BWI_PHY_NOISE_11G };
121 static const uint32_t bwi_phy_rotor_11g_rev1[] =
122 { BWI_PHY_ROTOR_11G_REV1 };
123 static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
124 { BWI_PHY_NOISE_SCALE_11G_REV2 };
125 static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
126 { BWI_PHY_NOISE_SCALE_11G_REV7 };
127 static const uint16_t bwi_phy_noise_scale_11g[] =
128 { BWI_PHY_NOISE_SCALE_11G };
129 static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
130 { BWI_PHY_SIGMA_SQ_11G_REV2 };
131 static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
132 { BWI_PHY_SIGMA_SQ_11G_REV7 };
133 static const uint32_t bwi_phy_delay_11g_rev1[] =
134 { BWI_PHY_DELAY_11G_REV1 };
137 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
139 struct bwi_softc *sc = mac->mac_sc;
141 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
142 CSR_WRITE_2(sc, BWI_PHY_DATA, data);
146 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
148 struct bwi_softc *sc = mac->mac_sc;
150 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
151 return CSR_READ_2(sc, BWI_PHY_DATA);
155 bwi_phy_attach(struct bwi_mac *mac)
157 struct bwi_softc *sc = mac->mac_sc;
158 struct bwi_phy *phy = &mac->mac_phy;
159 uint8_t phyrev, phytype, phyver;
163 /* Get PHY type/revision/version */
164 val = CSR_READ_2(sc, BWI_PHYINFO);
165 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
166 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
167 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
168 device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
169 phytype, phyrev, phyver);
172 * Verify whether the revision of the PHY type is supported
173 * Convert PHY type to ieee80211_phymode
176 case BWI_PHYINFO_TYPE_11A:
178 device_printf(sc->sc_dev, "unsupported 11A PHY, "
182 phy->phy_init = bwi_phy_init_11a;
183 phy->phy_mode = IEEE80211_MODE_11A;
184 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
185 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
186 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
188 case BWI_PHYINFO_TYPE_11B:
189 for (i = 0; i < nitems(bwi_sup_bphy); ++i) {
190 if (phyrev == bwi_sup_bphy[i].rev) {
191 phy->phy_init = bwi_sup_bphy[i].init;
195 if (i == nitems(bwi_sup_bphy)) {
196 device_printf(sc->sc_dev, "unsupported 11B PHY, "
200 phy->phy_mode = IEEE80211_MODE_11B;
202 case BWI_PHYINFO_TYPE_11G:
204 device_printf(sc->sc_dev, "unsupported 11G PHY, "
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;
215 device_printf(sc->sc_dev, "unsupported PHY type %d\n",
219 phy->phy_rev = phyrev;
220 phy->phy_version = phyver;
225 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
227 struct bwi_phy *phy = &mac->mac_phy;
228 uint16_t mask = __BITS(3, 0);
230 if (phy->phy_version == 0) {
231 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
232 __SHIFTIN(bbp_atten, mask));
234 if (phy->phy_version > 1)
238 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
239 __SHIFTIN(bbp_atten, mask));
244 bwi_phy_calibrate(struct bwi_mac *mac)
246 struct bwi_phy *phy = &mac->mac_phy;
249 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
252 if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
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);
261 phy->phy_flags |= BWI_PHY_F_CALIBRATED;
266 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
268 struct bwi_phy *phy = &mac->mac_phy;
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);
278 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
280 struct bwi_phy *phy = &mac->mac_phy;
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));
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);
293 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
295 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
296 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
300 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
302 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
303 return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
307 bwi_phy_init_11a(struct bwi_mac *mac)
313 bwi_phy_init_11g(struct bwi_mac *mac)
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;
320 if (phy->phy_rev == 1)
321 bwi_phy_init_11b_rev5(mac);
323 bwi_phy_init_11b_rev6(mac);
325 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
326 bwi_phy_config_11g(mac);
328 if (phy->phy_rev >= 2) {
329 PHY_WRITE(mac, 0x814, 0);
330 PHY_WRITE(mac, 0x815, 0);
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);
341 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
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);
349 PHY_FILT_SETBITS(mac, 0x4cc,
355 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
357 PHY_WRITE(mac, 0x47e, 0x78);
359 if (rf->rf_rev == 8) {
360 PHY_SETBITS(mac, 0x801, 0x80);
361 PHY_SETBITS(mac, 0x43e, 0x4);
364 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
365 bwi_rf_get_gains(mac);
370 if (tpctl->tp_ctrl2 == 0xffff) {
371 bwi_rf_lo_update(mac);
373 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
375 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
377 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
380 if (phy->phy_rev >= 6) {
381 PHY_FILT_SETBITS(mac, 0x36, 0xfff,
382 tpctl->tp_ctrl2 << 12);
385 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
386 PHY_WRITE(mac, 0x2e, 0x8075);
388 PHY_WRITE(mac, 0x2e, 0x807f);
390 if (phy->phy_rev < 2)
391 PHY_WRITE(mac, 0x2f, 0x101);
393 PHY_WRITE(mac, 0x2f, 0x202);
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);
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);
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);
417 PHY_WRITE(mac, 0x805, 0x3230);
419 bwi_mac_init_tpctl_11bg(mac);
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);
428 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
431 device_printf(mac->mac_sc->sc_dev,
432 "%s is not implemented yet\n", __func__);
436 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
438 struct bwi_softc *sc = mac->mac_sc;
439 struct bwi_rf *rf = &mac->mac_rf;
443 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
445 PHY_WRITE(mac, 0x20, 0x301c);
446 PHY_WRITE(mac, 0x26, 0);
447 PHY_WRITE(mac, 0x30, 0xc6);
448 PHY_WRITE(mac, 0x88, 0x3e00);
450 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
451 PHY_WRITE(mac, 0x89 + ofs, val);
453 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
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);
460 if (rf->rf_type != BWI_RF_T_BCM2050) {
461 RF_WRITE(mac, 0x75, 0x80);
462 RF_WRITE(mac, 0x79, 0x81);
465 RF_WRITE(mac, 0x50, 0x20);
466 RF_WRITE(mac, 0x50, 0x23);
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);
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);
484 bwi_rf_lo_update(mac);
486 PHY_WRITE(mac, 0x26, 0xcc00);
487 if (rf->rf_type == BWI_RF_T_BCM2050)
488 PHY_WRITE(mac, 0x26, 0xce00);
490 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
492 PHY_WRITE(mac, 0x2a, 0x88a3);
493 if (rf->rf_type == BWI_RF_T_BCM2050)
494 PHY_WRITE(mac, 0x2a, 0x88c2);
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);
501 bwi_mac_init_tpctl_11bg(mac);
505 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
507 struct bwi_softc *sc = mac->mac_sc;
508 struct bwi_rf *rf = &mac->mac_rf;
509 struct bwi_phy *phy = &mac->mac_phy;
512 if (phy->phy_version == 1)
513 RF_SETBITS(mac, 0x7a, 0x50);
515 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
516 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
520 for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
521 PHY_WRITE(mac, ofs, val);
526 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
528 if (rf->rf_type == BWI_RF_T_BCM2050)
529 PHY_WRITE(mac, 0x38, 0x667);
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);
537 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
539 PHY_SETBITS(mac, 0x802, 0x100);
540 PHY_SETBITS(mac, 0x42b, 0x2000);
541 PHY_WRITE(mac, 0x1c, 0x186a);
543 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
544 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
545 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
548 /* TODO: bad_frame_preempt? */
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);
557 PHY_WRITE(mac, 0x26, 0xcc00);
559 PHY_WRITE(mac, 0x30, 0xc6);
561 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
563 if (phy->phy_version == 1)
564 PHY_WRITE(mac, 0x20, 0x3e1c);
566 PHY_WRITE(mac, 0x20, 0x301c);
568 if (phy->phy_version == 0)
569 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
571 /* Force to channel 7 */
572 orig_chan = rf->rf_curchan;
573 bwi_rf_set_chan(mac, 7, 0);
575 if (rf->rf_type != BWI_RF_T_BCM2050) {
576 RF_WRITE(mac, 0x75, 0x80);
577 RF_WRITE(mac, 0x79, 0x81);
580 RF_WRITE(mac, 0x50, 0x20);
581 RF_WRITE(mac, 0x50, 0x23);
583 if (rf->rf_type == BWI_RF_T_BCM2050) {
584 RF_WRITE(mac, 0x50, 0x20);
585 RF_WRITE(mac, 0x5a, 0x70);
588 RF_WRITE(mac, 0x5b, 0x7b);
589 RF_WRITE(mac, 0x5c, 0xb0);
590 RF_SETBITS(mac, 0x7a, 0x7);
592 bwi_rf_set_chan(mac, orig_chan, 0);
594 PHY_WRITE(mac, 0x14, 0x80);
595 PHY_WRITE(mac, 0x32, 0xca);
596 PHY_WRITE(mac, 0x2a, 0x88a3);
598 bwi_mac_set_tpctl_11bg(mac, NULL);
600 if (rf->rf_type == BWI_RF_T_BCM2050)
601 RF_WRITE(mac, 0x5d, 0xd);
603 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
607 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
609 struct bwi_softc *sc = mac->mac_sc;
610 struct bwi_rf *rf = &mac->mac_rf;
611 struct bwi_phy *phy = &mac->mac_phy;
615 PHY_WRITE(mac, 0x3e, 0x817a);
616 RF_SETBITS(mac, 0x7a, 0x58);
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);
641 RF_WRITE(mac, 0x5d, 0xf5);
642 RF_WRITE(mac, 0x5e, 0xb8);
644 RF_WRITE(mac, 0x73, 0x3);
645 RF_WRITE(mac, 0x7d, 0xa8);
646 RF_WRITE(mac, 0x7c, 0x1);
647 RF_WRITE(mac, 0x7e, 0x8);
651 for (ofs = 0x88; ofs < 0x98; ++ofs) {
652 PHY_WRITE(mac, ofs, val);
657 for (ofs = 0x98; ofs < 0xa8; ++ofs) {
658 PHY_WRITE(mac, ofs, val);
663 for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
664 PHY_WRITE(mac, ofs, (val & 0x3f3f));
667 /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */
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);
680 /* Force to channel 7 */
681 orig_chan = rf->rf_curchan;
683 bwi_rf_set_chan(mac, 1, 0);
685 bwi_rf_set_chan(mac, 13, 0);
687 RF_WRITE(mac, 0x50, 0x20);
688 RF_WRITE(mac, 0x50, 0x23);
692 if (rf->rf_rev < 6 || rf->rf_rev == 8) {
693 RF_SETBITS(mac, 0x7c, 0x2);
694 RF_WRITE(mac, 0x50, 0x20);
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);
703 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
705 bwi_rf_set_chan(mac, orig_chan, 0);
707 PHY_WRITE(mac, 0x14, 0x200);
709 PHY_WRITE(mac, 0x2a, 0x88c2);
711 PHY_WRITE(mac, 0x2a, 0x8ac0);
712 PHY_WRITE(mac, 0x38, 0x668);
714 bwi_mac_set_tpctl_11bg(mac, NULL);
716 if (rf->rf_rev <= 5) {
717 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
719 RF_WRITE(mac, 0x5d, 0xd);
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);
726 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
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);
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);
741 bwi_mac_init_tpctl_11bg(mac);
743 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
748 bwi_phy_config_11g(struct bwi_mac *mac)
750 struct bwi_softc *sc = mac->mac_sc;
751 struct bwi_phy *phy = &mac->mac_phy;
753 uint16_t wrd_ofs1, wrd_ofs2;
756 if (phy->phy_rev == 1) {
757 PHY_WRITE(mac, 0x406, 0x4f19);
758 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
759 PHY_WRITE(mac, 0x42c, 0x5a);
760 PHY_WRITE(mac, 0x427, 0x1a);
762 /* Fill frequency table */
763 for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) {
764 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
765 bwi_phy_freq_11g_rev1[i]);
768 /* Fill noise table */
769 for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) {
770 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
771 bwi_phy_noise_11g_rev1[i]);
774 /* Fill rotor table */
775 for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) {
776 /* NB: data length is 4 bytes */
777 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
778 bwi_phy_rotor_11g_rev1[i]);
781 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
783 if (phy->phy_rev == 2) {
784 PHY_WRITE(mac, 0x4c0, 0x1861);
785 PHY_WRITE(mac, 0x4c1, 0x271);
786 } else if (phy->phy_rev > 2) {
787 PHY_WRITE(mac, 0x4c0, 0x98);
788 PHY_WRITE(mac, 0x4c1, 0x70);
789 PHY_WRITE(mac, 0x4c9, 0x80);
791 PHY_SETBITS(mac, 0x42b, 0x800);
793 /* Fill RSSI table */
794 for (i = 0; i < 64; ++i)
795 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
797 /* Fill noise table */
798 for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) {
799 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
800 bwi_phy_noise_11g[i]);
805 * Fill noise scale table
807 if (phy->phy_rev <= 2) {
808 tbl = bwi_phy_noise_scale_11g_rev2;
809 n = nitems(bwi_phy_noise_scale_11g_rev2);
810 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
811 tbl = bwi_phy_noise_scale_11g_rev7;
812 n = nitems(bwi_phy_noise_scale_11g_rev7);
814 tbl = bwi_phy_noise_scale_11g;
815 n = nitems(bwi_phy_noise_scale_11g);
817 for (i = 0; i < n; ++i)
818 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
821 * Fill sigma square table
823 if (phy->phy_rev == 2) {
824 tbl = bwi_phy_sigma_sq_11g_rev2;
825 n = nitems(bwi_phy_sigma_sq_11g_rev2);
826 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
827 tbl = bwi_phy_sigma_sq_11g_rev7;
828 n = nitems(bwi_phy_sigma_sq_11g_rev7);
833 for (i = 0; i < n; ++i)
834 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
836 if (phy->phy_rev == 1) {
837 /* Fill delay table */
838 for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) {
839 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
840 bwi_phy_delay_11g_rev1[i]);
843 /* Fill WRSSI (Wide-Band RSSI) table */
844 for (i = 4; i < 20; ++i)
845 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
847 bwi_phy_config_agc(mac);
852 /* Fill WRSSI (Wide-Band RSSI) table */
853 for (i = 0; i < 0x20; ++i)
854 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
856 bwi_phy_config_agc(mac);
858 PHY_READ(mac, 0x400); /* Dummy read */
859 PHY_WRITE(mac, 0x403, 0x1000);
860 bwi_tbl_write_2(mac, 0x3c02, 0xf);
861 bwi_tbl_write_2(mac, 0x3c03, 0x14);
867 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
868 bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
869 bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
872 /* phy->phy_flags & BWI_PHY_F_LINKED ? */
873 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
874 PHY_WRITE(mac, 0x46e, 0x3cf);
878 * Configure Automatic Gain Controller
881 bwi_phy_config_agc(struct bwi_mac *mac)
883 struct bwi_phy *phy = &mac->mac_phy;
886 ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
888 bwi_tbl_write_2(mac, ofs, 0xfe);
889 bwi_tbl_write_2(mac, ofs + 1, 0xd);
890 bwi_tbl_write_2(mac, ofs + 2, 0x13);
891 bwi_tbl_write_2(mac, ofs + 3, 0x19);
893 if (phy->phy_rev == 1) {
894 bwi_tbl_write_2(mac, 0x1800, 0x2710);
895 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
896 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
897 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
898 PHY_WRITE(mac, 0x455, 0x4);
901 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
902 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
903 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
904 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
906 RF_SETBITS(mac, 0x7a, 0x8);
908 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
909 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
910 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
911 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
913 if (phy->phy_rev == 1)
914 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
916 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
917 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
918 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
919 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
920 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
921 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
922 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
923 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
924 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
926 if (phy->phy_rev == 1) {
927 PHY_WRITE(mac, 0x430, 0x92b);
928 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
930 PHY_CLRBITS(mac, 0x41b, 0x1e);
931 PHY_WRITE(mac, 0x41f, 0x287a);
932 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
934 if (phy->phy_rev >= 6) {
935 PHY_WRITE(mac, 0x422, 0x287a);
936 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
940 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
941 PHY_WRITE(mac, 0x48e, 0x1c00);
943 if (phy->phy_rev == 1) {
944 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
945 PHY_WRITE(mac, 0x48b, 0x5e);
946 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
947 PHY_WRITE(mac, 0x48d, 0x2);
950 bwi_tbl_write_2(mac, ofs + 0x800, 0);
951 bwi_tbl_write_2(mac, ofs + 0x801, 7);
952 bwi_tbl_write_2(mac, ofs + 0x802, 16);
953 bwi_tbl_write_2(mac, ofs + 0x803, 28);
955 if (phy->phy_rev >= 6) {
956 PHY_CLRBITS(mac, 0x426, 0x3);
957 PHY_CLRBITS(mac, 0x426, 0x1000);
962 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
964 struct bwi_phy *phy = &mac->mac_phy;
965 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
968 if (phy->phy_rev <= 1) {
969 tbl_gain_ofs1 = 0x5000;
970 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
972 tbl_gain_ofs1 = 0x400;
973 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
976 for (i = 0; i < 4; ++i) {
978 tbl_gain = gains->tbl_gain1;
981 tbl_gain = (i & 0x1) << 1;
982 tbl_gain |= (i & 0x2) >> 1;
984 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
987 for (i = 0; i < 16; ++i) {
989 tbl_gain = gains->tbl_gain2;
992 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
995 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
996 uint16_t phy_gain1, phy_gain2;
1000 ((uint16_t)gains->phy_gain << 14) |
1001 ((uint16_t)gains->phy_gain << 6);
1002 phy_gain2 = phy_gain1;
1007 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1008 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1009 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1011 bwi_mac_dummy_xmit(mac);
1015 bwi_phy_clear_state(struct bwi_phy *phy)
1017 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;