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