]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwi/bwiphy.c
MFV r324198: 8081 Compiler warnings in zdb
[FreeBSD/FreeBSD.git] / sys / dev / bwi / bwiphy.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
5  * 
6  * This code is derived from software contributed to The DragonFly Project
7  * by Sepherosa Ziehau <sepherosa@gmail.com>
8  * 
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  * 3. Neither the name of The DragonFly Project nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific, prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  * 
36  * $DragonFly: src/sys/dev/netif/bwi/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $
37  */
38
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41
42 #include "opt_inet.h"
43 #include "opt_wlan.h"
44
45 #include <sys/param.h>
46 #include <sys/endian.h>
47 #include <sys/kernel.h>
48 #include <sys/bus.h>
49 #include <sys/malloc.h>
50 #include <sys/proc.h>
51 #include <sys/rman.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/sysctl.h>
55 #include <sys/systm.h>
56  
57 #include <net/if.h>
58 #include <net/if_var.h>
59 #include <net/if_dl.h>
60 #include <net/if_media.h>
61 #include <net/if_types.h>
62 #include <net/if_arp.h>
63 #include <net/ethernet.h>
64 #include <net/if_llc.h>
65
66 #include <net80211/ieee80211_var.h>
67 #include <net80211/ieee80211_radiotap.h>
68 #include <net80211/ieee80211_amrr.h>
69
70 #include <machine/bus.h>
71
72 #include <dev/bwi/bitops.h>
73 #include <dev/bwi/if_bwireg.h>
74 #include <dev/bwi/if_bwivar.h>
75 #include <dev/bwi/bwimac.h>
76 #include <dev/bwi/bwirf.h>
77 #include <dev/bwi/bwiphy.h>
78
79 static void     bwi_phy_init_11a(struct bwi_mac *);
80 static void     bwi_phy_init_11g(struct bwi_mac *);
81 static void     bwi_phy_init_11b_rev2(struct bwi_mac *);
82 static void     bwi_phy_init_11b_rev4(struct bwi_mac *);
83 static void     bwi_phy_init_11b_rev5(struct bwi_mac *);
84 static void     bwi_phy_init_11b_rev6(struct bwi_mac *);
85
86 static void     bwi_phy_config_11g(struct bwi_mac *);
87 static void     bwi_phy_config_agc(struct bwi_mac *);
88
89 static void     bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
90 static void     bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
91
92 #define SUP_BPHY(num)   { .rev = num, .init = bwi_phy_init_11b_rev##num }
93
94 static const struct {
95         uint8_t rev;
96         void    (*init)(struct bwi_mac *);
97 } bwi_sup_bphy[] = {
98         SUP_BPHY(2),
99         SUP_BPHY(4),
100         SUP_BPHY(5),
101         SUP_BPHY(6)
102 };
103
104 #undef SUP_BPHY
105
106 #define BWI_PHYTBL_WRSSI        0x1000
107 #define BWI_PHYTBL_NOISE_SCALE  0x1400
108 #define BWI_PHYTBL_NOISE        0x1800
109 #define BWI_PHYTBL_ROTOR        0x2000
110 #define BWI_PHYTBL_DELAY        0x2400
111 #define BWI_PHYTBL_RSSI         0x4000
112 #define BWI_PHYTBL_SIGMA_SQ     0x5000
113 #define BWI_PHYTBL_WRSSI_REV1   0x5400
114 #define BWI_PHYTBL_FREQ         0x5800
115
116 static const uint16_t   bwi_phy_freq_11g_rev1[] =
117         { BWI_PHY_FREQ_11G_REV1 };
118 static const uint16_t   bwi_phy_noise_11g_rev1[] =
119         { BWI_PHY_NOISE_11G_REV1 };
120 static const uint16_t   bwi_phy_noise_11g[] =
121         { BWI_PHY_NOISE_11G };
122 static const uint32_t   bwi_phy_rotor_11g_rev1[] =
123         { BWI_PHY_ROTOR_11G_REV1 };
124 static const uint16_t   bwi_phy_noise_scale_11g_rev2[] =
125         { BWI_PHY_NOISE_SCALE_11G_REV2 };
126 static const uint16_t   bwi_phy_noise_scale_11g_rev7[] =
127         { BWI_PHY_NOISE_SCALE_11G_REV7 };
128 static const uint16_t   bwi_phy_noise_scale_11g[] =
129         { BWI_PHY_NOISE_SCALE_11G };
130 static const uint16_t   bwi_phy_sigma_sq_11g_rev2[] =
131         { BWI_PHY_SIGMA_SQ_11G_REV2 };
132 static const uint16_t   bwi_phy_sigma_sq_11g_rev7[] =
133         { BWI_PHY_SIGMA_SQ_11G_REV7 };
134 static const uint32_t   bwi_phy_delay_11g_rev1[] =
135         { BWI_PHY_DELAY_11G_REV1 };
136
137 void
138 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
139 {
140         struct bwi_softc *sc = mac->mac_sc;
141
142         CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
143         CSR_WRITE_2(sc, BWI_PHY_DATA, data);
144 }
145
146 uint16_t
147 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
148 {
149         struct bwi_softc *sc = mac->mac_sc;
150
151         CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
152         return CSR_READ_2(sc, BWI_PHY_DATA);
153 }
154
155 int
156 bwi_phy_attach(struct bwi_mac *mac)
157 {
158         struct bwi_softc *sc = mac->mac_sc;
159         struct bwi_phy *phy = &mac->mac_phy;
160         uint8_t phyrev, phytype, phyver;
161         uint16_t val;
162         int i;
163
164         /* Get PHY type/revision/version */
165         val = CSR_READ_2(sc, BWI_PHYINFO);
166         phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
167         phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
168         phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
169         device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
170                       phytype, phyrev, phyver);
171
172         /*
173          * Verify whether the revision of the PHY type is supported
174          * Convert PHY type to ieee80211_phymode
175          */
176         switch (phytype) {
177         case BWI_PHYINFO_TYPE_11A:
178                 if (phyrev >= 4) {
179                         device_printf(sc->sc_dev, "unsupported 11A PHY, "
180                                       "rev %u\n", phyrev);
181                         return ENXIO;
182                 }
183                 phy->phy_init = bwi_phy_init_11a;
184                 phy->phy_mode = IEEE80211_MODE_11A;
185                 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
186                 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
187                 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
188                 break;
189         case BWI_PHYINFO_TYPE_11B:
190                 for (i = 0; i < nitems(bwi_sup_bphy); ++i) {
191                         if (phyrev == bwi_sup_bphy[i].rev) {
192                                 phy->phy_init = bwi_sup_bphy[i].init;
193                                 break;
194                         }
195                 }
196                 if (i == nitems(bwi_sup_bphy)) {
197                         device_printf(sc->sc_dev, "unsupported 11B PHY, "
198                                       "rev %u\n", phyrev);
199                         return ENXIO;
200                 }
201                 phy->phy_mode = IEEE80211_MODE_11B;
202                 break;
203         case BWI_PHYINFO_TYPE_11G:
204                 if (phyrev > 8) {
205                         device_printf(sc->sc_dev, "unsupported 11G PHY, "
206                                       "rev %u\n", phyrev);
207                         return ENXIO;
208                 }
209                 phy->phy_init = bwi_phy_init_11g;
210                 phy->phy_mode = IEEE80211_MODE_11G;
211                 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
212                 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
213                 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
214                 break;
215         default:
216                 device_printf(sc->sc_dev, "unsupported PHY type %d\n",
217                               phytype);
218                 return ENXIO;
219         }
220         phy->phy_rev = phyrev;
221         phy->phy_version = phyver;
222         return 0;
223 }
224
225 void
226 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
227 {
228         struct bwi_phy *phy = &mac->mac_phy;
229         uint16_t mask = __BITS(3, 0);
230
231         if (phy->phy_version == 0) {
232                 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
233                                    __SHIFTIN(bbp_atten, mask));
234         } else {
235                 if (phy->phy_version > 1)
236                         mask <<= 2;
237                 else
238                         mask <<= 3;
239                 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
240                                  __SHIFTIN(bbp_atten, mask));
241         }
242 }
243
244 int
245 bwi_phy_calibrate(struct bwi_mac *mac)
246 {
247         struct bwi_phy *phy = &mac->mac_phy;
248
249         /* Dummy read */
250         CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
251
252         /* Don't re-init */
253         if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
254                 return 0;
255
256         if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
257                 bwi_mac_reset(mac, 0);
258                 bwi_phy_init_11g(mac);
259                 bwi_mac_reset(mac, 1);
260         }
261
262         phy->phy_flags |= BWI_PHY_F_CALIBRATED;
263         return 0;
264 }
265
266 static void
267 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
268 {
269         struct bwi_phy *phy = &mac->mac_phy;
270
271         KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0,
272            ("phy_tbl_ctrl %d phy_tbl_data_lo %d",
273              phy->phy_tbl_ctrl, phy->phy_tbl_data_lo));
274         PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
275         PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
276 }
277
278 static void
279 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
280 {
281         struct bwi_phy *phy = &mac->mac_phy;
282
283         KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
284                  phy->phy_tbl_ctrl != 0,
285             ("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d",
286               phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl));
287
288         PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
289         PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
290         PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
291 }
292
293 void
294 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
295 {
296         PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
297         PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
298 }
299
300 int16_t
301 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
302 {
303         PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
304         return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
305 }
306
307 static void
308 bwi_phy_init_11a(struct bwi_mac *mac)
309 {
310         /* TODO:11A */
311 }
312
313 static void
314 bwi_phy_init_11g(struct bwi_mac *mac)
315 {
316         struct bwi_softc *sc = mac->mac_sc;
317         struct bwi_phy *phy = &mac->mac_phy;
318         struct bwi_rf *rf = &mac->mac_rf;
319         const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
320
321         if (phy->phy_rev == 1)
322                 bwi_phy_init_11b_rev5(mac);
323         else
324                 bwi_phy_init_11b_rev6(mac);
325
326         if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
327                 bwi_phy_config_11g(mac);
328
329         if (phy->phy_rev >= 2) {
330                 PHY_WRITE(mac, 0x814, 0);
331                 PHY_WRITE(mac, 0x815, 0);
332
333                 if (phy->phy_rev == 2) {
334                         PHY_WRITE(mac, 0x811, 0);
335                         PHY_WRITE(mac, 0x15, 0xc0);
336                 } else if (phy->phy_rev > 5) {
337                         PHY_WRITE(mac, 0x811, 0x400);
338                         PHY_WRITE(mac, 0x15, 0xc0);
339                 }
340         }
341
342         if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
343                 uint16_t val;
344
345                 val = PHY_READ(mac, 0x400) & 0xff;
346                 if (val == 3 || val == 5) {
347                         PHY_WRITE(mac, 0x4c2, 0x1816);
348                         PHY_WRITE(mac, 0x4c3, 0x8006);
349                         if (val == 5) {
350                                 PHY_FILT_SETBITS(mac, 0x4cc,
351                                                  0xff, 0x1f00);
352                         }
353                 }
354         }
355
356         if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
357             phy->phy_rev >= 2)
358                 PHY_WRITE(mac, 0x47e, 0x78);
359
360         if (rf->rf_rev == 8) {
361                 PHY_SETBITS(mac, 0x801, 0x80);
362                 PHY_SETBITS(mac, 0x43e, 0x4);
363         }
364
365         if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
366                 bwi_rf_get_gains(mac);
367
368         if (rf->rf_rev != 8)
369                 bwi_rf_init(mac);
370
371         if (tpctl->tp_ctrl2 == 0xffff) {
372                 bwi_rf_lo_update(mac);
373         } else {
374                 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
375                         RF_WRITE(mac, 0x52,
376                                  (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
377                 } else {
378                         RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
379                 }
380
381                 if (phy->phy_rev >= 6) {
382                         PHY_FILT_SETBITS(mac, 0x36, 0xfff,
383                                          tpctl->tp_ctrl2 << 12);
384                 }
385
386                 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
387                         PHY_WRITE(mac, 0x2e, 0x8075);
388                 else
389                         PHY_WRITE(mac, 0x2e, 0x807f);
390
391                 if (phy->phy_rev < 2)
392                         PHY_WRITE(mac, 0x2f, 0x101);
393                 else
394                         PHY_WRITE(mac, 0x2f, 0x202);
395         }
396
397         if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
398                 bwi_rf_lo_adjust(mac, tpctl);
399                 PHY_WRITE(mac, 0x80f, 0x8078);
400         }
401
402         if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
403                 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
404                 bwi_rf_set_nrssi_thr(mac);
405         } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
406                 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
407                         KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI,
408                             ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
409                         bwi_rf_calc_nrssi_slope(mac);
410                 } else {
411                         KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI,
412                             ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
413                         bwi_rf_set_nrssi_thr(mac);
414                 }
415         }
416
417         if (rf->rf_rev == 8)
418                 PHY_WRITE(mac, 0x805, 0x3230);
419
420         bwi_mac_init_tpctl_11bg(mac);
421
422         if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
423                 PHY_CLRBITS(mac, 0x429, 0x4000);
424                 PHY_CLRBITS(mac, 0x4c3, 0x8000);
425         }
426 }
427
428 static void
429 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
430
431         /* TODO:11B */
432         device_printf(mac->mac_sc->sc_dev,
433                   "%s is not implemented yet\n", __func__);
434 }
435
436 static void
437 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
438 {
439         struct bwi_softc *sc = mac->mac_sc;
440         struct bwi_rf *rf = &mac->mac_rf;
441         uint16_t val, ofs;
442         u_int chan;
443
444         CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
445
446         PHY_WRITE(mac, 0x20, 0x301c);
447         PHY_WRITE(mac, 0x26, 0);
448         PHY_WRITE(mac, 0x30, 0xc6);
449         PHY_WRITE(mac, 0x88, 0x3e00);
450
451         for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
452                 PHY_WRITE(mac, 0x89 + ofs, val);
453
454         CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
455
456         chan = rf->rf_curchan;
457         if (chan == IEEE80211_CHAN_ANY)
458                 chan = 6;       /* Force to channel 6 */
459         bwi_rf_set_chan(mac, chan, 0);
460
461         if (rf->rf_type != BWI_RF_T_BCM2050) {
462                 RF_WRITE(mac, 0x75, 0x80);
463                 RF_WRITE(mac, 0x79, 0x81);
464         }
465
466         RF_WRITE(mac, 0x50, 0x20);
467         RF_WRITE(mac, 0x50, 0x23);
468
469         if (rf->rf_type == BWI_RF_T_BCM2050) {
470                 RF_WRITE(mac, 0x50, 0x20);
471                 RF_WRITE(mac, 0x5a, 0x70);
472                 RF_WRITE(mac, 0x5b, 0x7b);
473                 RF_WRITE(mac, 0x5c, 0xb0);
474                 RF_WRITE(mac, 0x7a, 0xf);
475                 PHY_WRITE(mac, 0x38, 0x677);
476                 bwi_rf_init_bcm2050(mac);
477         }
478
479         PHY_WRITE(mac, 0x14, 0x80);
480         PHY_WRITE(mac, 0x32, 0xca);
481         if (rf->rf_type == BWI_RF_T_BCM2050)
482                 PHY_WRITE(mac, 0x32, 0xe0);
483         PHY_WRITE(mac, 0x35, 0x7c2);
484
485         bwi_rf_lo_update(mac);
486
487         PHY_WRITE(mac, 0x26, 0xcc00);
488         if (rf->rf_type == BWI_RF_T_BCM2050)
489                 PHY_WRITE(mac, 0x26, 0xce00);
490
491         CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
492
493         PHY_WRITE(mac, 0x2a, 0x88a3);
494         if (rf->rf_type == BWI_RF_T_BCM2050)
495                 PHY_WRITE(mac, 0x2a, 0x88c2);
496
497         bwi_mac_set_tpctl_11bg(mac, NULL);
498         if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
499                 bwi_rf_calc_nrssi_slope(mac);
500                 bwi_rf_set_nrssi_thr(mac);
501         }
502         bwi_mac_init_tpctl_11bg(mac);
503 }
504
505 static void
506 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
507 {
508         struct bwi_softc *sc = mac->mac_sc;
509         struct bwi_rf *rf = &mac->mac_rf;
510         struct bwi_phy *phy = &mac->mac_phy;
511         u_int orig_chan;
512
513         if (phy->phy_version == 1)
514                 RF_SETBITS(mac, 0x7a, 0x50);
515
516         if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
517             sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
518                 uint16_t ofs, val;
519
520                 val = 0x2120;
521                 for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
522                         PHY_WRITE(mac, ofs, val);
523                         val += 0x202;
524                 }
525         }
526
527         PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
528
529         if (rf->rf_type == BWI_RF_T_BCM2050)
530                 PHY_WRITE(mac, 0x38, 0x667);
531
532         if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
533                 if (rf->rf_type == BWI_RF_T_BCM2050) {
534                         RF_SETBITS(mac, 0x7a, 0x20);
535                         RF_SETBITS(mac, 0x51, 0x4);
536                 }
537
538                 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
539
540                 PHY_SETBITS(mac, 0x802, 0x100);
541                 PHY_SETBITS(mac, 0x42b, 0x2000);
542                 PHY_WRITE(mac, 0x1c, 0x186a);
543
544                 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
545                 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
546                 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
547         }
548
549         /* TODO: bad_frame_preempt? */
550
551         if (phy->phy_version == 1) {
552                 PHY_WRITE(mac, 0x26, 0xce00);
553                 PHY_WRITE(mac, 0x21, 0x3763);
554                 PHY_WRITE(mac, 0x22, 0x1bc3);
555                 PHY_WRITE(mac, 0x23, 0x6f9);
556                 PHY_WRITE(mac, 0x24, 0x37e);
557         } else {
558                 PHY_WRITE(mac, 0x26, 0xcc00);
559         }
560         PHY_WRITE(mac, 0x30, 0xc6);
561
562         CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
563
564         if (phy->phy_version == 1)
565                 PHY_WRITE(mac, 0x20, 0x3e1c);
566         else
567                 PHY_WRITE(mac, 0x20, 0x301c);
568
569         if (phy->phy_version == 0)
570                 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
571
572         /* Force to channel 7 */
573         orig_chan = rf->rf_curchan;
574         bwi_rf_set_chan(mac, 7, 0);
575
576         if (rf->rf_type != BWI_RF_T_BCM2050) {
577                 RF_WRITE(mac, 0x75, 0x80);
578                 RF_WRITE(mac, 0x79, 0x81);
579         }
580
581         RF_WRITE(mac, 0x50, 0x20);
582         RF_WRITE(mac, 0x50, 0x23);
583
584         if (rf->rf_type == BWI_RF_T_BCM2050) {
585                 RF_WRITE(mac, 0x50, 0x20);
586                 RF_WRITE(mac, 0x5a, 0x70);
587         }
588
589         RF_WRITE(mac, 0x5b, 0x7b);
590         RF_WRITE(mac, 0x5c, 0xb0);
591         RF_SETBITS(mac, 0x7a, 0x7);
592
593         bwi_rf_set_chan(mac, orig_chan, 0);
594
595         PHY_WRITE(mac, 0x14, 0x80);
596         PHY_WRITE(mac, 0x32, 0xca);
597         PHY_WRITE(mac, 0x2a, 0x88a3);
598
599         bwi_mac_set_tpctl_11bg(mac, NULL);
600
601         if (rf->rf_type == BWI_RF_T_BCM2050)
602                 RF_WRITE(mac, 0x5d, 0xd);
603
604         CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
605 }
606
607 static void
608 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
609 {
610         struct bwi_softc *sc = mac->mac_sc;
611         struct bwi_rf *rf = &mac->mac_rf;
612         struct bwi_phy *phy = &mac->mac_phy;
613         uint16_t val, ofs;
614         u_int orig_chan;
615
616         PHY_WRITE(mac, 0x3e, 0x817a);
617         RF_SETBITS(mac, 0x7a, 0x58);
618
619         if (rf->rf_rev == 4 || rf->rf_rev == 5) {
620                 RF_WRITE(mac, 0x51, 0x37);
621                 RF_WRITE(mac, 0x52, 0x70);
622                 RF_WRITE(mac, 0x53, 0xb3);
623                 RF_WRITE(mac, 0x54, 0x9b);
624                 RF_WRITE(mac, 0x5a, 0x88);
625                 RF_WRITE(mac, 0x5b, 0x88);
626                 RF_WRITE(mac, 0x5d, 0x88);
627                 RF_WRITE(mac, 0x5e, 0x88);
628                 RF_WRITE(mac, 0x7d, 0x88);
629                 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
630         } else if (rf->rf_rev == 8) {
631                 RF_WRITE(mac, 0x51, 0);
632                 RF_WRITE(mac, 0x52, 0x40);
633                 RF_WRITE(mac, 0x53, 0xb7);
634                 RF_WRITE(mac, 0x54, 0x98);
635                 RF_WRITE(mac, 0x5a, 0x88);
636                 RF_WRITE(mac, 0x5b, 0x6b);
637                 RF_WRITE(mac, 0x5c, 0xf);
638                 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
639                         RF_WRITE(mac, 0x5d, 0xfa);
640                         RF_WRITE(mac, 0x5e, 0xd8);
641                 } else {
642                         RF_WRITE(mac, 0x5d, 0xf5);
643                         RF_WRITE(mac, 0x5e, 0xb8);
644                 }
645                 RF_WRITE(mac, 0x73, 0x3);
646                 RF_WRITE(mac, 0x7d, 0xa8);
647                 RF_WRITE(mac, 0x7c, 0x1);
648                 RF_WRITE(mac, 0x7e, 0x8);
649         }
650
651         val = 0x1e1f;
652         for (ofs = 0x88; ofs < 0x98; ++ofs) {
653                 PHY_WRITE(mac, ofs, val);
654                 val -= 0x202;
655         }
656
657         val = 0x3e3f;
658         for (ofs = 0x98; ofs < 0xa8; ++ofs) {
659                 PHY_WRITE(mac, ofs, val);
660                 val -= 0x202;
661         }
662
663         val = 0x2120;
664         for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
665                 PHY_WRITE(mac, ofs, (val & 0x3f3f));
666                 val += 0x202;
667
668                 /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */
669                 DELAY(10);
670         }
671
672         if (phy->phy_mode == IEEE80211_MODE_11G) {
673                 RF_SETBITS(mac, 0x7a, 0x20);
674                 RF_SETBITS(mac, 0x51, 0x4);
675                 PHY_SETBITS(mac, 0x802, 0x100);
676                 PHY_SETBITS(mac, 0x42b, 0x2000);
677                 PHY_WRITE(mac, 0x5b, 0);
678                 PHY_WRITE(mac, 0x5c, 0);
679         }
680
681         /* Force to channel 7 */
682         orig_chan = rf->rf_curchan;
683         if (orig_chan >= 8)
684                 bwi_rf_set_chan(mac, 1, 0);
685         else
686                 bwi_rf_set_chan(mac, 13, 0);
687
688         RF_WRITE(mac, 0x50, 0x20);
689         RF_WRITE(mac, 0x50, 0x23);
690
691         DELAY(40);
692
693         if (rf->rf_rev < 6 || rf->rf_rev == 8) {
694                 RF_SETBITS(mac, 0x7c, 0x2);
695                 RF_WRITE(mac, 0x50, 0x20);
696         }
697         if (rf->rf_rev <= 2) {
698                 RF_WRITE(mac, 0x7c, 0x20);
699                 RF_WRITE(mac, 0x5a, 0x70);
700                 RF_WRITE(mac, 0x5b, 0x7b);
701                 RF_WRITE(mac, 0x5c, 0xb0);
702         }
703
704         RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
705
706         bwi_rf_set_chan(mac, orig_chan, 0);
707
708         PHY_WRITE(mac, 0x14, 0x200);
709         if (rf->rf_rev >= 6)
710                 PHY_WRITE(mac, 0x2a, 0x88c2);
711         else
712                 PHY_WRITE(mac, 0x2a, 0x8ac0);
713         PHY_WRITE(mac, 0x38, 0x668);
714
715         bwi_mac_set_tpctl_11bg(mac, NULL);
716
717         if (rf->rf_rev <= 5) {
718                 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
719                 if (rf->rf_rev <= 2)
720                         RF_WRITE(mac, 0x5d, 0xd);
721         }
722
723         if (phy->phy_version == 4) {
724                 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
725                 PHY_CLRBITS(mac, 0x61, 0xf000);
726         } else {
727                 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
728         }
729
730         if (phy->phy_mode == IEEE80211_MODE_11B) {
731                 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
732                 PHY_WRITE(mac, 0x16, 0x410);
733                 PHY_WRITE(mac, 0x17, 0x820);
734                 PHY_WRITE(mac, 0x62, 0x7);
735
736                 bwi_rf_init_bcm2050(mac);
737                 bwi_rf_lo_update(mac);
738                 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
739                         bwi_rf_calc_nrssi_slope(mac);
740                         bwi_rf_set_nrssi_thr(mac);
741                 }
742                 bwi_mac_init_tpctl_11bg(mac);
743         } else {
744                 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
745         }
746 }
747
748 static void
749 bwi_phy_config_11g(struct bwi_mac *mac)
750 {
751         struct bwi_softc *sc = mac->mac_sc;
752         struct bwi_phy *phy = &mac->mac_phy;
753         const uint16_t *tbl;
754         uint16_t wrd_ofs1, wrd_ofs2;
755         int i, n;
756
757         if (phy->phy_rev == 1) {
758                 PHY_WRITE(mac, 0x406, 0x4f19);
759                 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
760                 PHY_WRITE(mac, 0x42c, 0x5a);
761                 PHY_WRITE(mac, 0x427, 0x1a);
762
763                 /* Fill frequency table */
764                 for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) {
765                         bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
766                                         bwi_phy_freq_11g_rev1[i]);
767                 }
768
769                 /* Fill noise table */
770                 for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) {
771                         bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
772                                         bwi_phy_noise_11g_rev1[i]);
773                 }
774
775                 /* Fill rotor table */
776                 for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) {
777                         /* NB: data length is 4 bytes */
778                         bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
779                                         bwi_phy_rotor_11g_rev1[i]);
780                 }
781         } else {
782                 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
783
784                 if (phy->phy_rev == 2) {
785                         PHY_WRITE(mac, 0x4c0, 0x1861);
786                         PHY_WRITE(mac, 0x4c1, 0x271);
787                 } else if (phy->phy_rev > 2) {
788                         PHY_WRITE(mac, 0x4c0, 0x98);
789                         PHY_WRITE(mac, 0x4c1, 0x70);
790                         PHY_WRITE(mac, 0x4c9, 0x80);
791                 }
792                 PHY_SETBITS(mac, 0x42b, 0x800);
793
794                 /* Fill RSSI table */
795                 for (i = 0; i < 64; ++i)
796                         bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
797
798                 /* Fill noise table */
799                 for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) {
800                         bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
801                                         bwi_phy_noise_11g[i]);
802                 }
803         }
804
805         /*
806          * Fill noise scale table
807          */
808         if (phy->phy_rev <= 2) {
809                 tbl = bwi_phy_noise_scale_11g_rev2;
810                 n = nitems(bwi_phy_noise_scale_11g_rev2);
811         } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
812                 tbl = bwi_phy_noise_scale_11g_rev7;
813                 n = nitems(bwi_phy_noise_scale_11g_rev7);
814         } else {
815                 tbl = bwi_phy_noise_scale_11g;
816                 n = nitems(bwi_phy_noise_scale_11g);
817         }
818         for (i = 0; i < n; ++i)
819                 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
820
821         /*
822          * Fill sigma square table
823          */
824         if (phy->phy_rev == 2) {
825                 tbl = bwi_phy_sigma_sq_11g_rev2;
826                 n = nitems(bwi_phy_sigma_sq_11g_rev2);
827         } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
828                 tbl = bwi_phy_sigma_sq_11g_rev7;
829                 n = nitems(bwi_phy_sigma_sq_11g_rev7);
830         } else {
831                 tbl = NULL;
832                 n = 0;
833         }
834         for (i = 0; i < n; ++i)
835                 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
836
837         if (phy->phy_rev == 1) {
838                 /* Fill delay table */
839                 for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) {
840                         bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
841                                         bwi_phy_delay_11g_rev1[i]);
842                 }
843
844                 /* Fill WRSSI (Wide-Band RSSI) table */
845                 for (i = 4; i < 20; ++i)
846                         bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
847
848                 bwi_phy_config_agc(mac);
849
850                 wrd_ofs1 = 0x5001;
851                 wrd_ofs2 = 0x5002;
852         } else {
853                 /* Fill WRSSI (Wide-Band RSSI) table */
854                 for (i = 0; i < 0x20; ++i)
855                         bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
856
857                 bwi_phy_config_agc(mac);
858
859                 PHY_READ(mac, 0x400);   /* Dummy read */
860                 PHY_WRITE(mac, 0x403, 0x1000);
861                 bwi_tbl_write_2(mac, 0x3c02, 0xf);
862                 bwi_tbl_write_2(mac, 0x3c03, 0x14);
863
864                 wrd_ofs1 = 0x401;
865                 wrd_ofs2 = 0x402;
866         }
867
868         if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
869                 bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
870                 bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
871         }
872
873         /* phy->phy_flags & BWI_PHY_F_LINKED ? */
874         if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
875                 PHY_WRITE(mac, 0x46e, 0x3cf);
876 }
877
878 /*
879  * Configure Automatic Gain Controller
880  */
881 static void
882 bwi_phy_config_agc(struct bwi_mac *mac)
883 {
884         struct bwi_phy *phy = &mac->mac_phy;
885         uint16_t ofs;
886
887         ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
888
889         bwi_tbl_write_2(mac, ofs, 0xfe);
890         bwi_tbl_write_2(mac, ofs + 1, 0xd);
891         bwi_tbl_write_2(mac, ofs + 2, 0x13);
892         bwi_tbl_write_2(mac, ofs + 3, 0x19);
893
894         if (phy->phy_rev == 1) {
895                 bwi_tbl_write_2(mac, 0x1800, 0x2710);
896                 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
897                 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
898                 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
899                 PHY_WRITE(mac, 0x455, 0x4);
900         }
901
902         PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
903         PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
904         PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
905         PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
906
907         RF_SETBITS(mac, 0x7a, 0x8);
908
909         PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
910         PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
911         PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
912         PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
913
914         if (phy->phy_rev == 1)
915                 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
916
917         PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
918         PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
919         PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
920         PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
921         PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
922         PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
923         PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
924         PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
925         PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
926
927         if (phy->phy_rev == 1) {
928                 PHY_WRITE(mac, 0x430, 0x92b);
929                 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
930         } else {
931                 PHY_CLRBITS(mac, 0x41b, 0x1e);
932                 PHY_WRITE(mac, 0x41f, 0x287a);
933                 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
934
935                 if (phy->phy_rev >= 6) {
936                         PHY_WRITE(mac, 0x422, 0x287a);
937                         PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
938                 }
939         }
940
941         PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
942         PHY_WRITE(mac, 0x48e, 0x1c00);
943
944         if (phy->phy_rev == 1) {
945                 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
946                 PHY_WRITE(mac, 0x48b, 0x5e);
947                 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
948                 PHY_WRITE(mac, 0x48d, 0x2);
949         }
950
951         bwi_tbl_write_2(mac, ofs + 0x800, 0);
952         bwi_tbl_write_2(mac, ofs + 0x801, 7);
953         bwi_tbl_write_2(mac, ofs + 0x802, 16);
954         bwi_tbl_write_2(mac, ofs + 0x803, 28);
955
956         if (phy->phy_rev >= 6) {
957                 PHY_CLRBITS(mac, 0x426, 0x3);
958                 PHY_CLRBITS(mac, 0x426, 0x1000);
959         }
960 }
961
962 void
963 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
964 {
965         struct bwi_phy *phy = &mac->mac_phy;
966         uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
967         int i;
968
969         if (phy->phy_rev <= 1) {
970                 tbl_gain_ofs1 = 0x5000;
971                 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
972         } else {
973                 tbl_gain_ofs1 = 0x400;
974                 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
975         }
976
977         for (i = 0; i < 4; ++i) {
978                 if (gains != NULL) {
979                         tbl_gain = gains->tbl_gain1;
980                 } else {
981                         /* Bit swap */
982                         tbl_gain = (i & 0x1) << 1;
983                         tbl_gain |= (i & 0x2) >> 1;
984                 }
985                 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
986         }
987
988         for (i = 0; i < 16; ++i) {
989                 if (gains != NULL)
990                         tbl_gain = gains->tbl_gain2;
991                 else
992                         tbl_gain = i;
993                 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
994         }
995
996         if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
997                 uint16_t phy_gain1, phy_gain2;
998
999                 if (gains != NULL) {
1000                         phy_gain1 =
1001                         ((uint16_t)gains->phy_gain << 14) |
1002                         ((uint16_t)gains->phy_gain << 6);
1003                         phy_gain2 = phy_gain1;
1004                 } else {
1005                         phy_gain1 = 0x4040;
1006                         phy_gain2 = 0x4000;
1007                 }
1008                 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1009                 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1010                 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1011         }
1012         bwi_mac_dummy_xmit(mac);
1013 }
1014
1015 void
1016 bwi_phy_clear_state(struct bwi_phy *phy)
1017 {
1018         phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1019 }