xref: /freebsd/sys/dev/bwi/bwiphy.c (revision 9a14aa017b21c292740c00ee098195cd46642730)
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 
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 
75 static void	bwi_phy_init_11a(struct bwi_mac *);
76 static void	bwi_phy_init_11g(struct bwi_mac *);
77 static void	bwi_phy_init_11b_rev2(struct bwi_mac *);
78 static void	bwi_phy_init_11b_rev4(struct bwi_mac *);
79 static void	bwi_phy_init_11b_rev5(struct bwi_mac *);
80 static void	bwi_phy_init_11b_rev6(struct bwi_mac *);
81 
82 static void	bwi_phy_config_11g(struct bwi_mac *);
83 static void	bwi_phy_config_agc(struct bwi_mac *);
84 
85 static void	bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
86 static 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 
90 static 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 
112 static const uint16_t	bwi_phy_freq_11g_rev1[] =
113 	{ BWI_PHY_FREQ_11G_REV1 };
114 static const uint16_t	bwi_phy_noise_11g_rev1[] =
115 	{ BWI_PHY_NOISE_11G_REV1 };
116 static const uint16_t	bwi_phy_noise_11g[] =
117 	{ BWI_PHY_NOISE_11G };
118 static const uint32_t	bwi_phy_rotor_11g_rev1[] =
119 	{ BWI_PHY_ROTOR_11G_REV1 };
120 static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
121 	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
122 static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
123 	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
124 static const uint16_t	bwi_phy_noise_scale_11g[] =
125 	{ BWI_PHY_NOISE_SCALE_11G };
126 static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
127 	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
128 static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
129 	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
130 static const uint32_t	bwi_phy_delay_11g_rev1[] =
131 	{ BWI_PHY_DELAY_11G_REV1 };
132 
133 void
134 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
135 {
136 	struct bwi_softc *sc = mac->mac_sc;
137 
138 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
139 	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
140 }
141 
142 uint16_t
143 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
144 {
145 	struct bwi_softc *sc = mac->mac_sc;
146 
147 	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
148 	return CSR_READ_2(sc, BWI_PHY_DATA);
149 }
150 
151 int
152 bwi_phy_attach(struct bwi_mac *mac)
153 {
154 	struct bwi_softc *sc = mac->mac_sc;
155 	struct bwi_phy *phy = &mac->mac_phy;
156 	uint8_t phyrev, phytype, phyver;
157 	uint16_t val;
158 	int i;
159 
160 	/* Get PHY type/revision/version */
161 	val = CSR_READ_2(sc, BWI_PHYINFO);
162 	phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
163 	phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
164 	phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
165 	device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
166 		      phytype, phyrev, phyver);
167 
168 	/*
169 	 * Verify whether the revision of the PHY type is supported
170 	 * Convert PHY type to ieee80211_phymode
171 	 */
172 	switch (phytype) {
173 	case BWI_PHYINFO_TYPE_11A:
174 		if (phyrev >= 4) {
175 			device_printf(sc->sc_dev, "unsupported 11A PHY, "
176 				      "rev %u\n", phyrev);
177 			return ENXIO;
178 		}
179 		phy->phy_init = bwi_phy_init_11a;
180 		phy->phy_mode = IEEE80211_MODE_11A;
181 		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
182 		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
183 		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
184 		break;
185 	case BWI_PHYINFO_TYPE_11B:
186 #define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
187 		for (i = 0; i < N(bwi_sup_bphy); ++i) {
188 			if (phyrev == bwi_sup_bphy[i].rev) {
189 				phy->phy_init = bwi_sup_bphy[i].init;
190 				break;
191 			}
192 		}
193 		if (i == N(bwi_sup_bphy)) {
194 			device_printf(sc->sc_dev, "unsupported 11B PHY, "
195 				      "rev %u\n", phyrev);
196 			return ENXIO;
197 		}
198 #undef N
199 		phy->phy_mode = IEEE80211_MODE_11B;
200 		break;
201 	case BWI_PHYINFO_TYPE_11G:
202 		if (phyrev > 8) {
203 			device_printf(sc->sc_dev, "unsupported 11G PHY, "
204 				      "rev %u\n", phyrev);
205 			return ENXIO;
206 		}
207 		phy->phy_init = bwi_phy_init_11g;
208 		phy->phy_mode = IEEE80211_MODE_11G;
209 		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
210 		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
211 		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
212 		break;
213 	default:
214 		device_printf(sc->sc_dev, "unsupported PHY type %d\n",
215 			      phytype);
216 		return ENXIO;
217 	}
218 	phy->phy_rev = phyrev;
219 	phy->phy_version = phyver;
220 	return 0;
221 }
222 
223 void
224 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
225 {
226 	struct bwi_phy *phy = &mac->mac_phy;
227 	uint16_t mask = __BITS(3, 0);
228 
229 	if (phy->phy_version == 0) {
230 		CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
231 				   __SHIFTIN(bbp_atten, mask));
232 	} else {
233 		if (phy->phy_version > 1)
234 			mask <<= 2;
235 		else
236 			mask <<= 3;
237 		PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
238 				 __SHIFTIN(bbp_atten, mask));
239 	}
240 }
241 
242 int
243 bwi_phy_calibrate(struct bwi_mac *mac)
244 {
245 	struct bwi_phy *phy = &mac->mac_phy;
246 
247 	/* Dummy read */
248 	CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
249 
250 	/* Don't re-init */
251 	if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
252 		return 0;
253 
254 	if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
255 		bwi_mac_reset(mac, 0);
256 		bwi_phy_init_11g(mac);
257 		bwi_mac_reset(mac, 1);
258 	}
259 
260 	phy->phy_flags |= BWI_PHY_F_CALIBRATED;
261 	return 0;
262 }
263 
264 static void
265 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
266 {
267 	struct bwi_phy *phy = &mac->mac_phy;
268 
269 	KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0,
270 	   ("phy_tbl_ctrl %d phy_tbl_data_lo %d",
271 	     phy->phy_tbl_ctrl, phy->phy_tbl_data_lo));
272 	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
273 	PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
274 }
275 
276 static void
277 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
278 {
279 	struct bwi_phy *phy = &mac->mac_phy;
280 
281 	KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
282 		 phy->phy_tbl_ctrl != 0,
283 	    ("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d",
284 	      phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl));
285 
286 	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
287 	PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
288 	PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
289 }
290 
291 void
292 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
293 {
294 	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
295 	PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
296 }
297 
298 int16_t
299 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
300 {
301 	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
302 	return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
303 }
304 
305 static void
306 bwi_phy_init_11a(struct bwi_mac *mac)
307 {
308 	/* TODO:11A */
309 }
310 
311 static void
312 bwi_phy_init_11g(struct bwi_mac *mac)
313 {
314 	struct bwi_softc *sc = mac->mac_sc;
315 	struct bwi_phy *phy = &mac->mac_phy;
316 	struct bwi_rf *rf = &mac->mac_rf;
317 	const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
318 
319 	if (phy->phy_rev == 1)
320 		bwi_phy_init_11b_rev5(mac);
321 	else
322 		bwi_phy_init_11b_rev6(mac);
323 
324 	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
325 		bwi_phy_config_11g(mac);
326 
327 	if (phy->phy_rev >= 2) {
328 		PHY_WRITE(mac, 0x814, 0);
329 		PHY_WRITE(mac, 0x815, 0);
330 
331 		if (phy->phy_rev == 2) {
332 			PHY_WRITE(mac, 0x811, 0);
333 			PHY_WRITE(mac, 0x15, 0xc0);
334 		} else if (phy->phy_rev > 5) {
335 			PHY_WRITE(mac, 0x811, 0x400);
336 			PHY_WRITE(mac, 0x15, 0xc0);
337 		}
338 	}
339 
340 	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
341 		uint16_t val;
342 
343 		val = PHY_READ(mac, 0x400) & 0xff;
344 		if (val == 3 || val == 5) {
345 			PHY_WRITE(mac, 0x4c2, 0x1816);
346 			PHY_WRITE(mac, 0x4c3, 0x8006);
347 			if (val == 5) {
348 				PHY_FILT_SETBITS(mac, 0x4cc,
349 						 0xff, 0x1f00);
350 			}
351 		}
352 	}
353 
354 	if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
355 	    phy->phy_rev >= 2)
356 		PHY_WRITE(mac, 0x47e, 0x78);
357 
358 	if (rf->rf_rev == 8) {
359 		PHY_SETBITS(mac, 0x801, 0x80);
360 		PHY_SETBITS(mac, 0x43e, 0x4);
361 	}
362 
363 	if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
364 		bwi_rf_get_gains(mac);
365 
366 	if (rf->rf_rev != 8)
367 		bwi_rf_init(mac);
368 
369 	if (tpctl->tp_ctrl2 == 0xffff) {
370 		bwi_rf_lo_update(mac);
371 	} else {
372 		if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
373 			RF_WRITE(mac, 0x52,
374 				 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
375 		} else {
376 			RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
377 		}
378 
379 		if (phy->phy_rev >= 6) {
380 			PHY_FILT_SETBITS(mac, 0x36, 0xfff,
381 					 tpctl->tp_ctrl2 << 12);
382 		}
383 
384 		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
385 			PHY_WRITE(mac, 0x2e, 0x8075);
386 		else
387 			PHY_WRITE(mac, 0x2e, 0x807f);
388 
389 		if (phy->phy_rev < 2)
390 			PHY_WRITE(mac, 0x2f, 0x101);
391 		else
392 			PHY_WRITE(mac, 0x2f, 0x202);
393 	}
394 
395 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
396 		bwi_rf_lo_adjust(mac, tpctl);
397 		PHY_WRITE(mac, 0x80f, 0x8078);
398 	}
399 
400 	if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
401 		bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
402 		bwi_rf_set_nrssi_thr(mac);
403 	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
404 		if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
405 			KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI,
406 			    ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
407 			bwi_rf_calc_nrssi_slope(mac);
408 		} else {
409 			KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI,
410 			    ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
411 			bwi_rf_set_nrssi_thr(mac);
412 		}
413 	}
414 
415 	if (rf->rf_rev == 8)
416 		PHY_WRITE(mac, 0x805, 0x3230);
417 
418 	bwi_mac_init_tpctl_11bg(mac);
419 
420 	if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
421 		PHY_CLRBITS(mac, 0x429, 0x4000);
422 		PHY_CLRBITS(mac, 0x4c3, 0x8000);
423 	}
424 }
425 
426 static void
427 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
428 {
429 	/* TODO:11B */
430 	if_printf(mac->mac_sc->sc_ifp,
431 		  "%s is not implemented yet\n", __func__);
432 }
433 
434 static void
435 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
436 {
437 	struct bwi_softc *sc = mac->mac_sc;
438 	struct bwi_rf *rf = &mac->mac_rf;
439 	uint16_t val, ofs;
440 	u_int chan;
441 
442 	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
443 
444 	PHY_WRITE(mac, 0x20, 0x301c);
445 	PHY_WRITE(mac, 0x26, 0);
446 	PHY_WRITE(mac, 0x30, 0xc6);
447 	PHY_WRITE(mac, 0x88, 0x3e00);
448 
449 	for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
450 		PHY_WRITE(mac, 0x89 + ofs, val);
451 
452 	CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
453 
454 	chan = rf->rf_curchan;
455 	if (chan == IEEE80211_CHAN_ANY)
456 		chan = 6;	/* Force to channel 6 */
457 	bwi_rf_set_chan(mac, chan, 0);
458 
459 	if (rf->rf_type != BWI_RF_T_BCM2050) {
460 		RF_WRITE(mac, 0x75, 0x80);
461 		RF_WRITE(mac, 0x79, 0x81);
462 	}
463 
464 	RF_WRITE(mac, 0x50, 0x20);
465 	RF_WRITE(mac, 0x50, 0x23);
466 
467 	if (rf->rf_type == BWI_RF_T_BCM2050) {
468 		RF_WRITE(mac, 0x50, 0x20);
469 		RF_WRITE(mac, 0x5a, 0x70);
470 		RF_WRITE(mac, 0x5b, 0x7b);
471 		RF_WRITE(mac, 0x5c, 0xb0);
472 		RF_WRITE(mac, 0x7a, 0xf);
473 		PHY_WRITE(mac, 0x38, 0x677);
474 		bwi_rf_init_bcm2050(mac);
475 	}
476 
477 	PHY_WRITE(mac, 0x14, 0x80);
478 	PHY_WRITE(mac, 0x32, 0xca);
479 	if (rf->rf_type == BWI_RF_T_BCM2050)
480 		PHY_WRITE(mac, 0x32, 0xe0);
481 	PHY_WRITE(mac, 0x35, 0x7c2);
482 
483 	bwi_rf_lo_update(mac);
484 
485 	PHY_WRITE(mac, 0x26, 0xcc00);
486 	if (rf->rf_type == BWI_RF_T_BCM2050)
487 		PHY_WRITE(mac, 0x26, 0xce00);
488 
489 	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
490 
491 	PHY_WRITE(mac, 0x2a, 0x88a3);
492 	if (rf->rf_type == BWI_RF_T_BCM2050)
493 		PHY_WRITE(mac, 0x2a, 0x88c2);
494 
495 	bwi_mac_set_tpctl_11bg(mac, NULL);
496 	if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
497 		bwi_rf_calc_nrssi_slope(mac);
498 		bwi_rf_set_nrssi_thr(mac);
499 	}
500 	bwi_mac_init_tpctl_11bg(mac);
501 }
502 
503 static void
504 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
505 {
506 	struct bwi_softc *sc = mac->mac_sc;
507 	struct bwi_rf *rf = &mac->mac_rf;
508 	struct bwi_phy *phy = &mac->mac_phy;
509 	u_int orig_chan;
510 
511 	if (phy->phy_version == 1)
512 		RF_SETBITS(mac, 0x7a, 0x50);
513 
514 	if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
515 	    sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
516 		uint16_t ofs, val;
517 
518 		val = 0x2120;
519 		for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
520 			PHY_WRITE(mac, ofs, val);
521 			val += 0x202;
522 		}
523 	}
524 
525 	PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
526 
527 	if (rf->rf_type == BWI_RF_T_BCM2050)
528 		PHY_WRITE(mac, 0x38, 0x667);
529 
530 	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
531 		if (rf->rf_type == BWI_RF_T_BCM2050) {
532 			RF_SETBITS(mac, 0x7a, 0x20);
533 			RF_SETBITS(mac, 0x51, 0x4);
534 		}
535 
536 		CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
537 
538 		PHY_SETBITS(mac, 0x802, 0x100);
539 		PHY_SETBITS(mac, 0x42b, 0x2000);
540 		PHY_WRITE(mac, 0x1c, 0x186a);
541 
542 		PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
543 		PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
544 		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
545 	}
546 
547 	/* TODO: bad_frame_preempt? */
548 
549 	if (phy->phy_version == 1) {
550 	    	PHY_WRITE(mac, 0x26, 0xce00);
551 		PHY_WRITE(mac, 0x21, 0x3763);
552 		PHY_WRITE(mac, 0x22, 0x1bc3);
553 		PHY_WRITE(mac, 0x23, 0x6f9);
554 		PHY_WRITE(mac, 0x24, 0x37e);
555 	} else {
556 		PHY_WRITE(mac, 0x26, 0xcc00);
557 	}
558 	PHY_WRITE(mac, 0x30, 0xc6);
559 
560 	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
561 
562 	if (phy->phy_version == 1)
563 		PHY_WRITE(mac, 0x20, 0x3e1c);
564 	else
565 		PHY_WRITE(mac, 0x20, 0x301c);
566 
567 	if (phy->phy_version == 0)
568 		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
569 
570 	/* Force to channel 7 */
571 	orig_chan = rf->rf_curchan;
572 	bwi_rf_set_chan(mac, 7, 0);
573 
574 	if (rf->rf_type != BWI_RF_T_BCM2050) {
575 		RF_WRITE(mac, 0x75, 0x80);
576 		RF_WRITE(mac, 0x79, 0x81);
577 	}
578 
579 	RF_WRITE(mac, 0x50, 0x20);
580 	RF_WRITE(mac, 0x50, 0x23);
581 
582 	if (rf->rf_type == BWI_RF_T_BCM2050) {
583 		RF_WRITE(mac, 0x50, 0x20);
584 		RF_WRITE(mac, 0x5a, 0x70);
585 	}
586 
587 	RF_WRITE(mac, 0x5b, 0x7b);
588 	RF_WRITE(mac, 0x5c, 0xb0);
589 	RF_SETBITS(mac, 0x7a, 0x7);
590 
591 	bwi_rf_set_chan(mac, orig_chan, 0);
592 
593 	PHY_WRITE(mac, 0x14, 0x80);
594 	PHY_WRITE(mac, 0x32, 0xca);
595 	PHY_WRITE(mac, 0x2a, 0x88a3);
596 
597 	bwi_mac_set_tpctl_11bg(mac, NULL);
598 
599 	if (rf->rf_type == BWI_RF_T_BCM2050)
600 		RF_WRITE(mac, 0x5d, 0xd);
601 
602 	CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
603 }
604 
605 static void
606 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
607 {
608 	struct bwi_softc *sc = mac->mac_sc;
609 	struct bwi_rf *rf = &mac->mac_rf;
610 	struct bwi_phy *phy = &mac->mac_phy;
611 	uint16_t val, ofs;
612 	u_int orig_chan;
613 
614 	PHY_WRITE(mac, 0x3e, 0x817a);
615 	RF_SETBITS(mac, 0x7a, 0x58);
616 
617 	if (rf->rf_rev == 4 || rf->rf_rev == 5) {
618 		RF_WRITE(mac, 0x51, 0x37);
619 		RF_WRITE(mac, 0x52, 0x70);
620 		RF_WRITE(mac, 0x53, 0xb3);
621 		RF_WRITE(mac, 0x54, 0x9b);
622 		RF_WRITE(mac, 0x5a, 0x88);
623 		RF_WRITE(mac, 0x5b, 0x88);
624 		RF_WRITE(mac, 0x5d, 0x88);
625 		RF_WRITE(mac, 0x5e, 0x88);
626 		RF_WRITE(mac, 0x7d, 0x88);
627 		HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
628 	} else if (rf->rf_rev == 8) {
629 		RF_WRITE(mac, 0x51, 0);
630 		RF_WRITE(mac, 0x52, 0x40);
631 		RF_WRITE(mac, 0x53, 0xb7);
632 		RF_WRITE(mac, 0x54, 0x98);
633 		RF_WRITE(mac, 0x5a, 0x88);
634 		RF_WRITE(mac, 0x5b, 0x6b);
635 		RF_WRITE(mac, 0x5c, 0xf);
636 		if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
637 			RF_WRITE(mac, 0x5d, 0xfa);
638 			RF_WRITE(mac, 0x5e, 0xd8);
639 		} else {
640 			RF_WRITE(mac, 0x5d, 0xf5);
641 			RF_WRITE(mac, 0x5e, 0xb8);
642 		}
643 		RF_WRITE(mac, 0x73, 0x3);
644 		RF_WRITE(mac, 0x7d, 0xa8);
645 		RF_WRITE(mac, 0x7c, 0x1);
646 		RF_WRITE(mac, 0x7e, 0x8);
647 	}
648 
649 	val = 0x1e1f;
650 	for (ofs = 0x88; ofs < 0x98; ++ofs) {
651 		PHY_WRITE(mac, ofs, val);
652 		val -= 0x202;
653 	}
654 
655 	val = 0x3e3f;
656 	for (ofs = 0x98; ofs < 0xa8; ++ofs) {
657 		PHY_WRITE(mac, ofs, val);
658 		val -= 0x202;
659 	}
660 
661 	val = 0x2120;
662 	for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
663 		PHY_WRITE(mac, ofs, (val & 0x3f3f));
664 		val += 0x202;
665 
666 		/* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */
667 		DELAY(10);
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 
748 static void
749 bwi_phy_config_11g(struct bwi_mac *mac)
750 {
751 	struct bwi_softc *sc = mac->mac_sc;
752 	struct bwi_phy *phy = &mac->mac_phy;
753 	const uint16_t *tbl;
754 	uint16_t wrd_ofs1, wrd_ofs2;
755 	int i, n;
756 
757 	if (phy->phy_rev == 1) {
758 		PHY_WRITE(mac, 0x406, 0x4f19);
759 		PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
760 		PHY_WRITE(mac, 0x42c, 0x5a);
761 		PHY_WRITE(mac, 0x427, 0x1a);
762 
763 		/* Fill frequency table */
764 		for (i = 0; i < 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 < N(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  */
883 static void
884 bwi_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 
964 void
965 bwi_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 
1017 void
1018 bwi_phy_clear_state(struct bwi_phy *phy)
1019 {
1020 	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1021 }
1022