xref: /freebsd/sys/dev/bwi/bwiphy.c (revision 1c6d60de932c8553af44629218cb9697bc0f2ef1)
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_var.h>
57 #include <net/if_dl.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60 #include <net/if_arp.h>
61 #include <net/ethernet.h>
62 #include <net/if_llc.h>
63 
64 #include <net80211/ieee80211_var.h>
65 #include <net80211/ieee80211_radiotap.h>
66 #include <net80211/ieee80211_amrr.h>
67 
68 #include <machine/bus.h>
69 
70 #include <dev/bwi/bitops.h>
71 #include <dev/bwi/if_bwireg.h>
72 #include <dev/bwi/if_bwivar.h>
73 #include <dev/bwi/bwimac.h>
74 #include <dev/bwi/bwirf.h>
75 #include <dev/bwi/bwiphy.h>
76 
77 static void	bwi_phy_init_11a(struct bwi_mac *);
78 static void	bwi_phy_init_11g(struct bwi_mac *);
79 static void	bwi_phy_init_11b_rev2(struct bwi_mac *);
80 static void	bwi_phy_init_11b_rev4(struct bwi_mac *);
81 static void	bwi_phy_init_11b_rev5(struct bwi_mac *);
82 static void	bwi_phy_init_11b_rev6(struct bwi_mac *);
83 
84 static void	bwi_phy_config_11g(struct bwi_mac *);
85 static void	bwi_phy_config_agc(struct bwi_mac *);
86 
87 static void	bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
88 static void	bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
89 
90 #define SUP_BPHY(num)	{ .rev = num, .init = bwi_phy_init_11b_rev##num }
91 
92 static const struct {
93 	uint8_t	rev;
94 	void	(*init)(struct bwi_mac *);
95 } bwi_sup_bphy[] = {
96 	SUP_BPHY(2),
97 	SUP_BPHY(4),
98 	SUP_BPHY(5),
99 	SUP_BPHY(6)
100 };
101 
102 #undef SUP_BPHY
103 
104 #define BWI_PHYTBL_WRSSI	0x1000
105 #define BWI_PHYTBL_NOISE_SCALE	0x1400
106 #define BWI_PHYTBL_NOISE	0x1800
107 #define BWI_PHYTBL_ROTOR	0x2000
108 #define BWI_PHYTBL_DELAY	0x2400
109 #define BWI_PHYTBL_RSSI		0x4000
110 #define BWI_PHYTBL_SIGMA_SQ	0x5000
111 #define BWI_PHYTBL_WRSSI_REV1	0x5400
112 #define BWI_PHYTBL_FREQ		0x5800
113 
114 static const uint16_t	bwi_phy_freq_11g_rev1[] =
115 	{ BWI_PHY_FREQ_11G_REV1 };
116 static const uint16_t	bwi_phy_noise_11g_rev1[] =
117 	{ BWI_PHY_NOISE_11G_REV1 };
118 static const uint16_t	bwi_phy_noise_11g[] =
119 	{ BWI_PHY_NOISE_11G };
120 static const uint32_t	bwi_phy_rotor_11g_rev1[] =
121 	{ BWI_PHY_ROTOR_11G_REV1 };
122 static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
123 	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
124 static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
125 	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
126 static const uint16_t	bwi_phy_noise_scale_11g[] =
127 	{ BWI_PHY_NOISE_SCALE_11G };
128 static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
129 	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
130 static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
131 	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
132 static const uint32_t	bwi_phy_delay_11g_rev1[] =
133 	{ BWI_PHY_DELAY_11G_REV1 };
134 
135 void
136 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
137 {
138 	struct bwi_softc *sc = mac->mac_sc;
139 
140 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
141 	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
142 }
143 
144 uint16_t
145 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
146 {
147 	struct bwi_softc *sc = mac->mac_sc;
148 
149 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
150 	return CSR_READ_2(sc, BWI_PHY_DATA);
151 }
152 
153 int
154 bwi_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 
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 	if_printf(mac->mac_sc->sc_ifp,
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 #define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
749 
750 static void
751 bwi_phy_config_11g(struct bwi_mac *mac)
752 {
753 	struct bwi_softc *sc = mac->mac_sc;
754 	struct bwi_phy *phy = &mac->mac_phy;
755 	const uint16_t *tbl;
756 	uint16_t wrd_ofs1, wrd_ofs2;
757 	int i, n;
758 
759 	if (phy->phy_rev == 1) {
760 		PHY_WRITE(mac, 0x406, 0x4f19);
761 		PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
762 		PHY_WRITE(mac, 0x42c, 0x5a);
763 		PHY_WRITE(mac, 0x427, 0x1a);
764 
765 		/* Fill frequency table */
766 		for (i = 0; i < N(bwi_phy_freq_11g_rev1); ++i) {
767 			bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
768 					bwi_phy_freq_11g_rev1[i]);
769 		}
770 
771 		/* Fill noise table */
772 		for (i = 0; i < N(bwi_phy_noise_11g_rev1); ++i) {
773 			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
774 					bwi_phy_noise_11g_rev1[i]);
775 		}
776 
777 		/* Fill rotor table */
778 		for (i = 0; i < N(bwi_phy_rotor_11g_rev1); ++i) {
779 			/* NB: data length is 4 bytes */
780 			bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
781 					bwi_phy_rotor_11g_rev1[i]);
782 		}
783 	} else {
784 		bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
785 
786 		if (phy->phy_rev == 2) {
787 			PHY_WRITE(mac, 0x4c0, 0x1861);
788 			PHY_WRITE(mac, 0x4c1, 0x271);
789 		} else if (phy->phy_rev > 2) {
790 			PHY_WRITE(mac, 0x4c0, 0x98);
791 			PHY_WRITE(mac, 0x4c1, 0x70);
792 			PHY_WRITE(mac, 0x4c9, 0x80);
793 		}
794 		PHY_SETBITS(mac, 0x42b, 0x800);
795 
796 		/* Fill RSSI table */
797 		for (i = 0; i < 64; ++i)
798 			bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
799 
800 		/* Fill noise table */
801 		for (i = 0; i < N(bwi_phy_noise_11g); ++i) {
802 			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
803 					bwi_phy_noise_11g[i]);
804 		}
805 	}
806 
807 	/*
808 	 * Fill noise scale table
809 	 */
810 	if (phy->phy_rev <= 2) {
811 		tbl = bwi_phy_noise_scale_11g_rev2;
812 		n = N(bwi_phy_noise_scale_11g_rev2);
813 	} else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
814 		tbl = bwi_phy_noise_scale_11g_rev7;
815 		n = N(bwi_phy_noise_scale_11g_rev7);
816 	} else {
817 		tbl = bwi_phy_noise_scale_11g;
818 		n = N(bwi_phy_noise_scale_11g);
819 	}
820 	for (i = 0; i < n; ++i)
821 		bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
822 
823 	/*
824 	 * Fill sigma square table
825 	 */
826 	if (phy->phy_rev == 2) {
827 		tbl = bwi_phy_sigma_sq_11g_rev2;
828 		n = N(bwi_phy_sigma_sq_11g_rev2);
829 	} else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
830 		tbl = bwi_phy_sigma_sq_11g_rev7;
831 		n = N(bwi_phy_sigma_sq_11g_rev7);
832 	} else {
833 		tbl = NULL;
834 		n = 0;
835 	}
836 	for (i = 0; i < n; ++i)
837 		bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
838 
839 	if (phy->phy_rev == 1) {
840 		/* Fill delay table */
841 		for (i = 0; i < N(bwi_phy_delay_11g_rev1); ++i) {
842 			bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
843 					bwi_phy_delay_11g_rev1[i]);
844 		}
845 
846 		/* Fill WRSSI (Wide-Band RSSI) table */
847 		for (i = 4; i < 20; ++i)
848 			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
849 
850 		bwi_phy_config_agc(mac);
851 
852 		wrd_ofs1 = 0x5001;
853 		wrd_ofs2 = 0x5002;
854 	} else {
855 		/* Fill WRSSI (Wide-Band RSSI) table */
856 		for (i = 0; i < 0x20; ++i)
857 			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
858 
859 		bwi_phy_config_agc(mac);
860 
861 		PHY_READ(mac, 0x400);	/* Dummy read */
862 		PHY_WRITE(mac, 0x403, 0x1000);
863 		bwi_tbl_write_2(mac, 0x3c02, 0xf);
864 		bwi_tbl_write_2(mac, 0x3c03, 0x14);
865 
866 		wrd_ofs1 = 0x401;
867 		wrd_ofs2 = 0x402;
868 	}
869 
870 	if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
871 		bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
872 		bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
873 	}
874 
875 	/* phy->phy_flags & BWI_PHY_F_LINKED ? */
876 	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
877 		PHY_WRITE(mac, 0x46e, 0x3cf);
878 }
879 
880 #undef N
881 
882 /*
883  * Configure Automatic Gain Controller
884  */
885 static void
886 bwi_phy_config_agc(struct bwi_mac *mac)
887 {
888 	struct bwi_phy *phy = &mac->mac_phy;
889 	uint16_t ofs;
890 
891 	ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
892 
893 	bwi_tbl_write_2(mac, ofs, 0xfe);
894 	bwi_tbl_write_2(mac, ofs + 1, 0xd);
895 	bwi_tbl_write_2(mac, ofs + 2, 0x13);
896 	bwi_tbl_write_2(mac, ofs + 3, 0x19);
897 
898 	if (phy->phy_rev == 1) {
899 		bwi_tbl_write_2(mac, 0x1800, 0x2710);
900 		bwi_tbl_write_2(mac, 0x1801, 0x9b83);
901 		bwi_tbl_write_2(mac, 0x1802, 0x9b83);
902 		bwi_tbl_write_2(mac, 0x1803, 0xf8d);
903 		PHY_WRITE(mac, 0x455, 0x4);
904 	}
905 
906 	PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
907 	PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
908 	PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
909 	PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
910 
911 	RF_SETBITS(mac, 0x7a, 0x8);
912 
913 	PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
914 	PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
915 	PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
916 	PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
917 
918 	if (phy->phy_rev == 1)
919 		PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
920 
921 	PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
922 	PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
923 	PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
924 	PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
925 	PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
926 	PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
927 	PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
928 	PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
929 	PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
930 
931 	if (phy->phy_rev == 1) {
932 		PHY_WRITE(mac, 0x430, 0x92b);
933 		PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
934 	} else {
935 		PHY_CLRBITS(mac, 0x41b, 0x1e);
936 		PHY_WRITE(mac, 0x41f, 0x287a);
937 		PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
938 
939 		if (phy->phy_rev >= 6) {
940 			PHY_WRITE(mac, 0x422, 0x287a);
941 			PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
942 		}
943 	}
944 
945 	PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
946 	PHY_WRITE(mac, 0x48e, 0x1c00);
947 
948 	if (phy->phy_rev == 1) {
949 		PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
950 		PHY_WRITE(mac, 0x48b, 0x5e);
951 		PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
952 		PHY_WRITE(mac, 0x48d, 0x2);
953 	}
954 
955 	bwi_tbl_write_2(mac, ofs + 0x800, 0);
956 	bwi_tbl_write_2(mac, ofs + 0x801, 7);
957 	bwi_tbl_write_2(mac, ofs + 0x802, 16);
958 	bwi_tbl_write_2(mac, ofs + 0x803, 28);
959 
960 	if (phy->phy_rev >= 6) {
961 		PHY_CLRBITS(mac, 0x426, 0x3);
962 		PHY_CLRBITS(mac, 0x426, 0x1000);
963 	}
964 }
965 
966 void
967 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
968 {
969 	struct bwi_phy *phy = &mac->mac_phy;
970 	uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
971 	int i;
972 
973 	if (phy->phy_rev <= 1) {
974 		tbl_gain_ofs1 = 0x5000;
975 		tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
976 	} else {
977 		tbl_gain_ofs1 = 0x400;
978 		tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
979 	}
980 
981 	for (i = 0; i < 4; ++i) {
982 		if (gains != NULL) {
983 			tbl_gain = gains->tbl_gain1;
984 		} else {
985 			/* Bit swap */
986 			tbl_gain = (i & 0x1) << 1;
987 			tbl_gain |= (i & 0x2) >> 1;
988 		}
989 		bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
990 	}
991 
992 	for (i = 0; i < 16; ++i) {
993 		if (gains != NULL)
994 			tbl_gain = gains->tbl_gain2;
995 		else
996 			tbl_gain = i;
997 		bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
998 	}
999 
1000 	if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
1001 		uint16_t phy_gain1, phy_gain2;
1002 
1003 		if (gains != NULL) {
1004 			phy_gain1 =
1005 			((uint16_t)gains->phy_gain << 14) |
1006 			((uint16_t)gains->phy_gain << 6);
1007 			phy_gain2 = phy_gain1;
1008 		} else {
1009 			phy_gain1 = 0x4040;
1010 			phy_gain2 = 0x4000;
1011 		}
1012 		PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1013 		PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1014 		PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1015 	}
1016 	bwi_mac_dummy_xmit(mac);
1017 }
1018 
1019 void
1020 bwi_phy_clear_state(struct bwi_phy *phy)
1021 {
1022 	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1023 }
1024