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