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