dc57f26f29dd000f3081a4d41f7a55ba7e5fef41
[dragonfly.git] / sys / dev / netif / 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/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>
49
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>
57
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>
61
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcidevs.h>
65
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>
71
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 *);
78
79 static void     bwi_phy_config_11g(struct bwi_mac *);
80 static void     bwi_phy_config_agc(struct bwi_mac *);
81
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);
84
85 #define SUP_BPHY(num)   { .rev = num, .init = bwi_phy_init_11b_rev##num }
86
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)
95 };
96
97 #undef SUP_BPHY
98
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
108
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 };
129
130 void
131 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
132 {
133         struct bwi_softc *sc = mac->mac_sc;
134
135         /* TODO: 11A */
136         CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
137         CSR_WRITE_2(sc, BWI_PHY_DATA, data);
138 }
139
140 uint16_t
141 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
142 {
143         struct bwi_softc *sc = mac->mac_sc;
144
145         /* TODO: 11A */
146         CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
147         return CSR_READ_2(sc, BWI_PHY_DATA);
148 }
149
150 int
151 bwi_phy_attach(struct bwi_mac *mac)
152 {
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;
158
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);
166
167         /*
168          * Verify whether the revision of the PHY type is supported
169          * Convert PHY type to ieee80211_phymode
170          */
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;
177                 }
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;
190                         }
191                 }
192                 if (i == N(bwi_sup_bphy)) {
193                         device_printf(sc->sc_dev, "unsupported 11B PHY, "
194                                       "rev %u\n", phyrev);
195                         return ENXIO;
196                 }
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;
205                 }
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;
216         }
217         phy->phy_rev = phyrev;
218         phy->phy_version = phyver;
219         return 0;
220 }
221
222 void
223 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
224 {
225         struct bwi_phy *phy = &mac->mac_phy;
226         uint16_t mask = __BITS(3, 0);
227
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));
238         }
239 }
240
241 int
242 bwi_phy_calibrate(struct bwi_mac *mac)
243 {
244         struct bwi_phy *phy = &mac->mac_phy;
245
246         /* Dummy read */
247         CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
248
249         /* Don't re-init */
250         if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
251                 return 0;
252
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);
257         }
258
259         phy->phy_flags |= BWI_PHY_F_CALIBRATED;
260         return 0;
261 }
262
263 static void
264 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
265 {
266         struct bwi_phy *phy = &mac->mac_phy;
267
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);
271 }
272
273 static void
274 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
275 {
276         struct bwi_phy *phy = &mac->mac_phy;
277
278         KKASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
279                  phy->phy_tbl_ctrl != 0);
280
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);
284 }
285
286 void
287 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
288 {
289         PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
290         PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
291 }
292
293 int16_t
294 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
295 {
296         PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
297         return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
298 }
299
300 static void
301 bwi_phy_init_11a(struct bwi_mac *mac)
302 {
303         /* TODO:11A */
304 }
305
306 static void
307 bwi_phy_init_11g(struct bwi_mac *mac)
308 {
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;
313
314         if (phy->phy_rev == 1)
315                 bwi_phy_init_11b_rev5(mac);
316         else
317                 bwi_phy_init_11b_rev6(mac);
318
319         if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
320                 bwi_phy_config_11g(mac);
321
322         if (phy->phy_rev >= 2) {
323                 PHY_WRITE(mac, 0x814, 0);
324                 PHY_WRITE(mac, 0x815, 0);
325
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);
332                 }
333         }
334
335         if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
336                 uint16_t val;
337
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);
345                         }
346                 }
347         }
348
349         if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
350             phy->phy_rev >= 2)
351                 PHY_WRITE(mac, 0x47e, 0x78);
352
353         if (rf->rf_rev == 8) {
354                 PHY_SETBITS(mac, 0x801, 0x80);
355                 PHY_SETBITS(mac, 0x43e, 0x4);
356         }
357
358         if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
359                 bwi_rf_get_gains(mac);
360
361         if (rf->rf_rev != 8)
362                 bwi_rf_init(mac);
363
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);
372                 }
373
374                 if (phy->phy_rev >= 6) {
375                         PHY_FILT_SETBITS(mac, 0x36, 0xfff,
376                                          tpctl->tp_ctrl2 << 12);
377                 }
378
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);
383
384                 if (phy->phy_rev < 2)
385                         PHY_WRITE(mac, 0x2f, 0x101);
386                 else
387                         PHY_WRITE(mac, 0x2f, 0x202);
388         }
389
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);
393         }
394
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);
405                 }
406         }
407
408         if (rf->rf_rev == 8)
409                 PHY_WRITE(mac, 0x805, 0x3230);
410
411         bwi_mac_init_tpctl_11bg(mac);
412
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);
416         }
417 }
418
419 static void
420 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
421
422         /* TODO:11B */
423         if_printf(&mac->mac_sc->sc_ic.ic_if,
424                   "%s is not implemented yet\n", __func__);
425 }
426
427 static void
428 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
429 {
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;
434
435         CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
436
437         PHY_WRITE(mac, 0x20, 0x301c);
438         PHY_WRITE(mac, 0x26, 0);
439         PHY_WRITE(mac, 0x30, 0xc6);
440         PHY_WRITE(mac, 0x88, 0x3e00);
441
442         for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
443                 PHY_WRITE(mac, 0x89 + ofs, val);
444
445         CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
446
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);
451
452         if (rf->rf_type != BWI_RF_T_BCM2050) {
453                 RF_WRITE(mac, 0x75, 0x80);
454                 RF_WRITE(mac, 0x79, 0x81);
455         }
456
457         RF_WRITE(mac, 0x50, 0x20);
458         RF_WRITE(mac, 0x50, 0x23);
459
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);
468         }
469
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);
475
476         bwi_rf_lo_update(mac);
477
478         PHY_WRITE(mac, 0x26, 0xcc00);
479         if (rf->rf_type == BWI_RF_T_BCM2050)
480                 PHY_WRITE(mac, 0x26, 0xce00);
481
482         CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
483
484         PHY_WRITE(mac, 0x2a, 0x88a3);
485         if (rf->rf_type == BWI_RF_T_BCM2050)
486                 PHY_WRITE(mac, 0x2a, 0x88c2);
487
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);
492         }
493         bwi_mac_init_tpctl_11bg(mac);
494 }
495
496 static void
497 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
498 {
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;
503
504         if (phy->phy_version == 1)
505                 RF_SETBITS(mac, 0x7a, 0x50);
506
507         if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
508             sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
509                 uint16_t ofs, val;
510
511                 val = 0x2120;
512                 for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
513                         PHY_WRITE(mac, ofs, val);
514                         val += 0x202;
515                 }
516         }
517
518         PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
519
520         if (rf->rf_type == BWI_RF_T_BCM2050)
521                 PHY_WRITE(mac, 0x38, 0x667);
522
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);
527                 }
528
529                 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
530
531                 PHY_SETBITS(mac, 0x802, 0x100);
532                 PHY_SETBITS(mac, 0x42b, 0x2000);
533                 PHY_WRITE(mac, 0x1c, 0x186a);
534
535                 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
536                 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
537                 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
538         }
539
540         /* TODO: bad_frame_preempt? */
541
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);
550         }
551         PHY_WRITE(mac, 0x30, 0xc6);
552
553         CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
554
555         if (phy->phy_version == 1)
556                 PHY_WRITE(mac, 0x20, 0x3e1c);
557         else
558                 PHY_WRITE(mac, 0x20, 0x301c);
559
560         if (phy->phy_version == 0)
561                 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
562
563         /* Force to channel 7 */
564         orig_chan = rf->rf_curchan;
565         bwi_rf_set_chan(mac, 7, 0);
566
567         if (rf->rf_type != BWI_RF_T_BCM2050) {
568                 RF_WRITE(mac, 0x75, 0x80);
569                 RF_WRITE(mac, 0x79, 0x81);
570         }
571
572         RF_WRITE(mac, 0x50, 0x20);
573         RF_WRITE(mac, 0x50, 0x23);
574
575         if (rf->rf_type == BWI_RF_T_BCM2050) {
576                 RF_WRITE(mac, 0x50, 0x20);
577                 RF_WRITE(mac, 0x5a, 0x70);
578         }
579
580         RF_WRITE(mac, 0x5b, 0x7b);
581         RF_WRITE(mac, 0x5c, 0xb0);
582         RF_SETBITS(mac, 0x7a, 0x7);
583
584         bwi_rf_set_chan(mac, orig_chan, 0);
585
586         PHY_WRITE(mac, 0x14, 0x80);
587         PHY_WRITE(mac, 0x32, 0xca);
588         PHY_WRITE(mac, 0x2a, 0x88a3);
589
590         bwi_mac_set_tpctl_11bg(mac, NULL);
591
592         if (rf->rf_type == BWI_RF_T_BCM2050)
593                 RF_WRITE(mac, 0x5d, 0xd);
594
595         CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
596 }
597
598 static void
599 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
600 {
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;
606
607         PHY_WRITE(mac, 0x3e, 0x817a);
608         RF_SETBITS(mac, 0x7a, 0x58);
609
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);
635                 }
636                 RF_WRITE(mac, 0x73, 0x3);
637                 RF_WRITE(mac, 0x7d, 0xa8);
638                 RF_WRITE(mac, 0x7c, 0x1);
639                 RF_WRITE(mac, 0x7e, 0x8);
640         }
641
642         val = 0x1e1f;
643         for (ofs = 0x88; ofs < 0x98; ++ofs) {
644                 PHY_WRITE(mac, ofs, val);
645                 val -= 0x202;
646         }
647
648         val = 0x3e3f;
649         for (ofs = 0x98; ofs < 0xa8; ++ofs) {
650                 PHY_WRITE(mac, ofs, val);
651                 val -= 0x202;
652         }
653
654         val = 0x2120;
655         for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
656                 PHY_WRITE(mac, ofs, (val & 0x3f3f));
657                 val += 0x202;
658         }
659
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);
667         }
668
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);
675
676         RF_WRITE(mac, 0x50, 0x20);
677         RF_WRITE(mac, 0x50, 0x23);
678
679         DELAY(40);
680
681         if (rf->rf_rev < 6 || rf->rf_rev == 8) {
682                 RF_SETBITS(mac, 0x7c, 0x2);
683                 RF_WRITE(mac, 0x50, 0x20);
684         }
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);
690         }
691
692         RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
693
694         bwi_rf_set_chan(mac, orig_chan, 0);
695
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);
702
703         bwi_mac_set_tpctl_11bg(mac, NULL);
704
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);
709         }
710
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);
716         }
717
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);
723
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);
729                 }
730                 bwi_mac_init_tpctl_11bg(mac);
731         } else {
732                 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
733         }
734 }
735
736 #define N(arr)  (int)(sizeof(arr) / sizeof(arr[0]))
737
738 static void
739 bwi_phy_config_11g(struct bwi_mac *mac)
740 {
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;
746
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);
752
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]);
757                 }
758
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]);
763                 }
764
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]);
770                 }
771         } else {
772                 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
773
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);
781                 }
782                 PHY_SETBITS(mac, 0x42b, 0x800);
783
784                 /* Fill RSSI table */
785                 for (i = 0; i < 64; ++i)
786                         bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
787
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]);
792                 }
793         }
794
795         /*
796          * Fill noise scale table
797          */
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);
807         }
808         for (i = 0; i < n; ++i)
809                 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
810
811         /*
812          * Fill sigma square table
813          */
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;
823         }
824         for (i = 0; i < n; ++i)
825                 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
826
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]);
832                 }
833
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);
837
838                 bwi_phy_config_agc(mac);
839
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);
846
847                 bwi_phy_config_agc(mac);
848
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);
853
854                 wrd_ofs1 = 0x401;
855                 wrd_ofs2 = 0x402;
856         }
857
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);
861         }
862
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);
866 }
867
868 #undef N
869
870 /*
871  * Configure Automatic Gain Controller
872  */
873 static void
874 bwi_phy_config_agc(struct bwi_mac *mac)
875 {
876         struct bwi_phy *phy = &mac->mac_phy;
877         uint16_t ofs;
878
879         ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
880
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);
885
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);
892         }
893
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);
898
899         RF_SETBITS(mac, 0x7a, 0x8);
900
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);
905
906         if (phy->phy_rev == 1)
907                 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
908
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);
918
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);
926
927                 if (phy->phy_rev >= 6) {
928                         PHY_WRITE(mac, 0x422, 0x287a);
929                         PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
930                 }
931         }
932
933         PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
934         PHY_WRITE(mac, 0x48e, 0x1c00);
935
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);
941         }
942
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);
947
948         if (phy->phy_rev >= 6) {
949                 PHY_CLRBITS(mac, 0x426, 0x3);
950                 PHY_CLRBITS(mac, 0x426, 0x1000);
951         }
952 }
953
954 void
955 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
956 {
957         struct bwi_phy *phy = &mac->mac_phy;
958         uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
959         int i;
960
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;
967         }
968
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;
976                 }
977                 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
978         }
979
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);
986         }
987
988         if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
989                 uint16_t phy_gain1, phy_gain2;
990
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;
999                 }
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);
1003         }
1004         bwi_mac_dummy_xmit(mac);
1005 }
1006
1007 void
1008 bwi_phy_clear_state(struct bwi_phy *phy)
1009 {
1010         phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1011 }