linprocfs - Introduce /proc/mounts
[dragonfly.git] / sys / dev / netif / bwi / bwiphy.c
blobdc57f26f29dd000f3081a4d41f7a55ba7e5fef41
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:
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.
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.
34 * $DragonFly: src/sys/dev/netif/bwi/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/bitops.h>
39 #include <sys/endian.h>
40 #include <sys/kernel.h>
41 #include <sys/bus.h>
42 #include <sys/malloc.h>
43 #include <sys/proc.h>
44 #include <sys/rman.h>
45 #include <sys/serialize.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 #include <sys/sysctl.h>
50 #include <net/ethernet.h>
51 #include <net/if.h>
52 #include <net/bpf.h>
53 #include <net/if_arp.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/ifq_var.h>
58 #include <netproto/802_11/ieee80211_radiotap.h>
59 #include <netproto/802_11/ieee80211_var.h>
60 #include <netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcidevs.h>
66 #include <dev/netif/bwi/if_bwireg.h>
67 #include <dev/netif/bwi/if_bwivar.h>
68 #include <dev/netif/bwi/bwirf.h>
69 #include <dev/netif/bwi/bwiphy.h>
70 #include <dev/netif/bwi/bwimac.h>
72 static void bwi_phy_init_11a(struct bwi_mac *);
73 static void bwi_phy_init_11g(struct bwi_mac *);
74 static void bwi_phy_init_11b_rev2(struct bwi_mac *);
75 static void bwi_phy_init_11b_rev4(struct bwi_mac *);
76 static void bwi_phy_init_11b_rev5(struct bwi_mac *);
77 static void bwi_phy_init_11b_rev6(struct bwi_mac *);
79 static void bwi_phy_config_11g(struct bwi_mac *);
80 static void bwi_phy_config_agc(struct bwi_mac *);
82 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
83 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
85 #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
87 static const struct {
88 uint8_t rev;
89 void (*init)(struct bwi_mac *);
90 } bwi_sup_bphy[] = {
91 SUP_BPHY(2),
92 SUP_BPHY(4),
93 SUP_BPHY(5),
94 SUP_BPHY(6)
97 #undef SUP_BPHY
99 #define BWI_PHYTBL_WRSSI 0x1000
100 #define BWI_PHYTBL_NOISE_SCALE 0x1400
101 #define BWI_PHYTBL_NOISE 0x1800
102 #define BWI_PHYTBL_ROTOR 0x2000
103 #define BWI_PHYTBL_DELAY 0x2400
104 #define BWI_PHYTBL_RSSI 0x4000
105 #define BWI_PHYTBL_SIGMA_SQ 0x5000
106 #define BWI_PHYTBL_WRSSI_REV1 0x5400
107 #define BWI_PHYTBL_FREQ 0x5800
109 static const uint16_t bwi_phy_freq_11g_rev1[] =
110 { BWI_PHY_FREQ_11G_REV1 };
111 static const uint16_t bwi_phy_noise_11g_rev1[] =
112 { BWI_PHY_NOISE_11G_REV1 };
113 static const uint16_t bwi_phy_noise_11g[] =
114 { BWI_PHY_NOISE_11G };
115 static const uint32_t bwi_phy_rotor_11g_rev1[] =
116 { BWI_PHY_ROTOR_11G_REV1 };
117 static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
118 { BWI_PHY_NOISE_SCALE_11G_REV2 };
119 static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
120 { BWI_PHY_NOISE_SCALE_11G_REV7 };
121 static const uint16_t bwi_phy_noise_scale_11g[] =
122 { BWI_PHY_NOISE_SCALE_11G };
123 static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
124 { BWI_PHY_SIGMA_SQ_11G_REV2 };
125 static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
126 { BWI_PHY_SIGMA_SQ_11G_REV7 };
127 static const uint32_t bwi_phy_delay_11g_rev1[] =
128 { BWI_PHY_DELAY_11G_REV1 };
130 void
131 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
133 struct bwi_softc *sc = mac->mac_sc;
135 /* TODO: 11A */
136 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
137 CSR_WRITE_2(sc, BWI_PHY_DATA, data);
140 uint16_t
141 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
143 struct bwi_softc *sc = mac->mac_sc;
145 /* TODO: 11A */
146 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
147 return CSR_READ_2(sc, BWI_PHY_DATA);
151 bwi_phy_attach(struct bwi_mac *mac)
153 struct bwi_softc *sc = mac->mac_sc;
154 struct bwi_phy *phy = &mac->mac_phy;
155 uint8_t phyrev, phytype, phyver;
156 uint16_t val;
157 int i;
159 /* Get PHY type/revision/version */
160 val = CSR_READ_2(sc, BWI_PHYINFO);
161 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
162 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
163 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
164 device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
165 phytype, phyrev, phyver);
168 * Verify whether the revision of the PHY type is supported
169 * Convert PHY type to ieee80211_phymode
171 switch (phytype) {
172 case BWI_PHYINFO_TYPE_11A:
173 if (phyrev >= 4) {
174 device_printf(sc->sc_dev, "unsupported 11A PHY, "
175 "rev %u\n", phyrev);
176 return ENXIO;
178 phy->phy_init = bwi_phy_init_11a;
179 phy->phy_mode = IEEE80211_MODE_11A;
180 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
181 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
182 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
183 break;
184 case BWI_PHYINFO_TYPE_11B:
185 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
186 for (i = 0; i < N(bwi_sup_bphy); ++i) {
187 if (phyrev == bwi_sup_bphy[i].rev) {
188 phy->phy_init = bwi_sup_bphy[i].init;
189 break;
192 if (i == N(bwi_sup_bphy)) {
193 device_printf(sc->sc_dev, "unsupported 11B PHY, "
194 "rev %u\n", phyrev);
195 return ENXIO;
197 #undef N
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;
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;
217 phy->phy_rev = phyrev;
218 phy->phy_version = phyver;
219 return 0;
222 void
223 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
225 struct bwi_phy *phy = &mac->mac_phy;
226 uint16_t mask = __BITS(3, 0);
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));
242 bwi_phy_calibrate(struct bwi_mac *mac)
244 struct bwi_phy *phy = &mac->mac_phy;
246 /* Dummy read */
247 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
249 /* Don't re-init */
250 if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
251 return 0;
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);
259 phy->phy_flags |= BWI_PHY_F_CALIBRATED;
260 return 0;
263 static void
264 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
266 struct bwi_phy *phy = &mac->mac_phy;
268 KKASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0);
269 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
270 PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
273 static void
274 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
276 struct bwi_phy *phy = &mac->mac_phy;
278 KKASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
279 phy->phy_tbl_ctrl != 0);
281 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
282 PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
283 PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
286 void
287 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
289 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
290 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
293 int16_t
294 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
296 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
297 return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
300 static void
301 bwi_phy_init_11a(struct bwi_mac *mac)
303 /* TODO:11A */
306 static void
307 bwi_phy_init_11g(struct bwi_mac *mac)
309 struct bwi_softc *sc = mac->mac_sc;
310 struct bwi_phy *phy = &mac->mac_phy;
311 struct bwi_rf *rf = &mac->mac_rf;
312 const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
314 if (phy->phy_rev == 1)
315 bwi_phy_init_11b_rev5(mac);
316 else
317 bwi_phy_init_11b_rev6(mac);
319 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
320 bwi_phy_config_11g(mac);
322 if (phy->phy_rev >= 2) {
323 PHY_WRITE(mac, 0x814, 0);
324 PHY_WRITE(mac, 0x815, 0);
326 if (phy->phy_rev == 2) {
327 PHY_WRITE(mac, 0x811, 0);
328 PHY_WRITE(mac, 0x15, 0xc0);
329 } else if (phy->phy_rev > 5) {
330 PHY_WRITE(mac, 0x811, 0x400);
331 PHY_WRITE(mac, 0x15, 0xc0);
335 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
336 uint16_t val;
338 val = PHY_READ(mac, 0x400) & 0xff;
339 if (val == 3 || val == 5) {
340 PHY_WRITE(mac, 0x4c2, 0x1816);
341 PHY_WRITE(mac, 0x4c3, 0x8006);
342 if (val == 5) {
343 PHY_FILT_SETBITS(mac, 0x4cc,
344 0xff, 0x1f00);
349 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
350 phy->phy_rev >= 2)
351 PHY_WRITE(mac, 0x47e, 0x78);
353 if (rf->rf_rev == 8) {
354 PHY_SETBITS(mac, 0x801, 0x80);
355 PHY_SETBITS(mac, 0x43e, 0x4);
358 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
359 bwi_rf_get_gains(mac);
361 if (rf->rf_rev != 8)
362 bwi_rf_init(mac);
364 if (tpctl->tp_ctrl2 == 0xffff) {
365 bwi_rf_lo_update(mac);
366 } else {
367 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
368 RF_WRITE(mac, 0x52,
369 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
370 } else {
371 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl1);
374 if (phy->phy_rev >= 6) {
375 PHY_FILT_SETBITS(mac, 0x36, 0xfff,
376 tpctl->tp_ctrl2 << 12);
379 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
380 PHY_WRITE(mac, 0x2e, 0x8075);
381 else
382 PHY_WRITE(mac, 0x2e, 0x807f);
384 if (phy->phy_rev < 2)
385 PHY_WRITE(mac, 0x2f, 0x101);
386 else
387 PHY_WRITE(mac, 0x2f, 0x202);
390 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
391 bwi_rf_lo_adjust(mac, tpctl);
392 PHY_WRITE(mac, 0x80f, 0x8078);
395 if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
396 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
397 bwi_rf_set_nrssi_thr(mac);
398 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
399 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
400 KKASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI);
401 bwi_rf_calc_nrssi_slope(mac);
402 } else {
403 KKASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI);
404 bwi_rf_set_nrssi_thr(mac);
408 if (rf->rf_rev == 8)
409 PHY_WRITE(mac, 0x805, 0x3230);
411 bwi_mac_init_tpctl_11bg(mac);
413 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
414 PHY_CLRBITS(mac, 0x429, 0x4000);
415 PHY_CLRBITS(mac, 0x4c3, 0x8000);
419 static void
420 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
422 /* TODO:11B */
423 if_printf(&mac->mac_sc->sc_ic.ic_if,
424 "%s is not implemented yet\n", __func__);
427 static void
428 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
430 struct bwi_softc *sc = mac->mac_sc;
431 struct bwi_rf *rf = &mac->mac_rf;
432 uint16_t val, ofs;
433 u_int chan;
435 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
437 PHY_WRITE(mac, 0x20, 0x301c);
438 PHY_WRITE(mac, 0x26, 0);
439 PHY_WRITE(mac, 0x30, 0xc6);
440 PHY_WRITE(mac, 0x88, 0x3e00);
442 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
443 PHY_WRITE(mac, 0x89 + ofs, val);
445 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
447 chan = rf->rf_curchan;
448 if (chan == IEEE80211_CHAN_ANY)
449 chan = 6; /* Force to channel 6 */
450 bwi_rf_set_chan(mac, chan, 0);
452 if (rf->rf_type != BWI_RF_T_BCM2050) {
453 RF_WRITE(mac, 0x75, 0x80);
454 RF_WRITE(mac, 0x79, 0x81);
457 RF_WRITE(mac, 0x50, 0x20);
458 RF_WRITE(mac, 0x50, 0x23);
460 if (rf->rf_type == BWI_RF_T_BCM2050) {
461 RF_WRITE(mac, 0x50, 0x20);
462 RF_WRITE(mac, 0x5a, 0x70);
463 RF_WRITE(mac, 0x5b, 0x7b);
464 RF_WRITE(mac, 0x5c, 0xb0);
465 RF_WRITE(mac, 0x7a, 0xf);
466 PHY_WRITE(mac, 0x38, 0x677);
467 bwi_rf_init_bcm2050(mac);
470 PHY_WRITE(mac, 0x14, 0x80);
471 PHY_WRITE(mac, 0x32, 0xca);
472 if (rf->rf_type == BWI_RF_T_BCM2050)
473 PHY_WRITE(mac, 0x32, 0xe0);
474 PHY_WRITE(mac, 0x35, 0x7c2);
476 bwi_rf_lo_update(mac);
478 PHY_WRITE(mac, 0x26, 0xcc00);
479 if (rf->rf_type == BWI_RF_T_BCM2050)
480 PHY_WRITE(mac, 0x26, 0xce00);
482 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
484 PHY_WRITE(mac, 0x2a, 0x88a3);
485 if (rf->rf_type == BWI_RF_T_BCM2050)
486 PHY_WRITE(mac, 0x2a, 0x88c2);
488 bwi_mac_set_tpctl_11bg(mac, NULL);
489 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
490 bwi_rf_calc_nrssi_slope(mac);
491 bwi_rf_set_nrssi_thr(mac);
493 bwi_mac_init_tpctl_11bg(mac);
496 static void
497 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
499 struct bwi_softc *sc = mac->mac_sc;
500 struct bwi_rf *rf = &mac->mac_rf;
501 struct bwi_phy *phy = &mac->mac_phy;
502 u_int orig_chan;
504 if (phy->phy_version == 1)
505 RF_SETBITS(mac, 0x7a, 0x50);
507 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
508 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
509 uint16_t ofs, val;
511 val = 0x2120;
512 for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
513 PHY_WRITE(mac, ofs, val);
514 val += 0x202;
518 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
520 if (rf->rf_type == BWI_RF_T_BCM2050)
521 PHY_WRITE(mac, 0x38, 0x667);
523 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
524 if (rf->rf_type == BWI_RF_T_BCM2050) {
525 RF_SETBITS(mac, 0x7a, 0x20);
526 RF_SETBITS(mac, 0x51, 0x4);
529 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
531 PHY_SETBITS(mac, 0x802, 0x100);
532 PHY_SETBITS(mac, 0x42b, 0x2000);
533 PHY_WRITE(mac, 0x1c, 0x186a);
535 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
536 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
537 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
540 /* TODO: bad_frame_preempt? */
542 if (phy->phy_version == 1) {
543 PHY_WRITE(mac, 0x26, 0xce00);
544 PHY_WRITE(mac, 0x21, 0x3763);
545 PHY_WRITE(mac, 0x22, 0x1bc3);
546 PHY_WRITE(mac, 0x23, 0x6f9);
547 PHY_WRITE(mac, 0x24, 0x37e);
548 } else {
549 PHY_WRITE(mac, 0x26, 0xcc00);
551 PHY_WRITE(mac, 0x30, 0xc6);
553 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
555 if (phy->phy_version == 1)
556 PHY_WRITE(mac, 0x20, 0x3e1c);
557 else
558 PHY_WRITE(mac, 0x20, 0x301c);
560 if (phy->phy_version == 0)
561 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
563 /* Force to channel 7 */
564 orig_chan = rf->rf_curchan;
565 bwi_rf_set_chan(mac, 7, 0);
567 if (rf->rf_type != BWI_RF_T_BCM2050) {
568 RF_WRITE(mac, 0x75, 0x80);
569 RF_WRITE(mac, 0x79, 0x81);
572 RF_WRITE(mac, 0x50, 0x20);
573 RF_WRITE(mac, 0x50, 0x23);
575 if (rf->rf_type == BWI_RF_T_BCM2050) {
576 RF_WRITE(mac, 0x50, 0x20);
577 RF_WRITE(mac, 0x5a, 0x70);
580 RF_WRITE(mac, 0x5b, 0x7b);
581 RF_WRITE(mac, 0x5c, 0xb0);
582 RF_SETBITS(mac, 0x7a, 0x7);
584 bwi_rf_set_chan(mac, orig_chan, 0);
586 PHY_WRITE(mac, 0x14, 0x80);
587 PHY_WRITE(mac, 0x32, 0xca);
588 PHY_WRITE(mac, 0x2a, 0x88a3);
590 bwi_mac_set_tpctl_11bg(mac, NULL);
592 if (rf->rf_type == BWI_RF_T_BCM2050)
593 RF_WRITE(mac, 0x5d, 0xd);
595 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
598 static void
599 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
601 struct bwi_softc *sc = mac->mac_sc;
602 struct bwi_rf *rf = &mac->mac_rf;
603 struct bwi_phy *phy = &mac->mac_phy;
604 uint16_t val, ofs;
605 u_int orig_chan;
607 PHY_WRITE(mac, 0x3e, 0x817a);
608 RF_SETBITS(mac, 0x7a, 0x58);
610 if (rf->rf_rev == 4 || rf->rf_rev == 5) {
611 RF_WRITE(mac, 0x51, 0x37);
612 RF_WRITE(mac, 0x52, 0x70);
613 RF_WRITE(mac, 0x53, 0xb3);
614 RF_WRITE(mac, 0x54, 0x9b);
615 RF_WRITE(mac, 0x5a, 0x88);
616 RF_WRITE(mac, 0x5b, 0x88);
617 RF_WRITE(mac, 0x5d, 0x88);
618 RF_WRITE(mac, 0x5e, 0x88);
619 RF_WRITE(mac, 0x7d, 0x88);
620 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
621 } else if (rf->rf_rev == 8) {
622 RF_WRITE(mac, 0x51, 0);
623 RF_WRITE(mac, 0x52, 0x40);
624 RF_WRITE(mac, 0x53, 0xb7);
625 RF_WRITE(mac, 0x54, 0x98);
626 RF_WRITE(mac, 0x5a, 0x88);
627 RF_WRITE(mac, 0x5b, 0x6b);
628 RF_WRITE(mac, 0x5c, 0xf);
629 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
630 RF_WRITE(mac, 0x5d, 0xfa);
631 RF_WRITE(mac, 0x5e, 0xd8);
632 } else {
633 RF_WRITE(mac, 0x5d, 0xf5);
634 RF_WRITE(mac, 0x5e, 0xb8);
636 RF_WRITE(mac, 0x73, 0x3);
637 RF_WRITE(mac, 0x7d, 0xa8);
638 RF_WRITE(mac, 0x7c, 0x1);
639 RF_WRITE(mac, 0x7e, 0x8);
642 val = 0x1e1f;
643 for (ofs = 0x88; ofs < 0x98; ++ofs) {
644 PHY_WRITE(mac, ofs, val);
645 val -= 0x202;
648 val = 0x3e3f;
649 for (ofs = 0x98; ofs < 0xa8; ++ofs) {
650 PHY_WRITE(mac, ofs, val);
651 val -= 0x202;
654 val = 0x2120;
655 for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
656 PHY_WRITE(mac, ofs, (val & 0x3f3f));
657 val += 0x202;
660 if (phy->phy_mode == IEEE80211_MODE_11G) {
661 RF_SETBITS(mac, 0x7a, 0x20);
662 RF_SETBITS(mac, 0x51, 0x4);
663 PHY_SETBITS(mac, 0x802, 0x100);
664 PHY_SETBITS(mac, 0x42b, 0x2000);
665 PHY_WRITE(mac, 0x5b, 0);
666 PHY_WRITE(mac, 0x5c, 0);
669 /* Force to channel 7 */
670 orig_chan = rf->rf_curchan;
671 if (orig_chan >= 8)
672 bwi_rf_set_chan(mac, 1, 0);
673 else
674 bwi_rf_set_chan(mac, 13, 0);
676 RF_WRITE(mac, 0x50, 0x20);
677 RF_WRITE(mac, 0x50, 0x23);
679 DELAY(40);
681 if (rf->rf_rev < 6 || rf->rf_rev == 8) {
682 RF_SETBITS(mac, 0x7c, 0x2);
683 RF_WRITE(mac, 0x50, 0x20);
685 if (rf->rf_rev <= 2) {
686 RF_WRITE(mac, 0x7c, 0x20);
687 RF_WRITE(mac, 0x5a, 0x70);
688 RF_WRITE(mac, 0x5b, 0x7b);
689 RF_WRITE(mac, 0x5c, 0xb0);
692 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
694 bwi_rf_set_chan(mac, orig_chan, 0);
696 PHY_WRITE(mac, 0x14, 0x200);
697 if (rf->rf_rev >= 6)
698 PHY_WRITE(mac, 0x2a, 0x88c2);
699 else
700 PHY_WRITE(mac, 0x2a, 0x8ac0);
701 PHY_WRITE(mac, 0x38, 0x668);
703 bwi_mac_set_tpctl_11bg(mac, NULL);
705 if (rf->rf_rev <= 5) {
706 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
707 if (rf->rf_rev <= 2)
708 RF_WRITE(mac, 0x5d, 0xd);
711 if (phy->phy_version == 4) {
712 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
713 PHY_CLRBITS(mac, 0x61, 0xf000);
714 } else {
715 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
718 if (phy->phy_mode == IEEE80211_MODE_11B) {
719 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
720 PHY_WRITE(mac, 0x16, 0x410);
721 PHY_WRITE(mac, 0x17, 0x820);
722 PHY_WRITE(mac, 0x62, 0x7);
724 bwi_rf_init_bcm2050(mac);
725 bwi_rf_lo_update(mac);
726 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
727 bwi_rf_calc_nrssi_slope(mac);
728 bwi_rf_set_nrssi_thr(mac);
730 bwi_mac_init_tpctl_11bg(mac);
731 } else {
732 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
736 #define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
738 static void
739 bwi_phy_config_11g(struct bwi_mac *mac)
741 struct bwi_softc *sc = mac->mac_sc;
742 struct bwi_phy *phy = &mac->mac_phy;
743 const uint16_t *tbl;
744 uint16_t wrd_ofs1, wrd_ofs2;
745 int i, n;
747 if (phy->phy_rev == 1) {
748 PHY_WRITE(mac, 0x406, 0x4f19);
749 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
750 PHY_WRITE(mac, 0x42c, 0x5a);
751 PHY_WRITE(mac, 0x427, 0x1a);
753 /* Fill frequency table */
754 for (i = 0; i < N(bwi_phy_freq_11g_rev1); ++i) {
755 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
756 bwi_phy_freq_11g_rev1[i]);
759 /* Fill noise table */
760 for (i = 0; i < N(bwi_phy_noise_11g_rev1); ++i) {
761 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
762 bwi_phy_noise_11g_rev1[i]);
765 /* Fill rotor table */
766 for (i = 0; i < N(bwi_phy_rotor_11g_rev1); ++i) {
767 /* NB: data length is 4 bytes */
768 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
769 bwi_phy_rotor_11g_rev1[i]);
771 } else {
772 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
774 if (phy->phy_rev == 2) {
775 PHY_WRITE(mac, 0x4c0, 0x1861);
776 PHY_WRITE(mac, 0x4c1, 0x271);
777 } else if (phy->phy_rev > 2) {
778 PHY_WRITE(mac, 0x4c0, 0x98);
779 PHY_WRITE(mac, 0x4c1, 0x70);
780 PHY_WRITE(mac, 0x4c9, 0x80);
782 PHY_SETBITS(mac, 0x42b, 0x800);
784 /* Fill RSSI table */
785 for (i = 0; i < 64; ++i)
786 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
788 /* Fill noise table */
789 for (i = 0; i < sizeof(bwi_phy_noise_11g); ++i) {
790 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
791 bwi_phy_noise_11g[i]);
796 * Fill noise scale table
798 if (phy->phy_rev <= 2) {
799 tbl = bwi_phy_noise_scale_11g_rev2;
800 n = N(bwi_phy_noise_scale_11g_rev2);
801 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
802 tbl = bwi_phy_noise_scale_11g_rev7;
803 n = N(bwi_phy_noise_scale_11g_rev7);
804 } else {
805 tbl = bwi_phy_noise_scale_11g;
806 n = N(bwi_phy_noise_scale_11g);
808 for (i = 0; i < n; ++i)
809 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
812 * Fill sigma square table
814 if (phy->phy_rev == 2) {
815 tbl = bwi_phy_sigma_sq_11g_rev2;
816 n = N(bwi_phy_sigma_sq_11g_rev2);
817 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
818 tbl = bwi_phy_sigma_sq_11g_rev7;
819 n = N(bwi_phy_sigma_sq_11g_rev7);
820 } else {
821 tbl = NULL;
822 n = 0;
824 for (i = 0; i < n; ++i)
825 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
827 if (phy->phy_rev == 1) {
828 /* Fill delay table */
829 for (i = 0; i < N(bwi_phy_delay_11g_rev1); ++i) {
830 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
831 bwi_phy_delay_11g_rev1[i]);
834 /* Fill WRSSI (Wide-Band RSSI) table */
835 for (i = 4; i < 20; ++i)
836 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
838 bwi_phy_config_agc(mac);
840 wrd_ofs1 = 0x5001;
841 wrd_ofs2 = 0x5002;
842 } else {
843 /* Fill WRSSI (Wide-Band RSSI) table */
844 for (i = 0; i < 0x20; ++i)
845 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
847 bwi_phy_config_agc(mac);
849 PHY_READ(mac, 0x400); /* Dummy read */
850 PHY_WRITE(mac, 0x403, 0x1000);
851 bwi_tbl_write_2(mac, 0x3c02, 0xf);
852 bwi_tbl_write_2(mac, 0x3c03, 0x14);
854 wrd_ofs1 = 0x401;
855 wrd_ofs2 = 0x402;
858 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
859 bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
860 bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
863 /* phy->phy_flags & BWI_PHY_F_LINKED ? */
864 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
865 PHY_WRITE(mac, 0x46e, 0x3cf);
868 #undef N
871 * Configure Automatic Gain Controller
873 static void
874 bwi_phy_config_agc(struct bwi_mac *mac)
876 struct bwi_phy *phy = &mac->mac_phy;
877 uint16_t ofs;
879 ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
881 bwi_tbl_write_2(mac, ofs, 0xfe);
882 bwi_tbl_write_2(mac, ofs + 1, 0xd);
883 bwi_tbl_write_2(mac, ofs + 2, 0x13);
884 bwi_tbl_write_2(mac, ofs + 3, 0x19);
886 if (phy->phy_rev == 1) {
887 bwi_tbl_write_2(mac, 0x1800, 0x2710);
888 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
889 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
890 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
891 PHY_WRITE(mac, 0x455, 0x4);
894 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
895 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
896 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
897 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
899 RF_SETBITS(mac, 0x7a, 0x8);
901 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
902 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
903 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
904 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
906 if (phy->phy_rev == 1)
907 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
909 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
910 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
911 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
912 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
913 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
914 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
915 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
916 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
917 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
919 if (phy->phy_rev == 1) {
920 PHY_WRITE(mac, 0x430, 0x92b);
921 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
922 } else {
923 PHY_CLRBITS(mac, 0x41b, 0x1e);
924 PHY_WRITE(mac, 0x41f, 0x287a);
925 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
927 if (phy->phy_rev >= 6) {
928 PHY_WRITE(mac, 0x422, 0x287a);
929 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
933 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
934 PHY_WRITE(mac, 0x48e, 0x1c00);
936 if (phy->phy_rev == 1) {
937 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
938 PHY_WRITE(mac, 0x48b, 0x5e);
939 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
940 PHY_WRITE(mac, 0x48d, 0x2);
943 bwi_tbl_write_2(mac, ofs + 0x800, 0);
944 bwi_tbl_write_2(mac, ofs + 0x801, 7);
945 bwi_tbl_write_2(mac, ofs + 0x802, 16);
946 bwi_tbl_write_2(mac, ofs + 0x803, 28);
948 if (phy->phy_rev >= 6) {
949 PHY_CLRBITS(mac, 0x426, 0x3);
950 PHY_CLRBITS(mac, 0x426, 0x1000);
954 void
955 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
957 struct bwi_phy *phy = &mac->mac_phy;
958 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
959 int i;
961 if (phy->phy_rev <= 1) {
962 tbl_gain_ofs1 = 0x5000;
963 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
964 } else {
965 tbl_gain_ofs1 = 0x400;
966 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
969 for (i = 0; i < 4; ++i) {
970 if (gains != NULL) {
971 tbl_gain = gains->tbl_gain1;
972 } else {
973 /* Bit swap */
974 tbl_gain = (i & 0x1) << 1;
975 tbl_gain |= (i & 0x2) >> 1;
977 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
980 for (i = 0; i < 16; ++i) {
981 if (gains != NULL)
982 tbl_gain = gains->tbl_gain2;
983 else
984 tbl_gain = i;
985 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
988 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
989 uint16_t phy_gain1, phy_gain2;
991 if (gains != NULL) {
992 phy_gain1 =
993 ((uint16_t)gains->phy_gain << 14) |
994 ((uint16_t)gains->phy_gain << 6);
995 phy_gain2 = phy_gain1;
996 } else {
997 phy_gain1 = 0x4040;
998 phy_gain2 = 0x4000;
1000 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1001 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1002 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1004 bwi_mac_dummy_xmit(mac);
1007 void
1008 bwi_phy_clear_state(struct bwi_phy *phy)
1010 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;