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
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#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		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
222void
223bwi_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
241int
242bwi_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
263static void
264bwi_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
275static void
276bwi_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
290void
291bwi_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
297int16_t
298bwi_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
304static void
305bwi_phy_init_11a(struct bwi_mac *mac)
306{
307	/* TODO:11A */
308}
309
310static void
311bwi_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
425static void
426bwi_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
433static void
434bwi_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
502static void
503bwi_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
604static void
605bwi_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
745static void
746bwi_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 */
878static void
879bwi_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
959void
960bwi_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
1012void
1013bwi_phy_clear_state(struct bwi_phy *phy)
1014{
1015	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1016}
1017