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