]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/bwi/bwiphy.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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_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 }