bwiphy.c revision 192046
1/*
2 * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $DragonFly: src/sys/dev/netif/bwi/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/sys/dev/bwi/bwiphy.c 192046 2009-05-13 16:19:05Z nwhitehorn $");
39
40#include "opt_inet.h"
41
42#include <sys/param.h>
43#include <sys/endian.h>
44#include <sys/kernel.h>
45#include <sys/bus.h>
46#include <sys/malloc.h>
47#include <sys/proc.h>
48#include <sys/rman.h>
49#include <sys/socket.h>
50#include <sys/sockio.h>
51#include <sys/sysctl.h>
52#include <sys/systm.h>
53
54#include <net/if.h>
55#include <net/if_dl.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58#include <net/if_arp.h>
59#include <net/ethernet.h>
60#include <net/if_llc.h>
61
62#include <net80211/ieee80211_var.h>
63#include <net80211/ieee80211_radiotap.h>
64#include <net80211/ieee80211_amrr.h>
65
66#include <machine/bus.h>
67
68#include <dev/bwi/bitops.h>
69#include <dev/bwi/if_bwireg.h>
70#include <dev/bwi/if_bwivar.h>
71#include <dev/bwi/bwimac.h>
72#include <dev/bwi/bwirf.h>
73#include <dev/bwi/bwiphy.h>
74
75static void	bwi_phy_init_11a(struct bwi_mac *);
76static void	bwi_phy_init_11g(struct bwi_mac *);
77static void	bwi_phy_init_11b_rev2(struct bwi_mac *);
78static void	bwi_phy_init_11b_rev4(struct bwi_mac *);
79static void	bwi_phy_init_11b_rev5(struct bwi_mac *);
80static void	bwi_phy_init_11b_rev6(struct bwi_mac *);
81
82static void	bwi_phy_config_11g(struct bwi_mac *);
83static void	bwi_phy_config_agc(struct bwi_mac *);
84
85static void	bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
86static void	bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
87
88#define SUP_BPHY(num)	{ .rev = num, .init = bwi_phy_init_11b_rev##num }
89
90static const struct {
91	uint8_t	rev;
92	void	(*init)(struct bwi_mac *);
93} bwi_sup_bphy[] = {
94	SUP_BPHY(2),
95	SUP_BPHY(4),
96	SUP_BPHY(5),
97	SUP_BPHY(6)
98};
99
100#undef SUP_BPHY
101
102#define BWI_PHYTBL_WRSSI	0x1000
103#define BWI_PHYTBL_NOISE_SCALE	0x1400
104#define BWI_PHYTBL_NOISE	0x1800
105#define BWI_PHYTBL_ROTOR	0x2000
106#define BWI_PHYTBL_DELAY	0x2400
107#define BWI_PHYTBL_RSSI		0x4000
108#define BWI_PHYTBL_SIGMA_SQ	0x5000
109#define BWI_PHYTBL_WRSSI_REV1	0x5400
110#define BWI_PHYTBL_FREQ		0x5800
111
112static const uint16_t	bwi_phy_freq_11g_rev1[] =
113	{ BWI_PHY_FREQ_11G_REV1 };
114static const uint16_t	bwi_phy_noise_11g_rev1[] =
115	{ BWI_PHY_NOISE_11G_REV1 };
116static const uint16_t	bwi_phy_noise_11g[] =
117	{ BWI_PHY_NOISE_11G };
118static const uint32_t	bwi_phy_rotor_11g_rev1[] =
119	{ BWI_PHY_ROTOR_11G_REV1 };
120static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
121	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
122static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
123	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
124static const uint16_t	bwi_phy_noise_scale_11g[] =
125	{ BWI_PHY_NOISE_SCALE_11G };
126static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
127	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
128static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
129	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
130static const uint32_t	bwi_phy_delay_11g_rev1[] =
131	{ BWI_PHY_DELAY_11G_REV1 };
132
133void
134bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
135{
136	struct bwi_softc *sc = mac->mac_sc;
137
138	/* TODO: 11A */
139	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
140	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
141}
142
143uint16_t
144bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
145{
146	struct bwi_softc *sc = mac->mac_sc;
147
148	/* TODO: 11A */
149	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
150	return CSR_READ_2(sc, BWI_PHY_DATA);
151}
152
153int
154bwi_phy_attach(struct bwi_mac *mac)
155{
156	struct bwi_softc *sc = mac->mac_sc;
157	struct bwi_phy *phy = &mac->mac_phy;
158	uint8_t phyrev, phytype, phyver;
159	uint16_t val;
160	int i;
161
162	/* Get PHY type/revision/version */
163	val = CSR_READ_2(sc, BWI_PHYINFO);
164	phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
165	phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
166	phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
167	device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
168		      phytype, phyrev, phyver);
169
170	/*
171	 * Verify whether the revision of the PHY type is supported
172	 * Convert PHY type to ieee80211_phymode
173	 */
174	switch (phytype) {
175	case BWI_PHYINFO_TYPE_11A:
176		if (phyrev >= 4) {
177			device_printf(sc->sc_dev, "unsupported 11A PHY, "
178				      "rev %u\n", phyrev);
179			return ENXIO;
180		}
181		phy->phy_init = bwi_phy_init_11a;
182		phy->phy_mode = IEEE80211_MODE_11A;
183		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
184		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
185		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
186		break;
187	case BWI_PHYINFO_TYPE_11B:
188#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
189		for (i = 0; i < N(bwi_sup_bphy); ++i) {
190			if (phyrev == bwi_sup_bphy[i].rev) {
191				phy->phy_init = bwi_sup_bphy[i].init;
192				break;
193			}
194		}
195		if (i == N(bwi_sup_bphy)) {
196			device_printf(sc->sc_dev, "unsupported 11B PHY, "
197				      "rev %u\n", phyrev);
198			return ENXIO;
199		}
200#undef N
201		phy->phy_mode = IEEE80211_MODE_11B;
202		break;
203	case BWI_PHYINFO_TYPE_11G:
204		if (phyrev > 8) {
205			device_printf(sc->sc_dev, "unsupported 11G PHY, "
206				      "rev %u\n", phyrev);
207			return ENXIO;
208		}
209		phy->phy_init = bwi_phy_init_11g;
210		phy->phy_mode = IEEE80211_MODE_11G;
211		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
212		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
213		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
214		break;
215	default:
216		device_printf(sc->sc_dev, "unsupported PHY type %d\n",
217			      phytype);
218		return ENXIO;
219	}
220	phy->phy_rev = phyrev;
221	phy->phy_version = phyver;
222	return 0;
223}
224
225void
226bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
227{
228	struct bwi_phy *phy = &mac->mac_phy;
229	uint16_t mask = __BITS(3, 0);
230
231	if (phy->phy_version == 0) {
232		CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
233				   __SHIFTIN(bbp_atten, mask));
234	} else {
235		if (phy->phy_version > 1)
236			mask <<= 2;
237		else
238			mask <<= 3;
239		PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
240				 __SHIFTIN(bbp_atten, mask));
241	}
242}
243
244int
245bwi_phy_calibrate(struct bwi_mac *mac)
246{
247	struct bwi_phy *phy = &mac->mac_phy;
248
249	/* Dummy read */
250	CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
251
252	/* Don't re-init */
253	if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
254		return 0;
255
256	if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
257		bwi_mac_reset(mac, 0);
258		bwi_phy_init_11g(mac);
259		bwi_mac_reset(mac, 1);
260	}
261
262	phy->phy_flags |= BWI_PHY_F_CALIBRATED;
263	return 0;
264}
265
266static void
267bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
268{
269	struct bwi_phy *phy = &mac->mac_phy;
270
271	KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0,
272	   ("phy_tbl_ctrl %d phy_tbl_data_lo %d",
273	     phy->phy_tbl_ctrl, phy->phy_tbl_data_lo));
274	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
275	PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
276}
277
278static void
279bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
280{
281	struct bwi_phy *phy = &mac->mac_phy;
282
283	KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
284		 phy->phy_tbl_ctrl != 0,
285	    ("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d",
286	      phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl));
287
288	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
289	PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
290	PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
291}
292
293void
294bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
295{
296	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
297	PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
298}
299
300int16_t
301bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
302{
303	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
304	return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
305}
306
307static void
308bwi_phy_init_11a(struct bwi_mac *mac)
309{
310	/* TODO:11A */
311}
312
313static void
314bwi_phy_init_11g(struct bwi_mac *mac)
315{
316	struct bwi_softc *sc = mac->mac_sc;
317	struct bwi_phy *phy = &mac->mac_phy;
318	struct bwi_rf *rf = &mac->mac_rf;
319	const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
320
321	if (phy->phy_rev == 1)
322		bwi_phy_init_11b_rev5(mac);
323	else
324		bwi_phy_init_11b_rev6(mac);
325
326	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
327		bwi_phy_config_11g(mac);
328
329	if (phy->phy_rev >= 2) {
330		PHY_WRITE(mac, 0x814, 0);
331		PHY_WRITE(mac, 0x815, 0);
332
333		if (phy->phy_rev == 2) {
334			PHY_WRITE(mac, 0x811, 0);
335			PHY_WRITE(mac, 0x15, 0xc0);
336		} else if (phy->phy_rev > 5) {
337			PHY_WRITE(mac, 0x811, 0x400);
338			PHY_WRITE(mac, 0x15, 0xc0);
339		}
340	}
341
342	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
343		uint16_t val;
344
345		val = PHY_READ(mac, 0x400) & 0xff;
346		if (val == 3 || val == 5) {
347			PHY_WRITE(mac, 0x4c2, 0x1816);
348			PHY_WRITE(mac, 0x4c3, 0x8006);
349			if (val == 5) {
350				PHY_FILT_SETBITS(mac, 0x4cc,
351						 0xff, 0x1f00);
352			}
353		}
354	}
355
356	if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
357	    phy->phy_rev >= 2)
358		PHY_WRITE(mac, 0x47e, 0x78);
359
360	if (rf->rf_rev == 8) {
361		PHY_SETBITS(mac, 0x801, 0x80);
362		PHY_SETBITS(mac, 0x43e, 0x4);
363	}
364
365	if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
366		bwi_rf_get_gains(mac);
367
368	if (rf->rf_rev != 8)
369		bwi_rf_init(mac);
370
371	if (tpctl->tp_ctrl2 == 0xffff) {
372		bwi_rf_lo_update(mac);
373	} else {
374		if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
375			RF_WRITE(mac, 0x52,
376				 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
377		} else {
378			RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl1);
379		}
380
381		if (phy->phy_rev >= 6) {
382			PHY_FILT_SETBITS(mac, 0x36, 0xfff,
383					 tpctl->tp_ctrl2 << 12);
384		}
385
386		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
387			PHY_WRITE(mac, 0x2e, 0x8075);
388		else
389			PHY_WRITE(mac, 0x2e, 0x807f);
390
391		if (phy->phy_rev < 2)
392			PHY_WRITE(mac, 0x2f, 0x101);
393		else
394			PHY_WRITE(mac, 0x2f, 0x202);
395	}
396
397	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
398		bwi_rf_lo_adjust(mac, tpctl);
399		PHY_WRITE(mac, 0x80f, 0x8078);
400	}
401
402	if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
403		bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
404		bwi_rf_set_nrssi_thr(mac);
405	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
406		if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
407			KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI,
408			    ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
409			bwi_rf_calc_nrssi_slope(mac);
410		} else {
411			KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI,
412			    ("rf_nrssi[1] %d", rf->rf_nrssi[1]));
413			bwi_rf_set_nrssi_thr(mac);
414		}
415	}
416
417	if (rf->rf_rev == 8)
418		PHY_WRITE(mac, 0x805, 0x3230);
419
420	bwi_mac_init_tpctl_11bg(mac);
421
422	if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
423		PHY_CLRBITS(mac, 0x429, 0x4000);
424		PHY_CLRBITS(mac, 0x4c3, 0x8000);
425	}
426}
427
428static void
429bwi_phy_init_11b_rev2(struct bwi_mac *mac)
430{
431	/* TODO:11B */
432	if_printf(mac->mac_sc->sc_ifp,
433		  "%s is not implemented yet\n", __func__);
434}
435
436static void
437bwi_phy_init_11b_rev4(struct bwi_mac *mac)
438{
439	struct bwi_softc *sc = mac->mac_sc;
440	struct bwi_rf *rf = &mac->mac_rf;
441	uint16_t val, ofs;
442	u_int chan;
443
444	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
445
446	PHY_WRITE(mac, 0x20, 0x301c);
447	PHY_WRITE(mac, 0x26, 0);
448	PHY_WRITE(mac, 0x30, 0xc6);
449	PHY_WRITE(mac, 0x88, 0x3e00);
450
451	for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
452		PHY_WRITE(mac, 0x89 + ofs, val);
453
454	CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
455
456	chan = rf->rf_curchan;
457	if (chan == IEEE80211_CHAN_ANY)
458		chan = 6;	/* Force to channel 6 */
459	bwi_rf_set_chan(mac, chan, 0);
460
461	if (rf->rf_type != BWI_RF_T_BCM2050) {
462		RF_WRITE(mac, 0x75, 0x80);
463		RF_WRITE(mac, 0x79, 0x81);
464	}
465
466	RF_WRITE(mac, 0x50, 0x20);
467	RF_WRITE(mac, 0x50, 0x23);
468
469	if (rf->rf_type == BWI_RF_T_BCM2050) {
470		RF_WRITE(mac, 0x50, 0x20);
471		RF_WRITE(mac, 0x5a, 0x70);
472		RF_WRITE(mac, 0x5b, 0x7b);
473		RF_WRITE(mac, 0x5c, 0xb0);
474		RF_WRITE(mac, 0x7a, 0xf);
475		PHY_WRITE(mac, 0x38, 0x677);
476		bwi_rf_init_bcm2050(mac);
477	}
478
479	PHY_WRITE(mac, 0x14, 0x80);
480	PHY_WRITE(mac, 0x32, 0xca);
481	if (rf->rf_type == BWI_RF_T_BCM2050)
482		PHY_WRITE(mac, 0x32, 0xe0);
483	PHY_WRITE(mac, 0x35, 0x7c2);
484
485	bwi_rf_lo_update(mac);
486
487	PHY_WRITE(mac, 0x26, 0xcc00);
488	if (rf->rf_type == BWI_RF_T_BCM2050)
489		PHY_WRITE(mac, 0x26, 0xce00);
490
491	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
492
493	PHY_WRITE(mac, 0x2a, 0x88a3);
494	if (rf->rf_type == BWI_RF_T_BCM2050)
495		PHY_WRITE(mac, 0x2a, 0x88c2);
496
497	bwi_mac_set_tpctl_11bg(mac, NULL);
498	if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
499		bwi_rf_calc_nrssi_slope(mac);
500		bwi_rf_set_nrssi_thr(mac);
501	}
502	bwi_mac_init_tpctl_11bg(mac);
503}
504
505static void
506bwi_phy_init_11b_rev5(struct bwi_mac *mac)
507{
508	struct bwi_softc *sc = mac->mac_sc;
509	struct bwi_rf *rf = &mac->mac_rf;
510	struct bwi_phy *phy = &mac->mac_phy;
511	u_int orig_chan;
512
513	if (phy->phy_version == 1)
514		RF_SETBITS(mac, 0x7a, 0x50);
515
516	if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
517	    sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
518		uint16_t ofs, val;
519
520		val = 0x2120;
521		for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
522			PHY_WRITE(mac, ofs, val);
523			val += 0x202;
524		}
525	}
526
527	PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
528
529	if (rf->rf_type == BWI_RF_T_BCM2050)
530		PHY_WRITE(mac, 0x38, 0x667);
531
532	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
533		if (rf->rf_type == BWI_RF_T_BCM2050) {
534			RF_SETBITS(mac, 0x7a, 0x20);
535			RF_SETBITS(mac, 0x51, 0x4);
536		}
537
538		CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
539
540		PHY_SETBITS(mac, 0x802, 0x100);
541		PHY_SETBITS(mac, 0x42b, 0x2000);
542		PHY_WRITE(mac, 0x1c, 0x186a);
543
544		PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
545		PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
546		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
547	}
548
549	/* TODO: bad_frame_preempt? */
550
551	if (phy->phy_version == 1) {
552	    	PHY_WRITE(mac, 0x26, 0xce00);
553		PHY_WRITE(mac, 0x21, 0x3763);
554		PHY_WRITE(mac, 0x22, 0x1bc3);
555		PHY_WRITE(mac, 0x23, 0x6f9);
556		PHY_WRITE(mac, 0x24, 0x37e);
557	} else {
558		PHY_WRITE(mac, 0x26, 0xcc00);
559	}
560	PHY_WRITE(mac, 0x30, 0xc6);
561
562	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
563
564	if (phy->phy_version == 1)
565		PHY_WRITE(mac, 0x20, 0x3e1c);
566	else
567		PHY_WRITE(mac, 0x20, 0x301c);
568
569	if (phy->phy_version == 0)
570		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
571
572	/* Force to channel 7 */
573	orig_chan = rf->rf_curchan;
574	bwi_rf_set_chan(mac, 7, 0);
575
576	if (rf->rf_type != BWI_RF_T_BCM2050) {
577		RF_WRITE(mac, 0x75, 0x80);
578		RF_WRITE(mac, 0x79, 0x81);
579	}
580
581	RF_WRITE(mac, 0x50, 0x20);
582	RF_WRITE(mac, 0x50, 0x23);
583
584	if (rf->rf_type == BWI_RF_T_BCM2050) {
585		RF_WRITE(mac, 0x50, 0x20);
586		RF_WRITE(mac, 0x5a, 0x70);
587	}
588
589	RF_WRITE(mac, 0x5b, 0x7b);
590	RF_WRITE(mac, 0x5c, 0xb0);
591	RF_SETBITS(mac, 0x7a, 0x7);
592
593	bwi_rf_set_chan(mac, orig_chan, 0);
594
595	PHY_WRITE(mac, 0x14, 0x80);
596	PHY_WRITE(mac, 0x32, 0xca);
597	PHY_WRITE(mac, 0x2a, 0x88a3);
598
599	bwi_mac_set_tpctl_11bg(mac, NULL);
600
601	if (rf->rf_type == BWI_RF_T_BCM2050)
602		RF_WRITE(mac, 0x5d, 0xd);
603
604	CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
605}
606
607static void
608bwi_phy_init_11b_rev6(struct bwi_mac *mac)
609{
610	struct bwi_softc *sc = mac->mac_sc;
611	struct bwi_rf *rf = &mac->mac_rf;
612	struct bwi_phy *phy = &mac->mac_phy;
613	uint16_t val, ofs;
614	u_int orig_chan;
615
616	PHY_WRITE(mac, 0x3e, 0x817a);
617	RF_SETBITS(mac, 0x7a, 0x58);
618
619	if (rf->rf_rev == 4 || rf->rf_rev == 5) {
620		RF_WRITE(mac, 0x51, 0x37);
621		RF_WRITE(mac, 0x52, 0x70);
622		RF_WRITE(mac, 0x53, 0xb3);
623		RF_WRITE(mac, 0x54, 0x9b);
624		RF_WRITE(mac, 0x5a, 0x88);
625		RF_WRITE(mac, 0x5b, 0x88);
626		RF_WRITE(mac, 0x5d, 0x88);
627		RF_WRITE(mac, 0x5e, 0x88);
628		RF_WRITE(mac, 0x7d, 0x88);
629		HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
630	} else if (rf->rf_rev == 8) {
631		RF_WRITE(mac, 0x51, 0);
632		RF_WRITE(mac, 0x52, 0x40);
633		RF_WRITE(mac, 0x53, 0xb7);
634		RF_WRITE(mac, 0x54, 0x98);
635		RF_WRITE(mac, 0x5a, 0x88);
636		RF_WRITE(mac, 0x5b, 0x6b);
637		RF_WRITE(mac, 0x5c, 0xf);
638		if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
639			RF_WRITE(mac, 0x5d, 0xfa);
640			RF_WRITE(mac, 0x5e, 0xd8);
641		} else {
642			RF_WRITE(mac, 0x5d, 0xf5);
643			RF_WRITE(mac, 0x5e, 0xb8);
644		}
645		RF_WRITE(mac, 0x73, 0x3);
646		RF_WRITE(mac, 0x7d, 0xa8);
647		RF_WRITE(mac, 0x7c, 0x1);
648		RF_WRITE(mac, 0x7e, 0x8);
649	}
650
651	val = 0x1e1f;
652	for (ofs = 0x88; ofs < 0x98; ++ofs) {
653		PHY_WRITE(mac, ofs, val);
654		val -= 0x202;
655	}
656
657	val = 0x3e3f;
658	for (ofs = 0x98; ofs < 0xa8; ++ofs) {
659		PHY_WRITE(mac, ofs, val);
660		val -= 0x202;
661	}
662
663	val = 0x2120;
664	for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
665		PHY_WRITE(mac, ofs, (val & 0x3f3f));
666		val += 0x202;
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
750static void
751bwi_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 < sizeof(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 */
885static void
886bwi_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
966void
967bwi_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
1019void
1020bwi_phy_clear_state(struct bwi_phy *phy)
1021{
1022	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1023}
1024