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