Deleted Added
full compact
bwiphy.c (191762) bwiphy.c (192042)
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>
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: head/sys/dev/bwi/bwiphy.c 191762 2009-05-03 04:01:43Z imp $");
38__FBSDID("$FreeBSD: head/sys/dev/bwi/bwiphy.c 192042 2009-05-13 14:25:55Z nwhitehorn $");
39
40#include "opt_inet.h"
41
42#include <sys/param.h>
43#include <sys/endian.h>
44#include <sys/kernel.h>
45#include <sys/bus.h>
46#include <sys/malloc.h>
47#include <sys/proc.h>
48#include <sys/rman.h>
49#include <sys/socket.h>
50#include <sys/sockio.h>
51#include <sys/sysctl.h>
52#include <sys/systm.h>
53
54#include <net/if.h>
55#include <net/if_dl.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58#include <net/if_arp.h>
59#include <net/ethernet.h>
60#include <net/if_llc.h>
61
62#include <net80211/ieee80211_var.h>
63#include <net80211/ieee80211_radiotap.h>
64#include <net80211/ieee80211_amrr.h>
65
66#include <machine/bus.h>
67
68#include <dev/bwi/bitops.h>
69#include <dev/bwi/if_bwireg.h>
70#include <dev/bwi/if_bwivar.h>
71#include <dev/bwi/bwimac.h>
72#include <dev/bwi/bwirf.h>
73#include <dev/bwi/bwiphy.h>
74
75static void bwi_phy_init_11a(struct bwi_mac *);
76static void bwi_phy_init_11g(struct bwi_mac *);
77static void bwi_phy_init_11b_rev2(struct bwi_mac *);
78static void bwi_phy_init_11b_rev4(struct bwi_mac *);
79static void bwi_phy_init_11b_rev5(struct bwi_mac *);
80static void bwi_phy_init_11b_rev6(struct bwi_mac *);
81
82static void bwi_phy_config_11g(struct bwi_mac *);
83static void bwi_phy_config_agc(struct bwi_mac *);
84
85static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
86static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
87
88#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
89
90static const struct {
91 uint8_t rev;
92 void (*init)(struct bwi_mac *);
93} bwi_sup_bphy[] = {
94 SUP_BPHY(2),
95 SUP_BPHY(4),
96 SUP_BPHY(5),
97 SUP_BPHY(6)
98};
99
100#undef SUP_BPHY
101
102#define BWI_PHYTBL_WRSSI 0x1000
103#define BWI_PHYTBL_NOISE_SCALE 0x1400
104#define BWI_PHYTBL_NOISE 0x1800
105#define BWI_PHYTBL_ROTOR 0x2000
106#define BWI_PHYTBL_DELAY 0x2400
107#define BWI_PHYTBL_RSSI 0x4000
108#define BWI_PHYTBL_SIGMA_SQ 0x5000
109#define BWI_PHYTBL_WRSSI_REV1 0x5400
110#define BWI_PHYTBL_FREQ 0x5800
111
112static const uint16_t bwi_phy_freq_11g_rev1[] =
113 { BWI_PHY_FREQ_11G_REV1 };
114static const uint16_t bwi_phy_noise_11g_rev1[] =
115 { BWI_PHY_NOISE_11G_REV1 };
116static const uint16_t bwi_phy_noise_11g[] =
117 { BWI_PHY_NOISE_11G };
118static const uint32_t bwi_phy_rotor_11g_rev1[] =
119 { BWI_PHY_ROTOR_11G_REV1 };
120static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
121 { BWI_PHY_NOISE_SCALE_11G_REV2 };
122static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
123 { BWI_PHY_NOISE_SCALE_11G_REV7 };
124static const uint16_t bwi_phy_noise_scale_11g[] =
125 { BWI_PHY_NOISE_SCALE_11G };
126static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
127 { BWI_PHY_SIGMA_SQ_11G_REV2 };
128static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
129 { BWI_PHY_SIGMA_SQ_11G_REV7 };
130static const uint32_t bwi_phy_delay_11g_rev1[] =
131 { BWI_PHY_DELAY_11G_REV1 };
132
133void
134bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
135{
136 struct bwi_softc *sc = mac->mac_sc;
137
138 /* TODO: 11A */
139 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
140 CSR_WRITE_2(sc, BWI_PHY_DATA, data);
141}
142
143uint16_t
144bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
145{
146 struct bwi_softc *sc = mac->mac_sc;
147
148 /* TODO: 11A */
149 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
150 return CSR_READ_2(sc, BWI_PHY_DATA);
151}
152
153int
154bwi_phy_attach(struct bwi_mac *mac)
155{
156 struct bwi_softc *sc = mac->mac_sc;
157 struct bwi_phy *phy = &mac->mac_phy;
158 uint8_t phyrev, phytype, phyver;
159 uint16_t val;
160 int i;
161
162 /* Get PHY type/revision/version */
163 val = CSR_READ_2(sc, BWI_PHYINFO);
164 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
165 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
166 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
167 device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
168 phytype, phyrev, phyver);
169
170 /*
171 * Verify whether the revision of the PHY type is supported
172 * Convert PHY type to ieee80211_phymode
173 */
174 switch (phytype) {
175 case BWI_PHYINFO_TYPE_11A:
176 if (phyrev >= 4) {
177 device_printf(sc->sc_dev, "unsupported 11A PHY, "
178 "rev %u\n", phyrev);
179 return ENXIO;
180 }
181 phy->phy_init = bwi_phy_init_11a;
182 phy->phy_mode = IEEE80211_MODE_11A;
183 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
184 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
185 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
186 break;
187 case BWI_PHYINFO_TYPE_11B:
188#define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
189 for (i = 0; i < N(bwi_sup_bphy); ++i) {
190 if (phyrev == bwi_sup_bphy[i].rev) {
191 phy->phy_init = bwi_sup_bphy[i].init;
192 break;
193 }
194 }
195 if (i == N(bwi_sup_bphy)) {
196 device_printf(sc->sc_dev, "unsupported 11B PHY, "
197 "rev %u\n", phyrev);
198 return ENXIO;
199 }
200#undef N
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
225void
226bwi_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
244int
245bwi_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
266static void
267bwi_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
278static void
279bwi_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
293void
294bwi_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
300int16_t
301bwi_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
307static void
308bwi_phy_init_11a(struct bwi_mac *mac)
309{
310 /* TODO:11A */
311}
312
313static void
314bwi_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_ctrl1);
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
428static void
429bwi_phy_init_11b_rev2(struct bwi_mac *mac)
430{
431 /* TODO:11B */
432 if_printf(mac->mac_sc->sc_ifp,
433 "%s is not implemented yet\n", __func__);
434}
435
436static void
437bwi_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
505static void
506bwi_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
607static void
608bwi_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;
39
40#include "opt_inet.h"
41
42#include <sys/param.h>
43#include <sys/endian.h>
44#include <sys/kernel.h>
45#include <sys/bus.h>
46#include <sys/malloc.h>
47#include <sys/proc.h>
48#include <sys/rman.h>
49#include <sys/socket.h>
50#include <sys/sockio.h>
51#include <sys/sysctl.h>
52#include <sys/systm.h>
53
54#include <net/if.h>
55#include <net/if_dl.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58#include <net/if_arp.h>
59#include <net/ethernet.h>
60#include <net/if_llc.h>
61
62#include <net80211/ieee80211_var.h>
63#include <net80211/ieee80211_radiotap.h>
64#include <net80211/ieee80211_amrr.h>
65
66#include <machine/bus.h>
67
68#include <dev/bwi/bitops.h>
69#include <dev/bwi/if_bwireg.h>
70#include <dev/bwi/if_bwivar.h>
71#include <dev/bwi/bwimac.h>
72#include <dev/bwi/bwirf.h>
73#include <dev/bwi/bwiphy.h>
74
75static void bwi_phy_init_11a(struct bwi_mac *);
76static void bwi_phy_init_11g(struct bwi_mac *);
77static void bwi_phy_init_11b_rev2(struct bwi_mac *);
78static void bwi_phy_init_11b_rev4(struct bwi_mac *);
79static void bwi_phy_init_11b_rev5(struct bwi_mac *);
80static void bwi_phy_init_11b_rev6(struct bwi_mac *);
81
82static void bwi_phy_config_11g(struct bwi_mac *);
83static void bwi_phy_config_agc(struct bwi_mac *);
84
85static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
86static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
87
88#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
89
90static const struct {
91 uint8_t rev;
92 void (*init)(struct bwi_mac *);
93} bwi_sup_bphy[] = {
94 SUP_BPHY(2),
95 SUP_BPHY(4),
96 SUP_BPHY(5),
97 SUP_BPHY(6)
98};
99
100#undef SUP_BPHY
101
102#define BWI_PHYTBL_WRSSI 0x1000
103#define BWI_PHYTBL_NOISE_SCALE 0x1400
104#define BWI_PHYTBL_NOISE 0x1800
105#define BWI_PHYTBL_ROTOR 0x2000
106#define BWI_PHYTBL_DELAY 0x2400
107#define BWI_PHYTBL_RSSI 0x4000
108#define BWI_PHYTBL_SIGMA_SQ 0x5000
109#define BWI_PHYTBL_WRSSI_REV1 0x5400
110#define BWI_PHYTBL_FREQ 0x5800
111
112static const uint16_t bwi_phy_freq_11g_rev1[] =
113 { BWI_PHY_FREQ_11G_REV1 };
114static const uint16_t bwi_phy_noise_11g_rev1[] =
115 { BWI_PHY_NOISE_11G_REV1 };
116static const uint16_t bwi_phy_noise_11g[] =
117 { BWI_PHY_NOISE_11G };
118static const uint32_t bwi_phy_rotor_11g_rev1[] =
119 { BWI_PHY_ROTOR_11G_REV1 };
120static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
121 { BWI_PHY_NOISE_SCALE_11G_REV2 };
122static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
123 { BWI_PHY_NOISE_SCALE_11G_REV7 };
124static const uint16_t bwi_phy_noise_scale_11g[] =
125 { BWI_PHY_NOISE_SCALE_11G };
126static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
127 { BWI_PHY_SIGMA_SQ_11G_REV2 };
128static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
129 { BWI_PHY_SIGMA_SQ_11G_REV7 };
130static const uint32_t bwi_phy_delay_11g_rev1[] =
131 { BWI_PHY_DELAY_11G_REV1 };
132
133void
134bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
135{
136 struct bwi_softc *sc = mac->mac_sc;
137
138 /* TODO: 11A */
139 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
140 CSR_WRITE_2(sc, BWI_PHY_DATA, data);
141}
142
143uint16_t
144bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
145{
146 struct bwi_softc *sc = mac->mac_sc;
147
148 /* TODO: 11A */
149 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
150 return CSR_READ_2(sc, BWI_PHY_DATA);
151}
152
153int
154bwi_phy_attach(struct bwi_mac *mac)
155{
156 struct bwi_softc *sc = mac->mac_sc;
157 struct bwi_phy *phy = &mac->mac_phy;
158 uint8_t phyrev, phytype, phyver;
159 uint16_t val;
160 int i;
161
162 /* Get PHY type/revision/version */
163 val = CSR_READ_2(sc, BWI_PHYINFO);
164 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
165 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
166 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
167 device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
168 phytype, phyrev, phyver);
169
170 /*
171 * Verify whether the revision of the PHY type is supported
172 * Convert PHY type to ieee80211_phymode
173 */
174 switch (phytype) {
175 case BWI_PHYINFO_TYPE_11A:
176 if (phyrev >= 4) {
177 device_printf(sc->sc_dev, "unsupported 11A PHY, "
178 "rev %u\n", phyrev);
179 return ENXIO;
180 }
181 phy->phy_init = bwi_phy_init_11a;
182 phy->phy_mode = IEEE80211_MODE_11A;
183 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
184 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
185 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
186 break;
187 case BWI_PHYINFO_TYPE_11B:
188#define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
189 for (i = 0; i < N(bwi_sup_bphy); ++i) {
190 if (phyrev == bwi_sup_bphy[i].rev) {
191 phy->phy_init = bwi_sup_bphy[i].init;
192 break;
193 }
194 }
195 if (i == N(bwi_sup_bphy)) {
196 device_printf(sc->sc_dev, "unsupported 11B PHY, "
197 "rev %u\n", phyrev);
198 return ENXIO;
199 }
200#undef N
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
225void
226bwi_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
244int
245bwi_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
266static void
267bwi_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
278static void
279bwi_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
293void
294bwi_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
300int16_t
301bwi_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
307static void
308bwi_phy_init_11a(struct bwi_mac *mac)
309{
310 /* TODO:11A */
311}
312
313static void
314bwi_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_ctrl1);
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
428static void
429bwi_phy_init_11b_rev2(struct bwi_mac *mac)
430{
431 /* TODO:11B */
432 if_printf(mac->mac_sc->sc_ifp,
433 "%s is not implemented yet\n", __func__);
434}
435
436static void
437bwi_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
505static void
506bwi_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
607static void
608bwi_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 DELAY(10);
667 }
668
669 if (phy->phy_mode == IEEE80211_MODE_11G) {
670 RF_SETBITS(mac, 0x7a, 0x20);
671 RF_SETBITS(mac, 0x51, 0x4);
672 PHY_SETBITS(mac, 0x802, 0x100);
673 PHY_SETBITS(mac, 0x42b, 0x2000);
674 PHY_WRITE(mac, 0x5b, 0);
675 PHY_WRITE(mac, 0x5c, 0);
676 }
677
678 /* Force to channel 7 */
679 orig_chan = rf->rf_curchan;
680 if (orig_chan >= 8)
681 bwi_rf_set_chan(mac, 1, 0);
682 else
683 bwi_rf_set_chan(mac, 13, 0);
684
685 RF_WRITE(mac, 0x50, 0x20);
686 RF_WRITE(mac, 0x50, 0x23);
687
688 DELAY(40);
689
690 if (rf->rf_rev < 6 || rf->rf_rev == 8) {
691 RF_SETBITS(mac, 0x7c, 0x2);
692 RF_WRITE(mac, 0x50, 0x20);
693 }
694 if (rf->rf_rev <= 2) {
695 RF_WRITE(mac, 0x7c, 0x20);
696 RF_WRITE(mac, 0x5a, 0x70);
697 RF_WRITE(mac, 0x5b, 0x7b);
698 RF_WRITE(mac, 0x5c, 0xb0);
699 }
700
701 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
702
703 bwi_rf_set_chan(mac, orig_chan, 0);
704
705 PHY_WRITE(mac, 0x14, 0x200);
706 if (rf->rf_rev >= 6)
707 PHY_WRITE(mac, 0x2a, 0x88c2);
708 else
709 PHY_WRITE(mac, 0x2a, 0x8ac0);
710 PHY_WRITE(mac, 0x38, 0x668);
711
712 bwi_mac_set_tpctl_11bg(mac, NULL);
713
714 if (rf->rf_rev <= 5) {
715 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
716 if (rf->rf_rev <= 2)
717 RF_WRITE(mac, 0x5d, 0xd);
718 }
719
720 if (phy->phy_version == 4) {
721 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
722 PHY_CLRBITS(mac, 0x61, 0xf000);
723 } else {
724 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
725 }
726
727 if (phy->phy_mode == IEEE80211_MODE_11B) {
728 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
729 PHY_WRITE(mac, 0x16, 0x410);
730 PHY_WRITE(mac, 0x17, 0x820);
731 PHY_WRITE(mac, 0x62, 0x7);
732
733 bwi_rf_init_bcm2050(mac);
734 bwi_rf_lo_update(mac);
735 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
736 bwi_rf_calc_nrssi_slope(mac);
737 bwi_rf_set_nrssi_thr(mac);
738 }
739 bwi_mac_init_tpctl_11bg(mac);
740 } else {
741 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
742 }
743}
744
745#define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
746
747static void
748bwi_phy_config_11g(struct bwi_mac *mac)
749{
750 struct bwi_softc *sc = mac->mac_sc;
751 struct bwi_phy *phy = &mac->mac_phy;
752 const uint16_t *tbl;
753 uint16_t wrd_ofs1, wrd_ofs2;
754 int i, n;
755
756 if (phy->phy_rev == 1) {
757 PHY_WRITE(mac, 0x406, 0x4f19);
758 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
759 PHY_WRITE(mac, 0x42c, 0x5a);
760 PHY_WRITE(mac, 0x427, 0x1a);
761
762 /* Fill frequency table */
763 for (i = 0; i < N(bwi_phy_freq_11g_rev1); ++i) {
764 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
765 bwi_phy_freq_11g_rev1[i]);
766 }
767
768 /* Fill noise table */
769 for (i = 0; i < N(bwi_phy_noise_11g_rev1); ++i) {
770 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
771 bwi_phy_noise_11g_rev1[i]);
772 }
773
774 /* Fill rotor table */
775 for (i = 0; i < N(bwi_phy_rotor_11g_rev1); ++i) {
776 /* NB: data length is 4 bytes */
777 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
778 bwi_phy_rotor_11g_rev1[i]);
779 }
780 } else {
781 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
782
783 if (phy->phy_rev == 2) {
784 PHY_WRITE(mac, 0x4c0, 0x1861);
785 PHY_WRITE(mac, 0x4c1, 0x271);
786 } else if (phy->phy_rev > 2) {
787 PHY_WRITE(mac, 0x4c0, 0x98);
788 PHY_WRITE(mac, 0x4c1, 0x70);
789 PHY_WRITE(mac, 0x4c9, 0x80);
790 }
791 PHY_SETBITS(mac, 0x42b, 0x800);
792
793 /* Fill RSSI table */
794 for (i = 0; i < 64; ++i)
795 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
796
797 /* Fill noise table */
798 for (i = 0; i < sizeof(bwi_phy_noise_11g); ++i) {
799 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
800 bwi_phy_noise_11g[i]);
801 }
802 }
803
804 /*
805 * Fill noise scale table
806 */
807 if (phy->phy_rev <= 2) {
808 tbl = bwi_phy_noise_scale_11g_rev2;
809 n = N(bwi_phy_noise_scale_11g_rev2);
810 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
811 tbl = bwi_phy_noise_scale_11g_rev7;
812 n = N(bwi_phy_noise_scale_11g_rev7);
813 } else {
814 tbl = bwi_phy_noise_scale_11g;
815 n = N(bwi_phy_noise_scale_11g);
816 }
817 for (i = 0; i < n; ++i)
818 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
819
820 /*
821 * Fill sigma square table
822 */
823 if (phy->phy_rev == 2) {
824 tbl = bwi_phy_sigma_sq_11g_rev2;
825 n = N(bwi_phy_sigma_sq_11g_rev2);
826 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
827 tbl = bwi_phy_sigma_sq_11g_rev7;
828 n = N(bwi_phy_sigma_sq_11g_rev7);
829 } else {
830 tbl = NULL;
831 n = 0;
832 }
833 for (i = 0; i < n; ++i)
834 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
835
836 if (phy->phy_rev == 1) {
837 /* Fill delay table */
838 for (i = 0; i < N(bwi_phy_delay_11g_rev1); ++i) {
839 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
840 bwi_phy_delay_11g_rev1[i]);
841 }
842
843 /* Fill WRSSI (Wide-Band RSSI) table */
844 for (i = 4; i < 20; ++i)
845 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
846
847 bwi_phy_config_agc(mac);
848
849 wrd_ofs1 = 0x5001;
850 wrd_ofs2 = 0x5002;
851 } else {
852 /* Fill WRSSI (Wide-Band RSSI) table */
853 for (i = 0; i < 0x20; ++i)
854 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
855
856 bwi_phy_config_agc(mac);
857
858 PHY_READ(mac, 0x400); /* Dummy read */
859 PHY_WRITE(mac, 0x403, 0x1000);
860 bwi_tbl_write_2(mac, 0x3c02, 0xf);
861 bwi_tbl_write_2(mac, 0x3c03, 0x14);
862
863 wrd_ofs1 = 0x401;
864 wrd_ofs2 = 0x402;
865 }
866
867 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
868 bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
869 bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
870 }
871
872 /* phy->phy_flags & BWI_PHY_F_LINKED ? */
873 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
874 PHY_WRITE(mac, 0x46e, 0x3cf);
875}
876
877#undef N
878
879/*
880 * Configure Automatic Gain Controller
881 */
882static void
883bwi_phy_config_agc(struct bwi_mac *mac)
884{
885 struct bwi_phy *phy = &mac->mac_phy;
886 uint16_t ofs;
887
888 ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
889
890 bwi_tbl_write_2(mac, ofs, 0xfe);
891 bwi_tbl_write_2(mac, ofs + 1, 0xd);
892 bwi_tbl_write_2(mac, ofs + 2, 0x13);
893 bwi_tbl_write_2(mac, ofs + 3, 0x19);
894
895 if (phy->phy_rev == 1) {
896 bwi_tbl_write_2(mac, 0x1800, 0x2710);
897 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
898 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
899 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
900 PHY_WRITE(mac, 0x455, 0x4);
901 }
902
903 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
904 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
905 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
906 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
907
908 RF_SETBITS(mac, 0x7a, 0x8);
909
910 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
911 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
912 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
913 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
914
915 if (phy->phy_rev == 1)
916 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
917
918 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
919 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
920 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
921 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
922 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
923 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
924 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
925 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
926 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
927
928 if (phy->phy_rev == 1) {
929 PHY_WRITE(mac, 0x430, 0x92b);
930 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
931 } else {
932 PHY_CLRBITS(mac, 0x41b, 0x1e);
933 PHY_WRITE(mac, 0x41f, 0x287a);
934 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
935
936 if (phy->phy_rev >= 6) {
937 PHY_WRITE(mac, 0x422, 0x287a);
938 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
939 }
940 }
941
942 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
943 PHY_WRITE(mac, 0x48e, 0x1c00);
944
945 if (phy->phy_rev == 1) {
946 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
947 PHY_WRITE(mac, 0x48b, 0x5e);
948 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
949 PHY_WRITE(mac, 0x48d, 0x2);
950 }
951
952 bwi_tbl_write_2(mac, ofs + 0x800, 0);
953 bwi_tbl_write_2(mac, ofs + 0x801, 7);
954 bwi_tbl_write_2(mac, ofs + 0x802, 16);
955 bwi_tbl_write_2(mac, ofs + 0x803, 28);
956
957 if (phy->phy_rev >= 6) {
958 PHY_CLRBITS(mac, 0x426, 0x3);
959 PHY_CLRBITS(mac, 0x426, 0x1000);
960 }
961}
962
963void
964bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
965{
966 struct bwi_phy *phy = &mac->mac_phy;
967 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
968 int i;
969
970 if (phy->phy_rev <= 1) {
971 tbl_gain_ofs1 = 0x5000;
972 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
973 } else {
974 tbl_gain_ofs1 = 0x400;
975 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
976 }
977
978 for (i = 0; i < 4; ++i) {
979 if (gains != NULL) {
980 tbl_gain = gains->tbl_gain1;
981 } else {
982 /* Bit swap */
983 tbl_gain = (i & 0x1) << 1;
984 tbl_gain |= (i & 0x2) >> 1;
985 }
986 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
987 }
988
989 for (i = 0; i < 16; ++i) {
990 if (gains != NULL)
991 tbl_gain = gains->tbl_gain2;
992 else
993 tbl_gain = i;
994 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
995 }
996
997 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
998 uint16_t phy_gain1, phy_gain2;
999
1000 if (gains != NULL) {
1001 phy_gain1 =
1002 ((uint16_t)gains->phy_gain << 14) |
1003 ((uint16_t)gains->phy_gain << 6);
1004 phy_gain2 = phy_gain1;
1005 } else {
1006 phy_gain1 = 0x4040;
1007 phy_gain2 = 0x4000;
1008 }
1009 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1010 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1011 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1012 }
1013 bwi_mac_dummy_xmit(mac);
1014}
1015
1016void
1017bwi_phy_clear_state(struct bwi_phy *phy)
1018{
1019 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1020}
668 }
669
670 if (phy->phy_mode == IEEE80211_MODE_11G) {
671 RF_SETBITS(mac, 0x7a, 0x20);
672 RF_SETBITS(mac, 0x51, 0x4);
673 PHY_SETBITS(mac, 0x802, 0x100);
674 PHY_SETBITS(mac, 0x42b, 0x2000);
675 PHY_WRITE(mac, 0x5b, 0);
676 PHY_WRITE(mac, 0x5c, 0);
677 }
678
679 /* Force to channel 7 */
680 orig_chan = rf->rf_curchan;
681 if (orig_chan >= 8)
682 bwi_rf_set_chan(mac, 1, 0);
683 else
684 bwi_rf_set_chan(mac, 13, 0);
685
686 RF_WRITE(mac, 0x50, 0x20);
687 RF_WRITE(mac, 0x50, 0x23);
688
689 DELAY(40);
690
691 if (rf->rf_rev < 6 || rf->rf_rev == 8) {
692 RF_SETBITS(mac, 0x7c, 0x2);
693 RF_WRITE(mac, 0x50, 0x20);
694 }
695 if (rf->rf_rev <= 2) {
696 RF_WRITE(mac, 0x7c, 0x20);
697 RF_WRITE(mac, 0x5a, 0x70);
698 RF_WRITE(mac, 0x5b, 0x7b);
699 RF_WRITE(mac, 0x5c, 0xb0);
700 }
701
702 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
703
704 bwi_rf_set_chan(mac, orig_chan, 0);
705
706 PHY_WRITE(mac, 0x14, 0x200);
707 if (rf->rf_rev >= 6)
708 PHY_WRITE(mac, 0x2a, 0x88c2);
709 else
710 PHY_WRITE(mac, 0x2a, 0x8ac0);
711 PHY_WRITE(mac, 0x38, 0x668);
712
713 bwi_mac_set_tpctl_11bg(mac, NULL);
714
715 if (rf->rf_rev <= 5) {
716 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
717 if (rf->rf_rev <= 2)
718 RF_WRITE(mac, 0x5d, 0xd);
719 }
720
721 if (phy->phy_version == 4) {
722 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
723 PHY_CLRBITS(mac, 0x61, 0xf000);
724 } else {
725 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
726 }
727
728 if (phy->phy_mode == IEEE80211_MODE_11B) {
729 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
730 PHY_WRITE(mac, 0x16, 0x410);
731 PHY_WRITE(mac, 0x17, 0x820);
732 PHY_WRITE(mac, 0x62, 0x7);
733
734 bwi_rf_init_bcm2050(mac);
735 bwi_rf_lo_update(mac);
736 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
737 bwi_rf_calc_nrssi_slope(mac);
738 bwi_rf_set_nrssi_thr(mac);
739 }
740 bwi_mac_init_tpctl_11bg(mac);
741 } else {
742 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
743 }
744}
745
746#define N(arr) (int)(sizeof(arr) / sizeof(arr[0]))
747
748static void
749bwi_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 < N(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 < N(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 < N(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 < sizeof(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 = N(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 = N(bwi_phy_noise_scale_11g_rev7);
814 } else {
815 tbl = bwi_phy_noise_scale_11g;
816 n = N(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 = N(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 = N(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 < N(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#undef N
879
880/*
881 * Configure Automatic Gain Controller
882 */
883static void
884bwi_phy_config_agc(struct bwi_mac *mac)
885{
886 struct bwi_phy *phy = &mac->mac_phy;
887 uint16_t ofs;
888
889 ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
890
891 bwi_tbl_write_2(mac, ofs, 0xfe);
892 bwi_tbl_write_2(mac, ofs + 1, 0xd);
893 bwi_tbl_write_2(mac, ofs + 2, 0x13);
894 bwi_tbl_write_2(mac, ofs + 3, 0x19);
895
896 if (phy->phy_rev == 1) {
897 bwi_tbl_write_2(mac, 0x1800, 0x2710);
898 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
899 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
900 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
901 PHY_WRITE(mac, 0x455, 0x4);
902 }
903
904 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
905 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
906 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
907 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
908
909 RF_SETBITS(mac, 0x7a, 0x8);
910
911 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
912 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
913 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
914 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
915
916 if (phy->phy_rev == 1)
917 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
918
919 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
920 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
921 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
922 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
923 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
924 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
925 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
926 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
927 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
928
929 if (phy->phy_rev == 1) {
930 PHY_WRITE(mac, 0x430, 0x92b);
931 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
932 } else {
933 PHY_CLRBITS(mac, 0x41b, 0x1e);
934 PHY_WRITE(mac, 0x41f, 0x287a);
935 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
936
937 if (phy->phy_rev >= 6) {
938 PHY_WRITE(mac, 0x422, 0x287a);
939 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
940 }
941 }
942
943 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
944 PHY_WRITE(mac, 0x48e, 0x1c00);
945
946 if (phy->phy_rev == 1) {
947 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
948 PHY_WRITE(mac, 0x48b, 0x5e);
949 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
950 PHY_WRITE(mac, 0x48d, 0x2);
951 }
952
953 bwi_tbl_write_2(mac, ofs + 0x800, 0);
954 bwi_tbl_write_2(mac, ofs + 0x801, 7);
955 bwi_tbl_write_2(mac, ofs + 0x802, 16);
956 bwi_tbl_write_2(mac, ofs + 0x803, 28);
957
958 if (phy->phy_rev >= 6) {
959 PHY_CLRBITS(mac, 0x426, 0x3);
960 PHY_CLRBITS(mac, 0x426, 0x1000);
961 }
962}
963
964void
965bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
966{
967 struct bwi_phy *phy = &mac->mac_phy;
968 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
969 int i;
970
971 if (phy->phy_rev <= 1) {
972 tbl_gain_ofs1 = 0x5000;
973 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
974 } else {
975 tbl_gain_ofs1 = 0x400;
976 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
977 }
978
979 for (i = 0; i < 4; ++i) {
980 if (gains != NULL) {
981 tbl_gain = gains->tbl_gain1;
982 } else {
983 /* Bit swap */
984 tbl_gain = (i & 0x1) << 1;
985 tbl_gain |= (i & 0x2) >> 1;
986 }
987 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
988 }
989
990 for (i = 0; i < 16; ++i) {
991 if (gains != NULL)
992 tbl_gain = gains->tbl_gain2;
993 else
994 tbl_gain = i;
995 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
996 }
997
998 if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
999 uint16_t phy_gain1, phy_gain2;
1000
1001 if (gains != NULL) {
1002 phy_gain1 =
1003 ((uint16_t)gains->phy_gain << 14) |
1004 ((uint16_t)gains->phy_gain << 6);
1005 phy_gain2 = phy_gain1;
1006 } else {
1007 phy_gain1 = 0x4040;
1008 phy_gain2 = 0x4000;
1009 }
1010 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1011 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1012 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1013 }
1014 bwi_mac_dummy_xmit(mac);
1015}
1016
1017void
1018bwi_phy_clear_state(struct bwi_phy *phy)
1019{
1020 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1021}