Deleted Added
full compact
if_bwn.c (298944) if_bwn.c (298948)
1/*-
2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/bwn/if_bwn.c 298944 2016-05-02 21:06:02Z adrian $");
31__FBSDID("$FreeBSD: head/sys/dev/bwn/if_bwn.c 298948 2016-05-02 22:58:11Z adrian $");
32
33/*
34 * The Broadcom Wireless LAN controller driver.
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>

--- 30 unchanged lines hidden (view full) ---

70#include <net80211/ieee80211_radiotap.h>
71#include <net80211/ieee80211_regdomain.h>
72#include <net80211/ieee80211_phy.h>
73#include <net80211/ieee80211_ratectl.h>
74
75#include <dev/bwn/if_bwnreg.h>
76#include <dev/bwn/if_bwnvar.h>
77
32
33/*
34 * The Broadcom Wireless LAN controller driver.
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>

--- 30 unchanged lines hidden (view full) ---

70#include <net80211/ieee80211_radiotap.h>
71#include <net80211/ieee80211_regdomain.h>
72#include <net80211/ieee80211_phy.h>
73#include <net80211/ieee80211_ratectl.h>
74
75#include <dev/bwn/if_bwnreg.h>
76#include <dev/bwn/if_bwnvar.h>
77
78#include <dev/bwn/if_bwn_debug.h>
78#include <dev/bwn/if_bwn_misc.h>
79#include <dev/bwn/if_bwn_misc.h>
80#include <dev/bwn/if_bwn_phy_g.h>
79#include <dev/bwn/if_bwn_phy_lp.h>
80
81static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
82 "Broadcom driver parameters");
83
84/*
85 * Tunable & sysctl variables.
86 */
87
88#ifdef BWN_DEBUG
89static int bwn_debug = 0;
90SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
91 "Broadcom debugging printfs");
81#include <dev/bwn/if_bwn_phy_lp.h>
82
83static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
84 "Broadcom driver parameters");
85
86/*
87 * Tunable & sysctl variables.
88 */
89
90#ifdef BWN_DEBUG
91static int bwn_debug = 0;
92SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
93 "Broadcom debugging printfs");
92enum {
93 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
94 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
95 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
96 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
97 BWN_DEBUG_RESET = 0x00000010, /* reset processing */
98 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */
99 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
100 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
101 BWN_DEBUG_INTR = 0x00000100, /* ISR */
102 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
103 BWN_DEBUG_NODE = 0x00000400, /* node management */
104 BWN_DEBUG_LED = 0x00000800, /* led management */
105 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */
106 BWN_DEBUG_LO = 0x00002000, /* LO */
107 BWN_DEBUG_FW = 0x00004000, /* firmware */
108 BWN_DEBUG_WME = 0x00008000, /* WME */
109 BWN_DEBUG_RF = 0x00010000, /* RF */
110 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
111 BWN_DEBUG_ANY = 0xffffffff
112};
113#define DPRINTF(sc, m, fmt, ...) do { \
114 if (sc->sc_debug & (m)) \
115 printf(fmt, __VA_ARGS__); \
116} while (0)
117#else
118#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
119#endif
120
121static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
122SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
123 "uses Bad Frames Preemption");
124static int bwn_bluetooth = 1;
125SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
126 "turns on Bluetooth Coexistence");

--- 13 unchanged lines hidden (view full) ---

140static void bwn_attach_pre(struct bwn_softc *);
141static int bwn_attach_post(struct bwn_softc *);
142static void bwn_sprom_bugfixes(device_t);
143static int bwn_init(struct bwn_softc *);
144static void bwn_parent(struct ieee80211com *);
145static void bwn_start(struct bwn_softc *);
146static int bwn_transmit(struct ieee80211com *, struct mbuf *);
147static int bwn_attach_core(struct bwn_mac *);
94#endif
95
96static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
97SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
98 "uses Bad Frames Preemption");
99static int bwn_bluetooth = 1;
100SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
101 "turns on Bluetooth Coexistence");

--- 13 unchanged lines hidden (view full) ---

115static void bwn_attach_pre(struct bwn_softc *);
116static int bwn_attach_post(struct bwn_softc *);
117static void bwn_sprom_bugfixes(device_t);
118static int bwn_init(struct bwn_softc *);
119static void bwn_parent(struct ieee80211com *);
120static void bwn_start(struct bwn_softc *);
121static int bwn_transmit(struct ieee80211com *, struct mbuf *);
122static int bwn_attach_core(struct bwn_mac *);
148static void bwn_reset_core(struct bwn_mac *, uint32_t);
149static int bwn_phy_getinfo(struct bwn_mac *, int);
150static int bwn_chiptest(struct bwn_mac *);
151static int bwn_setup_channels(struct bwn_mac *, int, int);
123static int bwn_phy_getinfo(struct bwn_mac *, int);
124static int bwn_chiptest(struct bwn_mac *);
125static int bwn_setup_channels(struct bwn_mac *, int, int);
152static int bwn_phy_g_attach(struct bwn_mac *);
153static void bwn_phy_g_detach(struct bwn_mac *);
154static void bwn_phy_g_init_pre(struct bwn_mac *);
155static int bwn_phy_g_prepare_hw(struct bwn_mac *);
156static int bwn_phy_g_init(struct bwn_mac *);
157static void bwn_phy_g_exit(struct bwn_mac *);
158static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
159static void bwn_phy_g_write(struct bwn_mac *, uint16_t,
160 uint16_t);
161static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
162static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
163 uint16_t);
164static int bwn_phy_g_hwpctl(struct bwn_mac *);
165static void bwn_phy_g_rf_onoff(struct bwn_mac *, int);
166static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
167static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
168static void bwn_phy_g_set_antenna(struct bwn_mac *, int);
169static int bwn_phy_g_im(struct bwn_mac *, int);
170static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
171static void bwn_phy_g_set_txpwr(struct bwn_mac *);
172static void bwn_phy_g_task_15s(struct bwn_mac *);
173static void bwn_phy_g_task_60s(struct bwn_mac *);
174static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
175static void bwn_phy_switch_analog(struct bwn_mac *, int);
176static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
177static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
178 uint16_t);
179static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
180static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
181 uint32_t);
182static void bwn_shm_ctlword(struct bwn_mac *, uint16_t,
183 uint16_t);
184static void bwn_addchannels(struct ieee80211_channel [], int, int *,
185 const struct bwn_channelinfo *, int);
186static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
187 const struct ieee80211_bpf_params *);
188static void bwn_updateslot(struct ieee80211com *);
189static void bwn_update_promisc(struct ieee80211com *);

--- 126 unchanged lines hidden (view full) ---

316static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
317 uint8_t);
318static int bwn_dma_attach(struct bwn_mac *);
319static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
320 int, int, int);
321static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
322 const struct bwn_txstatus *, uint16_t, int *);
323static void bwn_dma_free(struct bwn_mac *);
126static void bwn_shm_ctlword(struct bwn_mac *, uint16_t,
127 uint16_t);
128static void bwn_addchannels(struct ieee80211_channel [], int, int *,
129 const struct bwn_channelinfo *, int);
130static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
131 const struct ieee80211_bpf_params *);
132static void bwn_updateslot(struct ieee80211com *);
133static void bwn_update_promisc(struct ieee80211com *);

--- 126 unchanged lines hidden (view full) ---

260static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
261 uint8_t);
262static int bwn_dma_attach(struct bwn_mac *);
263static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
264 int, int, int);
265static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
266 const struct bwn_txstatus *, uint16_t, int *);
267static void bwn_dma_free(struct bwn_mac *);
324static void bwn_phy_g_init_sub(struct bwn_mac *);
325static uint8_t bwn_has_hwpctl(struct bwn_mac *);
326static void bwn_phy_init_b5(struct bwn_mac *);
327static void bwn_phy_init_b6(struct bwn_mac *);
328static void bwn_phy_init_a(struct bwn_mac *);
329static void bwn_loopback_calcgain(struct bwn_mac *);
330static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
331static void bwn_lo_g_init(struct bwn_mac *);
332static void bwn_lo_g_adjust(struct bwn_mac *);
333static void bwn_lo_get_powervector(struct bwn_mac *);
334static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
335 const struct bwn_bbatt *, const struct bwn_rfatt *);
336static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
337static void bwn_phy_hwpctl_init(struct bwn_mac *);
338static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
339static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
340 const struct bwn_bbatt *, const struct bwn_rfatt *,
341 uint8_t);
342static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
343static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
344static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
345static void bwn_wa_init(struct bwn_mac *);
346static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
347 uint16_t);
348static void bwn_dummy_transmission(struct bwn_mac *, int, int);
349static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
350 uint32_t);
351static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
352 uint16_t);
353static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
354static void bwn_psctl(struct bwn_mac *, uint32_t);
355static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
356static void bwn_nrssi_offset(struct bwn_mac *);
357static void bwn_nrssi_threshold(struct bwn_mac *);
358static void bwn_nrssi_slope_11g(struct bwn_mac *);
359static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360 int16_t);
361static void bwn_set_original_gains(struct bwn_mac *);
362static void bwn_hwpctl_early_init(struct bwn_mac *);
363static void bwn_hwpctl_init_gphy(struct bwn_mac *);
364static uint16_t bwn_phy_g_chan2freq(uint8_t);
365static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367 const char *, struct bwn_fwfile *);
368static void bwn_release_firmware(struct bwn_mac *);
369static void bwn_do_release_fw(struct bwn_fwfile *);
370static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371static int bwn_fwinitvals_write(struct bwn_mac *,
372 const struct bwn_fwinitvals *, size_t, size_t);
268static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
269static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
270 const char *, struct bwn_fwfile *);
271static void bwn_release_firmware(struct bwn_mac *);
272static void bwn_do_release_fw(struct bwn_fwfile *);
273static uint16_t bwn_fwcaps_read(struct bwn_mac *);
274static int bwn_fwinitvals_write(struct bwn_mac *,
275 const struct bwn_fwinitvals *, size_t, size_t);
373static int bwn_switch_channel(struct bwn_mac *, int);
374static uint16_t bwn_ant2phy(int);
375static void bwn_mac_write_bssid(struct bwn_mac *);
376static void bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377 const uint8_t *);
378static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379 const uint8_t *, size_t, const uint8_t *);
380static void bwn_key_macwrite(struct bwn_mac *, uint8_t,
381 const uint8_t *);

--- 31 unchanged lines hidden (view full) ---

413static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
414static int bwn_set_txhdr(struct bwn_mac *,
415 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
416 uint16_t);
417static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
418 const uint8_t);
419static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
420static uint8_t bwn_get_fbrate(uint8_t);
276static uint16_t bwn_ant2phy(int);
277static void bwn_mac_write_bssid(struct bwn_mac *);
278static void bwn_mac_setfilter(struct bwn_mac *, uint16_t,
279 const uint8_t *);
280static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
281 const uint8_t *, size_t, const uint8_t *);
282static void bwn_key_macwrite(struct bwn_mac *, uint8_t,
283 const uint8_t *);

--- 31 unchanged lines hidden (view full) ---

315static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
316static int bwn_set_txhdr(struct bwn_mac *,
317 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
318 uint16_t);
319static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
320 const uint8_t);
321static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
322static uint8_t bwn_get_fbrate(uint8_t);
421static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
422static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
423static void bwn_phy_lock(struct bwn_mac *);
424static void bwn_phy_unlock(struct bwn_mac *);
425static void bwn_rf_lock(struct bwn_mac *);
426static void bwn_rf_unlock(struct bwn_mac *);
427static void bwn_txpwr(void *, int);
428static void bwn_tasks(void *);
429static void bwn_task_15s(struct bwn_mac *);
430static void bwn_task_30s(struct bwn_mac *);
431static void bwn_task_60s(struct bwn_mac *);
432static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
433 uint8_t);
434static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
435static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
436 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
437 int, int);
438static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
323static void bwn_txpwr(void *, int);
324static void bwn_tasks(void *);
325static void bwn_task_15s(struct bwn_mac *);
326static void bwn_task_30s(struct bwn_mac *);
327static void bwn_task_60s(struct bwn_mac *);
328static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
329 uint8_t);
330static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
331static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
332 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
333 int, int);
334static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
439static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
440static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
441static void bwn_watchdog(void *);
442static void bwn_dma_stop(struct bwn_mac *);
443static void bwn_pio_stop(struct bwn_mac *);
444static void bwn_dma_ringstop(struct bwn_dma_ring **);
445static void bwn_led_attach(struct bwn_mac *);
446static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
447static void bwn_led_event(struct bwn_mac *, int);

--- 80 unchanged lines hidden (view full) ---

528 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
529 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
530 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
531 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
532 { 6130, 226, 30 }, { 6140, 228, 30 } },
533 .nchannels = 110
534};
535
335static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
336static void bwn_watchdog(void *);
337static void bwn_dma_stop(struct bwn_mac *);
338static void bwn_pio_stop(struct bwn_mac *);
339static void bwn_dma_ringstop(struct bwn_dma_ring **);
340static void bwn_led_attach(struct bwn_mac *);
341static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
342static void bwn_led_event(struct bwn_mac *, int);

--- 80 unchanged lines hidden (view full) ---

423 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
424 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
425 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
426 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
427 { 6130, 226, 30 }, { 6140, 228, 30 } },
428 .nchannels = 110
429};
430
536static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
537static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
538static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
539static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
540static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
541const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
542
543#define VENDOR_LED_ACT(vendor) \
544{ \
545 .vid = PCI_VENDOR_##vendor, \
546 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
547}
548
549static const struct {
550 uint16_t vid;

--- 805 unchanged lines hidden (view full) ---

1356 mac->mac_phy.switch_analog(mac, 0);
1357
1358 siba_dev_down(sc->sc_dev, 0);
1359fail:
1360 siba_powerdown(sc->sc_dev);
1361 return (error);
1362}
1363
431#define VENDOR_LED_ACT(vendor) \
432{ \
433 .vid = PCI_VENDOR_##vendor, \
434 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
435}
436
437static const struct {
438 uint16_t vid;

--- 805 unchanged lines hidden (view full) ---

1244 mac->mac_phy.switch_analog(mac, 0);
1245
1246 siba_dev_down(sc->sc_dev, 0);
1247fail:
1248 siba_powerdown(sc->sc_dev);
1249 return (error);
1250}
1251
1364static void
1252void
1365bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1366{
1367 struct bwn_softc *sc = mac->mac_sc;
1368 uint32_t low, ctl;
1369
1370 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1371
1372 siba_dev_up(sc->sc_dev, flags);

--- 153 unchanged lines hidden (view full) ---

1526 }
1527
1528 mac->mac_phy.supports_2ghz = have_bg;
1529 mac->mac_phy.supports_5ghz = have_a;
1530
1531 return (ic->ic_nchans == 0 ? ENXIO : 0);
1532}
1533
1253bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1254{
1255 struct bwn_softc *sc = mac->mac_sc;
1256 uint32_t low, ctl;
1257
1258 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1259
1260 siba_dev_up(sc->sc_dev, flags);

--- 153 unchanged lines hidden (view full) ---

1414 }
1415
1416 mac->mac_phy.supports_2ghz = have_bg;
1417 mac->mac_phy.supports_5ghz = have_a;
1418
1419 return (ic->ic_nchans == 0 ? ENXIO : 0);
1420}
1421
1534static uint32_t
1422uint32_t
1535bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1536{
1537 uint32_t ret;
1538
1539 BWN_ASSERT_LOCKED(mac->mac_sc);
1540
1541 if (way == BWN_SHARED) {
1542 KASSERT((offset & 0x0001) == 0,

--- 9 unchanged lines hidden (view full) ---

1552 offset >>= 2;
1553 }
1554 bwn_shm_ctlword(mac, way, offset);
1555 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1556out:
1557 return (ret);
1558}
1559
1423bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1424{
1425 uint32_t ret;
1426
1427 BWN_ASSERT_LOCKED(mac->mac_sc);
1428
1429 if (way == BWN_SHARED) {
1430 KASSERT((offset & 0x0001) == 0,

--- 9 unchanged lines hidden (view full) ---

1440 offset >>= 2;
1441 }
1442 bwn_shm_ctlword(mac, way, offset);
1443 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1444out:
1445 return (ret);
1446}
1447
1560static uint16_t
1448uint16_t
1561bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1562{
1563 uint16_t ret;
1564
1565 BWN_ASSERT_LOCKED(mac->mac_sc);
1566
1567 if (way == BWN_SHARED) {
1568 KASSERT((offset & 0x0001) == 0,

--- 19 unchanged lines hidden (view full) ---

1588 uint32_t control;
1589
1590 control = way;
1591 control <<= 16;
1592 control |= offset;
1593 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1594}
1595
1449bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1450{
1451 uint16_t ret;
1452
1453 BWN_ASSERT_LOCKED(mac->mac_sc);
1454
1455 if (way == BWN_SHARED) {
1456 KASSERT((offset & 0x0001) == 0,

--- 19 unchanged lines hidden (view full) ---

1476 uint32_t control;
1477
1478 control = way;
1479 control <<= 16;
1480 control |= offset;
1481 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1482}
1483
1596static void
1484void
1597bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1598 uint32_t value)
1599{
1600 BWN_ASSERT_LOCKED(mac->mac_sc);
1601
1602 if (way == BWN_SHARED) {
1603 KASSERT((offset & 0x0001) == 0,
1604 ("%s:%d warn", __func__, __LINE__));

--- 6 unchanged lines hidden (view full) ---

1611 return;
1612 }
1613 offset >>= 2;
1614 }
1615 bwn_shm_ctlword(mac, way, offset);
1616 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1617}
1618
1485bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1486 uint32_t value)
1487{
1488 BWN_ASSERT_LOCKED(mac->mac_sc);
1489
1490 if (way == BWN_SHARED) {
1491 KASSERT((offset & 0x0001) == 0,
1492 ("%s:%d warn", __func__, __LINE__));

--- 6 unchanged lines hidden (view full) ---

1499 return;
1500 }
1501 offset >>= 2;
1502 }
1503 bwn_shm_ctlword(mac, way, offset);
1504 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1505}
1506
1619static void
1507void
1620bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1621 uint16_t value)
1622{
1623 BWN_ASSERT_LOCKED(mac->mac_sc);
1624
1625 if (way == BWN_SHARED) {
1626 KASSERT((offset & 0x0001) == 0,
1627 ("%s:%d warn", __func__, __LINE__));

--- 65 unchanged lines hidden (view full) ---

1693 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1694 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
1695 c++, (*nchans)++;
1696 }
1697 }
1698}
1699
1700static int
1508bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1509 uint16_t value)
1510{
1511 BWN_ASSERT_LOCKED(mac->mac_sc);
1512
1513 if (way == BWN_SHARED) {
1514 KASSERT((offset & 0x0001) == 0,
1515 ("%s:%d warn", __func__, __LINE__));

--- 65 unchanged lines hidden (view full) ---

1581 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1582 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
1583 c++, (*nchans)++;
1584 }
1585 }
1586}
1587
1588static int
1701bwn_phy_g_attach(struct bwn_mac *mac)
1702{
1703 struct bwn_softc *sc = mac->mac_sc;
1704 struct bwn_phy *phy = &mac->mac_phy;
1705 struct bwn_phy_g *pg = &phy->phy_g;
1706 unsigned int i;
1707 int16_t pab0, pab1, pab2;
1708 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
1709 int8_t bg;
1710
1711 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
1712 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
1713 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
1714 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
1715
1716 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
1717 device_printf(sc->sc_dev, "not supported anymore\n");
1718
1719 pg->pg_flags = 0;
1720 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
1721 pab2 == -1) {
1722 pg->pg_idletssi = 52;
1723 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
1724 return (0);
1725 }
1726
1727 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
1728 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
1729 if (pg->pg_tssi2dbm == NULL) {
1730 device_printf(sc->sc_dev, "failed to allocate buffer\n");
1731 return (ENOMEM);
1732 }
1733 for (i = 0; i < 64; i++) {
1734 int32_t m1, m2, f, q, delta;
1735 int8_t j = 0;
1736
1737 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
1738 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
1739 f = 256;
1740
1741 do {
1742 if (j > 15) {
1743 device_printf(sc->sc_dev,
1744 "failed to generate tssi2dBm\n");
1745 free(pg->pg_tssi2dbm, M_DEVBUF);
1746 return (ENOMEM);
1747 }
1748 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
1749 f, 2048);
1750 delta = abs(q - f);
1751 f = q;
1752 j++;
1753 } while (delta >= 2);
1754
1755 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
1756 128);
1757 }
1758
1759 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
1760 return (0);
1761}
1762
1763static void
1764bwn_phy_g_detach(struct bwn_mac *mac)
1765{
1766 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
1767
1768 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
1769 free(pg->pg_tssi2dbm, M_DEVBUF);
1770 pg->pg_tssi2dbm = NULL;
1771 }
1772 pg->pg_flags = 0;
1773}
1774
1775static void
1776bwn_phy_g_init_pre(struct bwn_mac *mac)
1777{
1778 struct bwn_phy *phy = &mac->mac_phy;
1779 struct bwn_phy_g *pg = &phy->phy_g;
1780 void *tssi2dbm;
1781 int idletssi;
1782 unsigned int i;
1783
1784 tssi2dbm = pg->pg_tssi2dbm;
1785 idletssi = pg->pg_idletssi;
1786
1787 memset(pg, 0, sizeof(*pg));
1788
1789 pg->pg_tssi2dbm = tssi2dbm;
1790 pg->pg_idletssi = idletssi;
1791
1792 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
1793
1794 for (i = 0; i < N(pg->pg_nrssi); i++)
1795 pg->pg_nrssi[i] = -1000;
1796 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
1797 pg->pg_nrssi_lt[i] = i;
1798 pg->pg_lofcal = 0xffff;
1799 pg->pg_initval = 0xffff;
1800 pg->pg_immode = BWN_IMMODE_NONE;
1801 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
1802 pg->pg_avgtssi = 0xff;
1803
1804 pg->pg_loctl.tx_bias = 0xff;
1805 TAILQ_INIT(&pg->pg_loctl.calib_list);
1806}
1807
1808static int
1809bwn_phy_g_prepare_hw(struct bwn_mac *mac)
1810{
1811 struct bwn_phy *phy = &mac->mac_phy;
1812 struct bwn_phy_g *pg = &phy->phy_g;
1813 struct bwn_softc *sc = mac->mac_sc;
1814 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
1815 static const struct bwn_rfatt rfatt0[] = {
1816 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
1817 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
1818 { 3, 1 }, { 4, 1 }
1819 };
1820 static const struct bwn_rfatt rfatt1[] = {
1821 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
1822 { 14, 1 }
1823 };
1824 static const struct bwn_rfatt rfatt2[] = {
1825 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
1826 { 9, 1 }
1827 };
1828 static const struct bwn_bbatt bbatt_0[] = {
1829 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
1830 };
1831
1832 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
1833
1834 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
1835 pg->pg_bbatt.att = 0;
1836 else
1837 pg->pg_bbatt.att = 2;
1838
1839 /* prepare Radio Attenuation */
1840 pg->pg_rfatt.padmix = 0;
1841
1842 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
1843 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
1844 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
1845 pg->pg_rfatt.att = 2;
1846 goto done;
1847 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
1848 pg->pg_rfatt.att = 3;
1849 goto done;
1850 }
1851 }
1852
1853 if (phy->type == BWN_PHYTYPE_A) {
1854 pg->pg_rfatt.att = 0x60;
1855 goto done;
1856 }
1857
1858 switch (phy->rf_ver) {
1859 case 0x2050:
1860 switch (phy->rf_rev) {
1861 case 0:
1862 pg->pg_rfatt.att = 5;
1863 goto done;
1864 case 1:
1865 if (phy->type == BWN_PHYTYPE_G) {
1866 if (siba_get_pci_subvendor(sc->sc_dev) ==
1867 SIBA_BOARDVENDOR_BCM &&
1868 siba_get_pci_subdevice(sc->sc_dev) ==
1869 SIBA_BOARD_BCM4309G &&
1870 siba_get_pci_revid(sc->sc_dev) >= 30)
1871 pg->pg_rfatt.att = 3;
1872 else if (siba_get_pci_subvendor(sc->sc_dev) ==
1873 SIBA_BOARDVENDOR_BCM &&
1874 siba_get_pci_subdevice(sc->sc_dev) ==
1875 SIBA_BOARD_BU4306)
1876 pg->pg_rfatt.att = 3;
1877 else
1878 pg->pg_rfatt.att = 1;
1879 } else {
1880 if (siba_get_pci_subvendor(sc->sc_dev) ==
1881 SIBA_BOARDVENDOR_BCM &&
1882 siba_get_pci_subdevice(sc->sc_dev) ==
1883 SIBA_BOARD_BCM4309G &&
1884 siba_get_pci_revid(sc->sc_dev) >= 30)
1885 pg->pg_rfatt.att = 7;
1886 else
1887 pg->pg_rfatt.att = 6;
1888 }
1889 goto done;
1890 case 2:
1891 if (phy->type == BWN_PHYTYPE_G) {
1892 if (siba_get_pci_subvendor(sc->sc_dev) ==
1893 SIBA_BOARDVENDOR_BCM &&
1894 siba_get_pci_subdevice(sc->sc_dev) ==
1895 SIBA_BOARD_BCM4309G &&
1896 siba_get_pci_revid(sc->sc_dev) >= 30)
1897 pg->pg_rfatt.att = 3;
1898 else if (siba_get_pci_subvendor(sc->sc_dev) ==
1899 SIBA_BOARDVENDOR_BCM &&
1900 siba_get_pci_subdevice(sc->sc_dev) ==
1901 SIBA_BOARD_BU4306)
1902 pg->pg_rfatt.att = 5;
1903 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
1904 pg->pg_rfatt.att = 4;
1905 else
1906 pg->pg_rfatt.att = 3;
1907 } else
1908 pg->pg_rfatt.att = 6;
1909 goto done;
1910 case 3:
1911 pg->pg_rfatt.att = 5;
1912 goto done;
1913 case 4:
1914 case 5:
1915 pg->pg_rfatt.att = 1;
1916 goto done;
1917 case 6:
1918 case 7:
1919 pg->pg_rfatt.att = 5;
1920 goto done;
1921 case 8:
1922 pg->pg_rfatt.att = 0xa;
1923 pg->pg_rfatt.padmix = 1;
1924 goto done;
1925 case 9:
1926 default:
1927 pg->pg_rfatt.att = 5;
1928 goto done;
1929 }
1930 break;
1931 case 0x2053:
1932 switch (phy->rf_rev) {
1933 case 1:
1934 pg->pg_rfatt.att = 6;
1935 goto done;
1936 }
1937 break;
1938 }
1939 pg->pg_rfatt.att = 5;
1940done:
1941 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
1942
1943 if (!bwn_has_hwpctl(mac)) {
1944 lo->rfatt.array = rfatt0;
1945 lo->rfatt.len = N(rfatt0);
1946 lo->rfatt.min = 0;
1947 lo->rfatt.max = 9;
1948 goto genbbatt;
1949 }
1950 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
1951 lo->rfatt.array = rfatt1;
1952 lo->rfatt.len = N(rfatt1);
1953 lo->rfatt.min = 0;
1954 lo->rfatt.max = 14;
1955 goto genbbatt;
1956 }
1957 lo->rfatt.array = rfatt2;
1958 lo->rfatt.len = N(rfatt2);
1959 lo->rfatt.min = 0;
1960 lo->rfatt.max = 9;
1961genbbatt:
1962 lo->bbatt.array = bbatt_0;
1963 lo->bbatt.len = N(bbatt_0);
1964 lo->bbatt.min = 0;
1965 lo->bbatt.max = 8;
1966
1967 BWN_READ_4(mac, BWN_MACCTL);
1968 if (phy->rev == 1) {
1969 phy->gmode = 0;
1970 bwn_reset_core(mac, 0);
1971 bwn_phy_g_init_sub(mac);
1972 phy->gmode = 1;
1973 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
1974 }
1975 return (0);
1976}
1977
1978static uint16_t
1979bwn_phy_g_txctl(struct bwn_mac *mac)
1980{
1981 struct bwn_phy *phy = &mac->mac_phy;
1982
1983 if (phy->rf_ver != 0x2050)
1984 return (0);
1985 if (phy->rf_rev == 1)
1986 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
1987 if (phy->rf_rev < 6)
1988 return (BWN_TXCTL_PA2DB);
1989 if (phy->rf_rev == 8)
1990 return (BWN_TXCTL_TXMIX);
1991 return (0);
1992}
1993
1994static int
1995bwn_phy_g_init(struct bwn_mac *mac)
1996{
1997
1998 bwn_phy_g_init_sub(mac);
1999 return (0);
2000}
2001
2002static void
2003bwn_phy_g_exit(struct bwn_mac *mac)
2004{
2005 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2006 struct bwn_lo_calib *cal, *tmp;
2007
2008 if (lo == NULL)
2009 return;
2010 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2011 TAILQ_REMOVE(&lo->calib_list, cal, list);
2012 free(cal, M_DEVBUF);
2013 }
2014}
2015
2016static uint16_t
2017bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2018{
2019
2020 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2021 return (BWN_READ_2(mac, BWN_PHYDATA));
2022}
2023
2024static void
2025bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2026{
2027
2028 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2029 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2030}
2031
2032static uint16_t
2033bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2034{
2035
2036 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2037 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2038 return (BWN_READ_2(mac, BWN_RFDATALO));
2039}
2040
2041static void
2042bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2043{
2044
2045 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2046 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2047 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2048}
2049
2050static int
2051bwn_phy_g_hwpctl(struct bwn_mac *mac)
2052{
2053
2054 return (mac->mac_phy.rev >= 6);
2055}
2056
2057static void
2058bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2059{
2060 struct bwn_phy *phy = &mac->mac_phy;
2061 struct bwn_phy_g *pg = &phy->phy_g;
2062 unsigned int channel;
2063 uint16_t rfover, rfoverval;
2064
2065 if (on) {
2066 if (phy->rf_on)
2067 return;
2068
2069 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2070 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2071 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2072 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2074 pg->pg_radioctx_over);
2075 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2076 pg->pg_radioctx_overval);
2077 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2078 }
2079 channel = phy->chan;
2080 bwn_phy_g_switch_chan(mac, 6, 1);
2081 bwn_phy_g_switch_chan(mac, channel, 0);
2082 return;
2083 }
2084
2085 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2086 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2087 pg->pg_radioctx_over = rfover;
2088 pg->pg_radioctx_overval = rfoverval;
2089 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2090 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2091 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2092}
2093
2094static int
2095bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2096{
2097
2098 if ((newchan < 1) || (newchan > 14))
2099 return (EINVAL);
2100 bwn_phy_g_switch_chan(mac, newchan, 0);
2101
2102 return (0);
2103}
2104
2105static uint32_t
2106bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2107{
2108
2109 return (1);
2110}
2111
2112static void
2113bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2114{
2115 struct bwn_phy *phy = &mac->mac_phy;
2116 uint64_t hf;
2117 int autodiv = 0;
2118 uint16_t tmp;
2119
2120 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2121 autodiv = 1;
2122
2123 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2124 bwn_hf_write(mac, hf);
2125
2126 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2127 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2128 ((autodiv ? BWN_ANTAUTO1 : antenna)
2129 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2130
2131 if (autodiv) {
2132 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2133 if (antenna == BWN_ANTAUTO1)
2134 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2135 else
2136 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2137 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2138 }
2139 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2140 if (autodiv)
2141 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2142 else
2143 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2144 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2145 if (phy->rev >= 2) {
2146 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2147 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2148 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2149 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2150 0x15);
2151 if (phy->rev == 2)
2152 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2153 else
2154 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2155 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2156 8);
2157 }
2158 if (phy->rev >= 6)
2159 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2160
2161 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2162 bwn_hf_write(mac, hf);
2163}
2164
2165static int
2166bwn_phy_g_im(struct bwn_mac *mac, int mode)
2167{
2168 struct bwn_phy *phy = &mac->mac_phy;
2169 struct bwn_phy_g *pg = &phy->phy_g;
2170
2171 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2172 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2173
2174 if (phy->rev == 0 || !phy->gmode)
2175 return (ENODEV);
2176
2177 pg->pg_aci_wlan_automatic = 0;
2178 return (0);
2179}
2180
2181static int
2182bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2183{
2184 struct bwn_phy *phy = &mac->mac_phy;
2185 struct bwn_phy_g *pg = &phy->phy_g;
2186 struct bwn_softc *sc = mac->mac_sc;
2187 unsigned int tssi;
2188 int cck, ofdm;
2189 int power;
2190 int rfatt, bbatt;
2191 unsigned int max;
2192
2193 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2194
2195 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2196 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2197 if (cck < 0 && ofdm < 0) {
2198 if (ignore_tssi == 0)
2199 return (BWN_TXPWR_RES_DONE);
2200 cck = 0;
2201 ofdm = 0;
2202 }
2203 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2204 if (pg->pg_avgtssi != 0xff)
2205 tssi = (tssi + pg->pg_avgtssi) / 2;
2206 pg->pg_avgtssi = tssi;
2207 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2208
2209 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2210 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2211 max -= 3;
2212 if (max >= 120) {
2213 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2214 max = 80;
2215 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2216 }
2217
2218 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2219 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2220 tssi, 0x00), 0x3f)]);
2221 if (power == 0)
2222 return (BWN_TXPWR_RES_DONE);
2223
2224 rfatt = -((power + 7) / 8);
2225 bbatt = (-(power / 2)) - (4 * rfatt);
2226 if ((rfatt == 0) && (bbatt == 0))
2227 return (BWN_TXPWR_RES_DONE);
2228 pg->pg_bbatt_delta = bbatt;
2229 pg->pg_rfatt_delta = rfatt;
2230 return (BWN_TXPWR_RES_NEED_ADJUST);
2231}
2232
2233static void
2234bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2235{
2236 struct bwn_phy *phy = &mac->mac_phy;
2237 struct bwn_phy_g *pg = &phy->phy_g;
2238 struct bwn_softc *sc = mac->mac_sc;
2239 int rfatt, bbatt;
2240 uint8_t txctl;
2241
2242 bwn_mac_suspend(mac);
2243
2244 BWN_ASSERT_LOCKED(sc);
2245
2246 bbatt = pg->pg_bbatt.att;
2247 bbatt += pg->pg_bbatt_delta;
2248 rfatt = pg->pg_rfatt.att;
2249 rfatt += pg->pg_rfatt_delta;
2250
2251 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2252 txctl = pg->pg_txctl;
2253 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2254 if (rfatt <= 1) {
2255 if (txctl == 0) {
2256 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2257 rfatt += 2;
2258 bbatt += 2;
2259 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2260 BWN_BFL_PACTRL) {
2261 bbatt += 4 * (rfatt - 2);
2262 rfatt = 2;
2263 }
2264 } else if (rfatt > 4 && txctl) {
2265 txctl = 0;
2266 if (bbatt < 3) {
2267 rfatt -= 3;
2268 bbatt += 2;
2269 } else {
2270 rfatt -= 2;
2271 bbatt -= 2;
2272 }
2273 }
2274 }
2275 pg->pg_txctl = txctl;
2276 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2277 pg->pg_rfatt.att = rfatt;
2278 pg->pg_bbatt.att = bbatt;
2279
2280 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2281
2282 bwn_phy_lock(mac);
2283 bwn_rf_lock(mac);
2284 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2285 pg->pg_txctl);
2286 bwn_rf_unlock(mac);
2287 bwn_phy_unlock(mac);
2288
2289 bwn_mac_enable(mac);
2290}
2291
2292static void
2293bwn_phy_g_task_15s(struct bwn_mac *mac)
2294{
2295 struct bwn_phy *phy = &mac->mac_phy;
2296 struct bwn_phy_g *pg = &phy->phy_g;
2297 struct bwn_softc *sc = mac->mac_sc;
2298 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2299 unsigned long expire, now;
2300 struct bwn_lo_calib *cal, *tmp;
2301 uint8_t expired = 0;
2302
2303 bwn_mac_suspend(mac);
2304
2305 if (lo == NULL)
2306 goto fail;
2307
2308 BWN_GETTIME(now);
2309 if (bwn_has_hwpctl(mac)) {
2310 expire = now - BWN_LO_PWRVEC_EXPIRE;
2311 if (ieee80211_time_before(lo->pwr_vec_read_time, expire)) {
2312 bwn_lo_get_powervector(mac);
2313 bwn_phy_g_dc_lookup_init(mac, 0);
2314 }
2315 goto fail;
2316 }
2317
2318 expire = now - BWN_LO_CALIB_EXPIRE;
2319 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2320 if (!ieee80211_time_before(cal->calib_time, expire))
2321 continue;
2322 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2323 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2324 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2325 expired = 1;
2326 }
2327
2328 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2329 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2330 cal->ctl.i, cal->ctl.q);
2331
2332 TAILQ_REMOVE(&lo->calib_list, cal, list);
2333 free(cal, M_DEVBUF);
2334 }
2335 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2336 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2337 &pg->pg_rfatt);
2338 if (cal == NULL) {
2339 device_printf(sc->sc_dev,
2340 "failed to recalibrate LO\n");
2341 goto fail;
2342 }
2343 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2344 bwn_lo_write(mac, &cal->ctl);
2345 }
2346
2347fail:
2348 bwn_mac_enable(mac);
2349}
2350
2351static void
2352bwn_phy_g_task_60s(struct bwn_mac *mac)
2353{
2354 struct bwn_phy *phy = &mac->mac_phy;
2355 struct bwn_softc *sc = mac->mac_sc;
2356 uint8_t old = phy->chan;
2357
2358 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2359 return;
2360
2361 bwn_mac_suspend(mac);
2362 bwn_nrssi_slope_11g(mac);
2363 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2364 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2365 bwn_switch_channel(mac, old);
2366 }
2367 bwn_mac_enable(mac);
2368}
2369
2370static void
2371bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2372{
2373
2374 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2375}
2376
2377static int
2378bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2379 const struct ieee80211_bpf_params *params)
2380{
2381 struct ieee80211com *ic = ni->ni_ic;
2382 struct bwn_softc *sc = ic->ic_softc;
2383 struct bwn_mac *mac = sc->sc_curmac;
2384 int error;
2385

--- 1911 unchanged lines hidden (view full) ---

4297bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4298{
4299 if (!error) {
4300 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4301 *((bus_addr_t *)arg) = seg->ds_addr;
4302 }
4303}
4304
1589bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1590 const struct ieee80211_bpf_params *params)
1591{
1592 struct ieee80211com *ic = ni->ni_ic;
1593 struct bwn_softc *sc = ic->ic_softc;
1594 struct bwn_mac *mac = sc->sc_curmac;
1595 int error;
1596

--- 1911 unchanged lines hidden (view full) ---

3508bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
3509{
3510 if (!error) {
3511 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
3512 *((bus_addr_t *)arg) = seg->ds_addr;
3513 }
3514}
3515
4305static void
4306bwn_phy_g_init_sub(struct bwn_mac *mac)
4307{
4308 struct bwn_phy *phy = &mac->mac_phy;
4309 struct bwn_phy_g *pg = &phy->phy_g;
4310 struct bwn_softc *sc = mac->mac_sc;
4311 uint16_t i, tmp;
4312
4313 if (phy->rev == 1)
4314 bwn_phy_init_b5(mac);
4315 else
4316 bwn_phy_init_b6(mac);
4317
4318 if (phy->rev >= 2 || phy->gmode)
4319 bwn_phy_init_a(mac);
4320
4321 if (phy->rev >= 2) {
4322 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4323 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4324 }
4325 if (phy->rev == 2) {
4326 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4327 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4328 }
4329 if (phy->rev > 5) {
4330 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4331 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4332 }
4333 if (phy->gmode || phy->rev >= 2) {
4334 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4335 tmp &= BWN_PHYVER_VERSION;
4336 if (tmp == 3 || tmp == 5) {
4337 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4338 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4339 }
4340 if (tmp == 5) {
4341 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4342 0x1f00);
4343 }
4344 }
4345 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4346 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4347 if (phy->rf_rev == 8) {
4348 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4349 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4350 }
4351 if (BWN_HAS_LOOPBACK(phy))
4352 bwn_loopback_calcgain(mac);
4353
4354 if (phy->rf_rev != 8) {
4355 if (pg->pg_initval == 0xffff)
4356 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4357 else
4358 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4359 }
4360 bwn_lo_g_init(mac);
4361 if (BWN_HAS_TXMAG(phy)) {
4362 BWN_RF_WRITE(mac, 0x52,
4363 (BWN_RF_READ(mac, 0x52) & 0xff00)
4364 | pg->pg_loctl.tx_bias |
4365 pg->pg_loctl.tx_magn);
4366 } else {
4367 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4368 }
4369 if (phy->rev >= 6) {
4370 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4371 (pg->pg_loctl.tx_bias << 12));
4372 }
4373 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4374 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4375 else
4376 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4377 if (phy->rev < 2)
4378 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4379 else
4380 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4381 if (phy->gmode || phy->rev >= 2) {
4382 bwn_lo_g_adjust(mac);
4383 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4384 }
4385
4386 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4387 for (i = 0; i < 64; i++) {
4388 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4389 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4390 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4391 -32), 31));
4392 }
4393 bwn_nrssi_threshold(mac);
4394 } else if (phy->gmode || phy->rev >= 2) {
4395 if (pg->pg_nrssi[0] == -1000) {
4396 KASSERT(pg->pg_nrssi[1] == -1000,
4397 ("%s:%d: fail", __func__, __LINE__));
4398 bwn_nrssi_slope_11g(mac);
4399 } else
4400 bwn_nrssi_threshold(mac);
4401 }
4402 if (phy->rf_rev == 8)
4403 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4404 bwn_phy_hwpctl_init(mac);
4405 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4406 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4407 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4408 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4409 }
4410}
4411
4412static uint8_t
4413bwn_has_hwpctl(struct bwn_mac *mac)
4414{
4415
4416 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4417 return (0);
4418 return (mac->mac_phy.use_hwpctl(mac));
4419}
4420
4421static void
4422bwn_phy_init_b5(struct bwn_mac *mac)
4423{
4424 struct bwn_phy *phy = &mac->mac_phy;
4425 struct bwn_phy_g *pg = &phy->phy_g;
4426 struct bwn_softc *sc = mac->mac_sc;
4427 uint16_t offset, value;
4428 uint8_t old_channel;
4429
4430 if (phy->analog == 1)
4431 BWN_RF_SET(mac, 0x007a, 0x0050);
4432 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4433 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4434 value = 0x2120;
4435 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4436 BWN_PHY_WRITE(mac, offset, value);
4437 value += 0x202;
4438 }
4439 }
4440 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4441 if (phy->rf_ver == 0x2050)
4442 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4443
4444 if (phy->gmode || phy->rev >= 2) {
4445 if (phy->rf_ver == 0x2050) {
4446 BWN_RF_SET(mac, 0x007a, 0x0020);
4447 BWN_RF_SET(mac, 0x0051, 0x0004);
4448 }
4449 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4450
4451 BWN_PHY_SET(mac, 0x0802, 0x0100);
4452 BWN_PHY_SET(mac, 0x042b, 0x2000);
4453
4454 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4455
4456 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4457 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4458 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4459 }
4460
4461 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4462 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4463
4464 if (phy->analog == 1) {
4465 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4466 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4467 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4468 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4469 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4470 } else
4471 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4472 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4473 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4474
4475 if (phy->analog == 1)
4476 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4477 else
4478 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4479
4480 if (phy->analog == 0)
4481 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4482
4483 old_channel = phy->chan;
4484 bwn_phy_g_switch_chan(mac, 7, 0);
4485
4486 if (phy->rf_ver != 0x2050) {
4487 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4488 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4489 }
4490
4491 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4492 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4493
4494 if (phy->rf_ver == 0x2050) {
4495 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4496 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4497 }
4498
4499 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4500 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4501 BWN_RF_SET(mac, 0x007a, 0x0007);
4502
4503 bwn_phy_g_switch_chan(mac, old_channel, 0);
4504 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4505 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4506 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4507
4508 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4509 pg->pg_txctl);
4510
4511 if (phy->rf_ver == 0x2050)
4512 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4513
4514 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4515}
4516
4517static void
4518bwn_loopback_calcgain(struct bwn_mac *mac)
4519{
4520 struct bwn_phy *phy = &mac->mac_phy;
4521 struct bwn_phy_g *pg = &phy->phy_g;
4522 struct bwn_softc *sc = mac->mac_sc;
4523 uint16_t backup_phy[16] = { 0 };
4524 uint16_t backup_radio[3];
4525 uint16_t backup_bband;
4526 uint16_t i, j, loop_i_max;
4527 uint16_t trsw_rx;
4528 uint16_t loop1_outer_done, loop1_inner_done;
4529
4530 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4531 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4532 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4533 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4534 if (phy->rev != 1) {
4535 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4536 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4537 }
4538 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4539 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4540 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4541 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4542 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4543 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4544 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4545 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4546 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4547 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4548 backup_bband = pg->pg_bbatt.att;
4549 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4550 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4551 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4552
4553 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4554 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4555 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4556 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4557 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4558 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4559 if (phy->rev != 1) {
4560 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4561 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4562 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4563 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4564 }
4565 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4566 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4567 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4568 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4569
4570 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4571 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4572 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4573
4574 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4575 if (phy->rev != 1) {
4576 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4577 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4578 }
4579 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4580
4581 if (phy->rf_rev == 8)
4582 BWN_RF_WRITE(mac, 0x43, 0x000f);
4583 else {
4584 BWN_RF_WRITE(mac, 0x52, 0);
4585 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4586 }
4587 bwn_phy_g_set_bbatt(mac, 11);
4588
4589 if (phy->rev >= 3)
4590 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4591 else
4592 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4593 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4594
4595 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4596 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4597
4598 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4599 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4600
4601 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4602 if (phy->rev >= 7) {
4603 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4604 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4605 }
4606 }
4607 BWN_RF_MASK(mac, 0x7a, 0x00f7);
4608
4609 j = 0;
4610 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4611 for (i = 0; i < loop_i_max; i++) {
4612 for (j = 0; j < 16; j++) {
4613 BWN_RF_WRITE(mac, 0x43, i);
4614 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4615 (j << 8));
4616 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4617 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4618 DELAY(20);
4619 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4620 goto done0;
4621 }
4622 }
4623done0:
4624 loop1_outer_done = i;
4625 loop1_inner_done = j;
4626 if (j >= 8) {
4627 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4628 trsw_rx = 0x1b;
4629 for (j = j - 8; j < 16; j++) {
4630 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4631 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4632 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4633 DELAY(20);
4634 trsw_rx -= 3;
4635 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4636 goto done1;
4637 }
4638 } else
4639 trsw_rx = 0x18;
4640done1:
4641
4642 if (phy->rev != 1) {
4643 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4644 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4645 }
4646 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4647 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4648 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4649 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4650 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4651 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4652 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4653 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4654 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4655
4656 bwn_phy_g_set_bbatt(mac, backup_bband);
4657
4658 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4659 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4660 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4661
4662 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4663 DELAY(10);
4664 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4665 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4666 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4667 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4668
4669 pg->pg_max_lb_gain =
4670 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4671 pg->pg_trsw_rx_gain = trsw_rx * 2;
4672}
4673
4674static uint16_t
4675bwn_rf_init_bcm2050(struct bwn_mac *mac)
4676{
4677 struct bwn_phy *phy = &mac->mac_phy;
4678 uint32_t tmp1 = 0, tmp2 = 0;
4679 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4680 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4681 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4682 static const uint8_t rcc_table[] = {
4683 0x02, 0x03, 0x01, 0x0f,
4684 0x06, 0x07, 0x05, 0x0f,
4685 0x0a, 0x0b, 0x09, 0x0f,
4686 0x0e, 0x0f, 0x0d, 0x0f,
4687 };
4688
4689 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
4690 rfoverval = rfover = cck3 = 0;
4691 radio0 = BWN_RF_READ(mac, 0x43);
4692 radio1 = BWN_RF_READ(mac, 0x51);
4693 radio2 = BWN_RF_READ(mac, 0x52);
4694 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4695 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4696 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4697 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4698
4699 if (phy->type == BWN_PHYTYPE_B) {
4700 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
4701 reg0 = BWN_READ_2(mac, 0x3ec);
4702
4703 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
4704 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
4705 } else if (phy->gmode || phy->rev >= 2) {
4706 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4707 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4708 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4709 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4710 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4711 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
4712
4713 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
4714 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
4715 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
4716 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
4717 if (BWN_HAS_LOOPBACK(phy)) {
4718 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4719 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4720 if (phy->rev >= 3)
4721 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4722 else
4723 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4724 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4725 }
4726
4727 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4728 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
4729 BWN_LPD(0, 1, 1)));
4730 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
4731 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
4732 }
4733 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
4734
4735 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
4736 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
4737 reg1 = BWN_READ_2(mac, 0x3e6);
4738 reg2 = BWN_READ_2(mac, 0x3f4);
4739
4740 if (phy->analog == 0)
4741 BWN_WRITE_2(mac, 0x03e6, 0x0122);
4742 else {
4743 if (phy->analog >= 2)
4744 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
4745 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
4746 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
4747 }
4748
4749 reg = BWN_RF_READ(mac, 0x60);
4750 index = (reg & 0x001e) >> 1;
4751 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
4752
4753 if (phy->type == BWN_PHYTYPE_B)
4754 BWN_RF_WRITE(mac, 0x78, 0x26);
4755 if (phy->gmode || phy->rev >= 2) {
4756 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4757 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
4758 BWN_LPD(0, 1, 1)));
4759 }
4760 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
4761 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
4762 if (phy->gmode || phy->rev >= 2) {
4763 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4764 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
4765 BWN_LPD(0, 0, 1)));
4766 }
4767 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
4768 BWN_RF_SET(mac, 0x51, 0x0004);
4769 if (phy->rf_rev == 8)
4770 BWN_RF_WRITE(mac, 0x43, 0x1f);
4771 else {
4772 BWN_RF_WRITE(mac, 0x52, 0);
4773 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
4774 }
4775 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
4776
4777 for (i = 0; i < 16; i++) {
4778 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
4779 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4780 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4781 if (phy->gmode || phy->rev >= 2) {
4782 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4783 bwn_rf_2050_rfoverval(mac,
4784 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4785 }
4786 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
4787 DELAY(10);
4788 if (phy->gmode || phy->rev >= 2) {
4789 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4790 bwn_rf_2050_rfoverval(mac,
4791 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4792 }
4793 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
4794 DELAY(10);
4795 if (phy->gmode || phy->rev >= 2) {
4796 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4797 bwn_rf_2050_rfoverval(mac,
4798 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
4799 }
4800 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
4801 DELAY(20);
4802 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4803 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
4804 if (phy->gmode || phy->rev >= 2) {
4805 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4806 bwn_rf_2050_rfoverval(mac,
4807 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4808 }
4809 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
4810 }
4811 DELAY(10);
4812
4813 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
4814 tmp1++;
4815 tmp1 >>= 9;
4816
4817 for (i = 0; i < 16; i++) {
4818 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
4819 BWN_RF_WRITE(mac, 0x78, radio78);
4820 DELAY(10);
4821 for (j = 0; j < 16; j++) {
4822 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
4823 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4824 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4825 if (phy->gmode || phy->rev >= 2) {
4826 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4827 bwn_rf_2050_rfoverval(mac,
4828 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4829 }
4830 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
4831 DELAY(10);
4832 if (phy->gmode || phy->rev >= 2) {
4833 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4834 bwn_rf_2050_rfoverval(mac,
4835 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4836 }
4837 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
4838 DELAY(10);
4839 if (phy->gmode || phy->rev >= 2) {
4840 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4841 bwn_rf_2050_rfoverval(mac,
4842 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
4843 }
4844 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
4845 DELAY(10);
4846 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4847 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
4848 if (phy->gmode || phy->rev >= 2) {
4849 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
4850 bwn_rf_2050_rfoverval(mac,
4851 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
4852 }
4853 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
4854 }
4855 tmp2++;
4856 tmp2 >>= 8;
4857 if (tmp1 < tmp2)
4858 break;
4859 }
4860
4861 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
4862 BWN_RF_WRITE(mac, 0x51, radio1);
4863 BWN_RF_WRITE(mac, 0x52, radio2);
4864 BWN_RF_WRITE(mac, 0x43, radio0);
4865 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
4866 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
4867 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
4868 BWN_WRITE_2(mac, 0x3e6, reg1);
4869 if (phy->analog != 0)
4870 BWN_WRITE_2(mac, 0x3f4, reg2);
4871 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
4872 bwn_spu_workaround(mac, phy->chan);
4873 if (phy->type == BWN_PHYTYPE_B) {
4874 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
4875 BWN_WRITE_2(mac, 0x3ec, reg0);
4876 } else if (phy->gmode) {
4877 BWN_WRITE_2(mac, BWN_PHY_RADIO,
4878 BWN_READ_2(mac, BWN_PHY_RADIO)
4879 & 0x7fff);
4880 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
4881 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
4882 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
4883 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
4884 analogoverval);
4885 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
4886 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
4887 if (BWN_HAS_LOOPBACK(phy)) {
4888 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
4889 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
4890 }
4891 }
4892
4893 return ((i > 15) ? radio78 : rcc);
4894}
4895
4896static void
4897bwn_phy_init_b6(struct bwn_mac *mac)
4898{
4899 struct bwn_phy *phy = &mac->mac_phy;
4900 struct bwn_phy_g *pg = &phy->phy_g;
4901 struct bwn_softc *sc = mac->mac_sc;
4902 uint16_t offset, val;
4903 uint8_t old_channel;
4904
4905 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
4906 ("%s:%d: fail", __func__, __LINE__));
4907
4908 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
4909 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
4910 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
4911 BWN_RF_WRITE(mac, 0x51, 0x37);
4912 BWN_RF_WRITE(mac, 0x52, 0x70);
4913 BWN_RF_WRITE(mac, 0x53, 0xb3);
4914 BWN_RF_WRITE(mac, 0x54, 0x9b);
4915 BWN_RF_WRITE(mac, 0x5a, 0x88);
4916 BWN_RF_WRITE(mac, 0x5b, 0x88);
4917 BWN_RF_WRITE(mac, 0x5d, 0x88);
4918 BWN_RF_WRITE(mac, 0x5e, 0x88);
4919 BWN_RF_WRITE(mac, 0x7d, 0x88);
4920 bwn_hf_write(mac,
4921 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
4922 }
4923 if (phy->rf_rev == 8) {
4924 BWN_RF_WRITE(mac, 0x51, 0);
4925 BWN_RF_WRITE(mac, 0x52, 0x40);
4926 BWN_RF_WRITE(mac, 0x53, 0xb7);
4927 BWN_RF_WRITE(mac, 0x54, 0x98);
4928 BWN_RF_WRITE(mac, 0x5a, 0x88);
4929 BWN_RF_WRITE(mac, 0x5b, 0x6b);
4930 BWN_RF_WRITE(mac, 0x5c, 0x0f);
4931 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
4932 BWN_RF_WRITE(mac, 0x5d, 0xfa);
4933 BWN_RF_WRITE(mac, 0x5e, 0xd8);
4934 } else {
4935 BWN_RF_WRITE(mac, 0x5d, 0xf5);
4936 BWN_RF_WRITE(mac, 0x5e, 0xb8);
4937 }
4938 BWN_RF_WRITE(mac, 0x0073, 0x0003);
4939 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
4940 BWN_RF_WRITE(mac, 0x007c, 0x0001);
4941 BWN_RF_WRITE(mac, 0x007e, 0x0008);
4942 }
4943 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
4944 BWN_PHY_WRITE(mac, offset, val);
4945 val -= 0x0202;
4946 }
4947 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
4948 BWN_PHY_WRITE(mac, offset, val);
4949 val -= 0x0202;
4950 }
4951 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
4952 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
4953 val += 0x0202;
4954 }
4955 if (phy->type == BWN_PHYTYPE_G) {
4956 BWN_RF_SET(mac, 0x007a, 0x0020);
4957 BWN_RF_SET(mac, 0x0051, 0x0004);
4958 BWN_PHY_SET(mac, 0x0802, 0x0100);
4959 BWN_PHY_SET(mac, 0x042b, 0x2000);
4960 BWN_PHY_WRITE(mac, 0x5b, 0);
4961 BWN_PHY_WRITE(mac, 0x5c, 0);
4962 }
4963
4964 old_channel = phy->chan;
4965 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
4966
4967 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4968 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4969 DELAY(40);
4970 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
4971 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
4972 BWN_RF_WRITE(mac, 0x50, 0x20);
4973 }
4974 if (phy->rf_rev <= 2) {
4975 BWN_RF_WRITE(mac, 0x7c, 0x20);
4976 BWN_RF_WRITE(mac, 0x5a, 0x70);
4977 BWN_RF_WRITE(mac, 0x5b, 0x7b);
4978 BWN_RF_WRITE(mac, 0x5c, 0xb0);
4979 }
4980 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
4981
4982 bwn_phy_g_switch_chan(mac, old_channel, 0);
4983
4984 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
4985 if (phy->rf_rev >= 6)
4986 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
4987 else
4988 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
4989 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
4990 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4991 pg->pg_txctl);
4992 if (phy->rf_rev <= 5)
4993 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
4994 if (phy->rf_rev <= 2)
4995 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4996
4997 if (phy->analog == 4) {
4998 BWN_WRITE_2(mac, 0x3e4, 9);
4999 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5000 } else
5001 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5002 if (phy->type == BWN_PHYTYPE_B)
5003 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5004 else if (phy->type == BWN_PHYTYPE_G)
5005 BWN_WRITE_2(mac, 0x03e6, 0x0);
5006}
5007
5008static void
5009bwn_phy_init_a(struct bwn_mac *mac)
5010{
5011 struct bwn_phy *phy = &mac->mac_phy;
5012 struct bwn_softc *sc = mac->mac_sc;
5013
5014 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5015 ("%s:%d: fail", __func__, __LINE__));
5016
5017 if (phy->rev >= 6) {
5018 if (phy->type == BWN_PHYTYPE_A)
5019 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5020 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5021 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5022 else
5023 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5024 }
5025
5026 bwn_wa_init(mac);
5027
5028 if (phy->type == BWN_PHYTYPE_G &&
5029 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5030 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5031}
5032
5033static void
5034bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5035{
5036 int i;
5037
5038 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5039 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5040}
5041
5042static void
5043bwn_wa_agc(struct bwn_mac *mac)
5044{
5045 struct bwn_phy *phy = &mac->mac_phy;
5046
5047 if (phy->rev == 1) {
5048 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5049 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5050 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5051 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5052 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5053 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5054 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5055 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5056 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5057 } else {
5058 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5059 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5060 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5061 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5062 }
5063
5064 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5065 0x5700);
5066 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5067 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5068 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5069 BWN_RF_SET(mac, 0x7a, 0x0008);
5070 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5071 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5072 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5073 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5074 if (phy->rev == 1)
5075 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5076 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5077 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5078 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5079 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5080 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5081 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5082 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5083 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5084 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5085 if (phy->rev == 1) {
5086 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5087 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5088 } else {
5089 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5090 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5091 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5092 if (phy->rev >= 6) {
5093 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5094 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5095 (uint16_t)~0xf000, 0x3000);
5096 }
5097 }
5098 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5099 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5100 if (phy->rev == 1) {
5101 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5102 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5103 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5104 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5105 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5106 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5107 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5108 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5109 } else {
5110 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5111 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5112 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5113 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5114 }
5115 if (phy->rev >= 6) {
5116 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5117 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5118 }
5119 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5120}
5121
5122static void
5123bwn_wa_grev1(struct bwn_mac *mac)
5124{
5125 struct bwn_phy *phy = &mac->mac_phy;
5126 int i;
5127 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5128 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5129 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5130
5131 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5132
5133 /* init CRSTHRES and ANTDWELL */
5134 if (phy->rev == 1) {
5135 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5136 } else if (phy->rev == 2) {
5137 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5138 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5139 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5140 } else {
5141 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5142 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5143 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5144 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5145 }
5146 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5147 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5148 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5149
5150 /* XXX support PHY-A??? */
5151 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5152 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5153 bwn_tab_finefreqg[i]);
5154
5155 /* XXX support PHY-A??? */
5156 if (phy->rev == 1)
5157 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5158 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5159 bwn_tab_noise_g1[i]);
5160 else
5161 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5162 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5163 bwn_tab_noise_g2[i]);
5164
5165
5166 for (i = 0; i < N(bwn_tab_rotor); i++)
5167 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5168 bwn_tab_rotor[i]);
5169
5170 /* XXX support PHY-A??? */
5171 if (phy->rev >= 6) {
5172 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5173 BWN_PHY_ENCORE_EN)
5174 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5175 else
5176 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5177 } else
5178 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5179
5180 for (i = 0; i < N(bwn_tab_retard); i++)
5181 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5182 bwn_tab_retard[i]);
5183
5184 if (phy->rev == 1) {
5185 for (i = 0; i < 16; i++)
5186 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5187 i, 0x0020);
5188 } else {
5189 for (i = 0; i < 32; i++)
5190 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5191 }
5192
5193 bwn_wa_agc(mac);
5194}
5195
5196static void
5197bwn_wa_grev26789(struct bwn_mac *mac)
5198{
5199 struct bwn_phy *phy = &mac->mac_phy;
5200 int i;
5201 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5202 uint16_t ofdmrev;
5203
5204 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5205
5206 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5207
5208 /* init CRSTHRES and ANTDWELL */
5209 if (phy->rev == 1)
5210 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5211 else if (phy->rev == 2) {
5212 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5213 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5214 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5215 } else {
5216 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5217 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5218 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5219 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5220 }
5221
5222 for (i = 0; i < 64; i++)
5223 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5224
5225 /* XXX support PHY-A??? */
5226 if (phy->rev == 1)
5227 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5228 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5229 bwn_tab_noise_g1[i]);
5230 else
5231 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5232 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5233 bwn_tab_noise_g2[i]);
5234
5235 /* XXX support PHY-A??? */
5236 if (phy->rev >= 6) {
5237 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5238 BWN_PHY_ENCORE_EN)
5239 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5240 else
5241 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5242 } else
5243 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5244
5245 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5246 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5247 bwn_tab_sigmasqr2[i]);
5248
5249 if (phy->rev == 1) {
5250 for (i = 0; i < 16; i++)
5251 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5252 0x0020);
5253 } else {
5254 for (i = 0; i < 32; i++)
5255 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5256 }
5257
5258 bwn_wa_agc(mac);
5259
5260 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5261 if (ofdmrev > 2) {
5262 if (phy->type == BWN_PHYTYPE_A)
5263 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5264 else
5265 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5266 } else {
5267 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5268 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5269 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5270 }
5271
5272 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5273 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5274}
5275
5276static void
5277bwn_wa_init(struct bwn_mac *mac)
5278{
5279 struct bwn_phy *phy = &mac->mac_phy;
5280 struct bwn_softc *sc = mac->mac_sc;
5281
5282 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5283
5284 switch (phy->rev) {
5285 case 1:
5286 bwn_wa_grev1(mac);
5287 break;
5288 case 2:
5289 case 6:
5290 case 7:
5291 case 8:
5292 case 9:
5293 bwn_wa_grev26789(mac);
5294 break;
5295 default:
5296 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5297 }
5298
5299 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5300 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5301 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5302 if (phy->rev < 2) {
5303 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5304 0x0002);
5305 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5306 0x0001);
5307 } else {
5308 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5309 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5310 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5311 BWN_BFL_EXTLNA) &&
5312 (phy->rev >= 7)) {
5313 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5314 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5315 0x0020, 0x0001);
5316 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5317 0x0021, 0x0001);
5318 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5319 0x0022, 0x0001);
5320 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5321 0x0023, 0x0000);
5322 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5323 0x0000, 0x0000);
5324 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5325 0x0003, 0x0002);
5326 }
5327 }
5328 }
5329 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5330 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5331 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5332 }
5333
5334 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5335 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5336}
5337
5338static void
5339bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5340 uint16_t value)
5341{
5342 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5343 uint16_t addr;
5344
5345 addr = table + offset;
5346 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5347 (addr - 1 != pg->pg_ofdmtab_addr)) {
5348 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5349 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5350 }
5351 pg->pg_ofdmtab_addr = addr;
5352 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5353}
5354
5355static void
5356bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5357 uint32_t value)
5358{
5359 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5360 uint16_t addr;
5361
5362 addr = table + offset;
5363 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5364 (addr - 1 != pg->pg_ofdmtab_addr)) {
5365 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5366 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5367 }
5368 pg->pg_ofdmtab_addr = addr;
5369
5370 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5371 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5372}
5373
5374static void
5375bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5376 uint16_t value)
5377{
5378
5379 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5380 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5381}
5382
5383static void
5384bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5385{
5386 struct bwn_phy *phy = &mac->mac_phy;
5387 struct bwn_softc *sc = mac->mac_sc;
5388 unsigned int i, max_loop;
5389 uint16_t value;
5390 uint32_t buffer[5] = {
5391 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5392 };
5393
5394 if (ofdm) {
5395 max_loop = 0x1e;
5396 buffer[0] = 0x000201cc;
5397 } else {
5398 max_loop = 0xfa;
5399 buffer[0] = 0x000b846e;
5400 }
5401
5402 BWN_ASSERT_LOCKED(mac->mac_sc);
5403
5404 for (i = 0; i < 5; i++)
5405 bwn_ram_write(mac, i * 4, buffer[i]);
5406
5407 BWN_WRITE_2(mac, 0x0568, 0x0000);
5408 BWN_WRITE_2(mac, 0x07c0,
5409 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5410 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5411 BWN_WRITE_2(mac, 0x050c, value);
5412 if (phy->type == BWN_PHYTYPE_LP)
5413 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5414 BWN_WRITE_2(mac, 0x0508, 0x0000);
5415 BWN_WRITE_2(mac, 0x050a, 0x0000);
5416 BWN_WRITE_2(mac, 0x054c, 0x0000);
5417 BWN_WRITE_2(mac, 0x056a, 0x0014);
5418 BWN_WRITE_2(mac, 0x0568, 0x0826);
5419 BWN_WRITE_2(mac, 0x0500, 0x0000);
5420 if (phy->type == BWN_PHYTYPE_LP)
5421 BWN_WRITE_2(mac, 0x0502, 0x0050);
5422 else
5423 BWN_WRITE_2(mac, 0x0502, 0x0030);
5424
5425 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5426 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5427 for (i = 0x00; i < max_loop; i++) {
5428 value = BWN_READ_2(mac, 0x050e);
5429 if (value & 0x0080)
5430 break;
5431 DELAY(10);
5432 }
5433 for (i = 0x00; i < 0x0a; i++) {
5434 value = BWN_READ_2(mac, 0x050e);
5435 if (value & 0x0400)
5436 break;
5437 DELAY(10);
5438 }
5439 for (i = 0x00; i < 0x19; i++) {
5440 value = BWN_READ_2(mac, 0x0690);
5441 if (!(value & 0x0100))
5442 break;
5443 DELAY(10);
5444 }
5445 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5446 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5447}
5448
5449static void
3516void
5450bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5451{
5452 uint32_t macctl;
5453
5454 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5455
5456 macctl = BWN_READ_4(mac, BWN_MACCTL);
5457 if (macctl & BWN_MACCTL_BIGENDIAN)
5458 printf("TODO: need swap\n");
5459
5460 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5461 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5462 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5463}
5464
3517bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
3518{
3519 uint32_t macctl;
3520
3521 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
3522
3523 macctl = BWN_READ_4(mac, BWN_MACCTL);
3524 if (macctl & BWN_MACCTL_BIGENDIAN)
3525 printf("TODO: need swap\n");
3526
3527 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
3528 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
3529 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
3530}
3531
5465static void
5466bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5467{
5468 uint16_t value;
5469
5470 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5471 ("%s:%d: fail", __func__, __LINE__));
5472
5473 value = (uint8_t) (ctl->q);
5474 value |= ((uint8_t) (ctl->i)) << 8;
5475 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5476}
5477
5478static uint16_t
5479bwn_lo_calcfeed(struct bwn_mac *mac,
5480 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5481{
5482 struct bwn_phy *phy = &mac->mac_phy;
5483 struct bwn_softc *sc = mac->mac_sc;
5484 uint16_t rfover;
5485 uint16_t feedthrough;
5486
5487 if (phy->gmode) {
5488 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5489 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5490
5491 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5492 ("%s:%d: fail", __func__, __LINE__));
5493 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5494 ("%s:%d: fail", __func__, __LINE__));
5495
5496 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5497
5498 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5499 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5500 phy->rev > 6)
5501 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5502
5503 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5504 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5505 DELAY(10);
5506 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5507 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5508 DELAY(10);
5509 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5510 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5511 DELAY(10);
5512 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5513 } else {
5514 pga |= BWN_PHY_PGACTL_UNKNOWN;
5515 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5516 DELAY(10);
5517 pga |= BWN_PHY_PGACTL_LOWBANDW;
5518 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5519 DELAY(10);
5520 pga |= BWN_PHY_PGACTL_LPF;
5521 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5522 }
5523 DELAY(21);
5524 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5525
5526 return (feedthrough);
5527}
5528
5529static uint16_t
5530bwn_lo_txctl_regtable(struct bwn_mac *mac,
5531 uint16_t *value, uint16_t *pad_mix_gain)
5532{
5533 struct bwn_phy *phy = &mac->mac_phy;
5534 uint16_t reg, v, padmix;
5535
5536 if (phy->type == BWN_PHYTYPE_B) {
5537 v = 0x30;
5538 if (phy->rf_rev <= 5) {
5539 reg = 0x43;
5540 padmix = 0;
5541 } else {
5542 reg = 0x52;
5543 padmix = 5;
5544 }
5545 } else {
5546 if (phy->rev >= 2 && phy->rf_rev == 8) {
5547 reg = 0x43;
5548 v = 0x10;
5549 padmix = 2;
5550 } else {
5551 reg = 0x52;
5552 v = 0x30;
5553 padmix = 5;
5554 }
5555 }
5556 if (value)
5557 *value = v;
5558 if (pad_mix_gain)
5559 *pad_mix_gain = padmix;
5560
5561 return (reg);
5562}
5563
5564static void
5565bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5566{
5567 struct bwn_phy *phy = &mac->mac_phy;
5568 struct bwn_phy_g *pg = &phy->phy_g;
5569 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5570 uint16_t reg, mask;
5571 uint16_t trsw_rx, pga;
5572 uint16_t rf_pctl_reg;
5573
5574 static const uint8_t tx_bias_values[] = {
5575 0x09, 0x08, 0x0a, 0x01, 0x00,
5576 0x02, 0x05, 0x04, 0x06,
5577 };
5578 static const uint8_t tx_magn_values[] = {
5579 0x70, 0x40,
5580 };
5581
5582 if (!BWN_HAS_LOOPBACK(phy)) {
5583 rf_pctl_reg = 6;
5584 trsw_rx = 2;
5585 pga = 0;
5586 } else {
5587 int lb_gain;
5588
5589 trsw_rx = 0;
5590 lb_gain = pg->pg_max_lb_gain / 2;
5591 if (lb_gain > 10) {
5592 rf_pctl_reg = 0;
5593 pga = abs(10 - lb_gain) / 6;
5594 pga = MIN(MAX(pga, 0), 15);
5595 } else {
5596 int cmp_val;
5597 int tmp;
5598
5599 pga = 0;
5600 cmp_val = 0x24;
5601 if ((phy->rev >= 2) &&
5602 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5603 cmp_val = 0x3c;
5604 tmp = lb_gain;
5605 if ((10 - lb_gain) < cmp_val)
5606 tmp = (10 - lb_gain);
5607 if (tmp < 0)
5608 tmp += 6;
5609 else
5610 tmp += 3;
5611 cmp_val /= 4;
5612 tmp /= 4;
5613 if (tmp >= cmp_val)
5614 rf_pctl_reg = cmp_val;
5615 else
5616 rf_pctl_reg = tmp;
5617 }
5618 }
5619 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5620 bwn_phy_g_set_bbatt(mac, 2);
5621
5622 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5623 mask = ~mask;
5624 BWN_RF_MASK(mac, reg, mask);
5625
5626 if (BWN_HAS_TXMAG(phy)) {
5627 int i, j;
5628 int feedthrough;
5629 int min_feedth = 0xffff;
5630 uint8_t tx_magn, tx_bias;
5631
5632 for (i = 0; i < N(tx_magn_values); i++) {
5633 tx_magn = tx_magn_values[i];
5634 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5635 for (j = 0; j < N(tx_bias_values); j++) {
5636 tx_bias = tx_bias_values[j];
5637 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5638 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5639 trsw_rx);
5640 if (feedthrough < min_feedth) {
5641 lo->tx_bias = tx_bias;
5642 lo->tx_magn = tx_magn;
5643 min_feedth = feedthrough;
5644 }
5645 if (lo->tx_bias == 0)
5646 break;
5647 }
5648 BWN_RF_WRITE(mac, 0x52,
5649 (BWN_RF_READ(mac, 0x52)
5650 & 0xff00) | lo->tx_bias | lo->
5651 tx_magn);
5652 }
5653 } else {
5654 lo->tx_magn = 0;
5655 lo->tx_bias = 0;
5656 BWN_RF_MASK(mac, 0x52, 0xfff0);
5657 }
5658
5659 BWN_GETTIME(lo->txctl_measured_time);
5660}
5661
5662static void
5663bwn_lo_get_powervector(struct bwn_mac *mac)
5664{
5665 struct bwn_phy *phy = &mac->mac_phy;
5666 struct bwn_phy_g *pg = &phy->phy_g;
5667 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5668 int i;
5669 uint64_t tmp;
5670 uint64_t power_vector = 0;
5671
5672 for (i = 0; i < 8; i += 2) {
5673 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5674 power_vector |= (tmp << (i * 8));
5675 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5676 }
5677 if (power_vector)
5678 lo->power_vector = power_vector;
5679
5680 BWN_GETTIME(lo->pwr_vec_read_time);
5681}
5682
5683static void
5684bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5685 int use_trsw_rx)
5686{
5687 struct bwn_phy *phy = &mac->mac_phy;
5688 struct bwn_phy_g *pg = &phy->phy_g;
5689 uint16_t tmp;
5690
5691 if (max_rx_gain < 0)
5692 max_rx_gain = 0;
5693
5694 if (BWN_HAS_LOOPBACK(phy)) {
5695 int trsw_rx = 0;
5696 int trsw_rx_gain;
5697
5698 if (use_trsw_rx) {
5699 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
5700 if (max_rx_gain >= trsw_rx_gain) {
5701 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
5702 trsw_rx = 0x20;
5703 }
5704 } else
5705 trsw_rx_gain = max_rx_gain;
5706 if (trsw_rx_gain < 9) {
5707 pg->pg_lna_lod_gain = 0;
5708 } else {
5709 pg->pg_lna_lod_gain = 1;
5710 trsw_rx_gain -= 8;
5711 }
5712 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
5713 pg->pg_pga_gain = trsw_rx_gain / 3;
5714 if (pg->pg_pga_gain >= 5) {
5715 pg->pg_pga_gain -= 5;
5716 pg->pg_lna_gain = 2;
5717 } else
5718 pg->pg_lna_gain = 0;
5719 } else {
5720 pg->pg_lna_gain = 0;
5721 pg->pg_trsw_rx_gain = 0x20;
5722 if (max_rx_gain >= 0x14) {
5723 pg->pg_lna_lod_gain = 1;
5724 pg->pg_pga_gain = 2;
5725 } else if (max_rx_gain >= 0x12) {
5726 pg->pg_lna_lod_gain = 1;
5727 pg->pg_pga_gain = 1;
5728 } else if (max_rx_gain >= 0xf) {
5729 pg->pg_lna_lod_gain = 1;
5730 pg->pg_pga_gain = 0;
5731 } else {
5732 pg->pg_lna_lod_gain = 0;
5733 pg->pg_pga_gain = 0;
5734 }
5735 }
5736
5737 tmp = BWN_RF_READ(mac, 0x7a);
5738 if (pg->pg_lna_lod_gain == 0)
5739 tmp &= ~0x0008;
5740 else
5741 tmp |= 0x0008;
5742 BWN_RF_WRITE(mac, 0x7a, tmp);
5743}
5744
5745static void
5746bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
5747{
5748 struct bwn_phy *phy = &mac->mac_phy;
5749 struct bwn_phy_g *pg = &phy->phy_g;
5750 struct bwn_softc *sc = mac->mac_sc;
5751 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5752 struct timespec ts;
5753 uint16_t tmp;
5754
5755 if (bwn_has_hwpctl(mac)) {
5756 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5757 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
5758 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
5759 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
5760 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
5761
5762 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
5763 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
5764 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
5765 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
5766 }
5767 if (phy->type == BWN_PHYTYPE_B &&
5768 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
5769 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
5770 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
5771 }
5772 if (phy->rev >= 2) {
5773 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5774 sav->phy_analogoverval =
5775 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5776 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5777 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5778 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5779 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
5780 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5781
5782 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5783 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5784 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5785 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5786 if (phy->type == BWN_PHYTYPE_G) {
5787 if ((phy->rev >= 7) &&
5788 (siba_sprom_get_bf_lo(sc->sc_dev) &
5789 BWN_BFL_EXTLNA)) {
5790 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
5791 } else {
5792 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
5793 }
5794 } else {
5795 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
5796 }
5797 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
5798 }
5799 sav->reg0 = BWN_READ_2(mac, 0x3f4);
5800 sav->reg1 = BWN_READ_2(mac, 0x3e2);
5801 sav->rf0 = BWN_RF_READ(mac, 0x43);
5802 sav->rf1 = BWN_RF_READ(mac, 0x7a);
5803 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5804 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
5805 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5806 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
5807
5808 if (!BWN_HAS_TXMAG(phy)) {
5809 sav->rf2 = BWN_RF_READ(mac, 0x52);
5810 sav->rf2 &= 0x00f0;
5811 }
5812 if (phy->type == BWN_PHYTYPE_B) {
5813 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5814 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
5815 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
5816 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
5817 } else {
5818 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
5819 | 0x8000);
5820 }
5821 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
5822 & 0xf000);
5823
5824 tmp =
5825 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
5826 BWN_PHY_WRITE(mac, tmp, 0x007f);
5827
5828 tmp = sav->phy_syncctl;
5829 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
5830 tmp = sav->rf1;
5831 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
5832
5833 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
5834 if (phy->type == BWN_PHYTYPE_G ||
5835 (phy->type == BWN_PHYTYPE_B &&
5836 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
5837 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
5838 } else
5839 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
5840 if (phy->rev >= 2)
5841 bwn_dummy_transmission(mac, 0, 1);
5842 bwn_phy_g_switch_chan(mac, 6, 0);
5843 BWN_RF_READ(mac, 0x51);
5844 if (phy->type == BWN_PHYTYPE_G)
5845 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
5846
5847 nanouptime(&ts);
5848 if (ieee80211_time_before(lo->txctl_measured_time,
5849 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
5850 bwn_lo_measure_txctl_values(mac);
5851
5852 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
5853 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
5854 else {
5855 if (phy->type == BWN_PHYTYPE_B)
5856 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
5857 else
5858 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
5859 }
5860}
5861
5862static void
5863bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
5864{
5865 struct bwn_phy *phy = &mac->mac_phy;
5866 struct bwn_phy_g *pg = &phy->phy_g;
5867 uint16_t tmp;
5868
5869 if (phy->rev >= 2) {
5870 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5871 tmp = (pg->pg_pga_gain << 8);
5872 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
5873 DELAY(5);
5874 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
5875 DELAY(2);
5876 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
5877 } else {
5878 tmp = (pg->pg_pga_gain | 0xefa0);
5879 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
5880 }
5881 if (phy->type == BWN_PHYTYPE_G) {
5882 if (phy->rev >= 3)
5883 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
5884 else
5885 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
5886 if (phy->rev >= 2)
5887 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
5888 else
5889 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
5890 }
5891 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
5892 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
5893 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
5894 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
5895 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
5896 BWN_RF_WRITE(mac, 0x43, sav->rf0);
5897 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
5898 if (!BWN_HAS_TXMAG(phy)) {
5899 tmp = sav->rf2;
5900 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
5901 }
5902 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
5903 if (phy->type == BWN_PHYTYPE_B &&
5904 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
5905 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
5906 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
5907 }
5908 if (phy->rev >= 2) {
5909 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
5910 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5911 sav->phy_analogoverval);
5912 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
5913 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
5914 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
5915 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
5916 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
5917 }
5918 if (bwn_has_hwpctl(mac)) {
5919 tmp = (sav->phy_lomask & 0xbfff);
5920 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
5921 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
5922 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
5923 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
5924 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
5925 }
5926 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
5927}
5928
5929static int
5930bwn_lo_probe_loctl(struct bwn_mac *mac,
5931 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
5932{
5933 struct bwn_phy *phy = &mac->mac_phy;
5934 struct bwn_phy_g *pg = &phy->phy_g;
5935 struct bwn_loctl orig, test;
5936 struct bwn_loctl prev = { -100, -100 };
5937 static const struct bwn_loctl modifiers[] = {
5938 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
5939 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
5940 };
5941 int begin, end, lower = 0, i;
5942 uint16_t feedth;
5943
5944 if (d->curstate == 0) {
5945 begin = 1;
5946 end = 8;
5947 } else if (d->curstate % 2 == 0) {
5948 begin = d->curstate - 1;
5949 end = d->curstate + 1;
5950 } else {
5951 begin = d->curstate - 2;
5952 end = d->curstate + 2;
5953 }
5954 if (begin < 1)
5955 begin += 8;
5956 if (end > 8)
5957 end -= 8;
5958
5959 memcpy(&orig, probe, sizeof(struct bwn_loctl));
5960 i = begin;
5961 d->curstate = i;
5962 while (1) {
5963 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
5964 memcpy(&test, &orig, sizeof(struct bwn_loctl));
5965 test.i += modifiers[i - 1].i * d->multipler;
5966 test.q += modifiers[i - 1].q * d->multipler;
5967 if ((test.i != prev.i || test.q != prev.q) &&
5968 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
5969 bwn_lo_write(mac, &test);
5970 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
5971 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
5972 if (feedth < d->feedth) {
5973 memcpy(probe, &test,
5974 sizeof(struct bwn_loctl));
5975 lower = 1;
5976 d->feedth = feedth;
5977 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
5978 break;
5979 }
5980 }
5981 memcpy(&prev, &test, sizeof(prev));
5982 if (i == end)
5983 break;
5984 if (i == 8)
5985 i = 1;
5986 else
5987 i++;
5988 d->curstate = i;
5989 }
5990
5991 return (lower);
5992}
5993
5994static void
5995bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
5996{
5997 struct bwn_phy *phy = &mac->mac_phy;
5998 struct bwn_phy_g *pg = &phy->phy_g;
5999 struct bwn_lo_g_sm d;
6000 struct bwn_loctl probe;
6001 int lower, repeat, cnt = 0;
6002 uint16_t feedth;
6003
6004 d.nmeasure = 0;
6005 d.multipler = 1;
6006 if (BWN_HAS_LOOPBACK(phy))
6007 d.multipler = 3;
6008
6009 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6010 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6011
6012 do {
6013 bwn_lo_write(mac, &d.loctl);
6014 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6015 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6016 if (feedth < 0x258) {
6017 if (feedth >= 0x12c)
6018 *rxgain += 6;
6019 else
6020 *rxgain += 3;
6021 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6022 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6023 }
6024 d.feedth = feedth;
6025 d.curstate = 0;
6026 do {
6027 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6028 ("%s:%d: fail", __func__, __LINE__));
6029 memcpy(&probe, &d.loctl,
6030 sizeof(struct bwn_loctl));
6031 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6032 if (!lower)
6033 break;
6034 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6035 break;
6036 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6037 d.nmeasure++;
6038 } while (d.nmeasure < 24);
6039 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6040
6041 if (BWN_HAS_LOOPBACK(phy)) {
6042 if (d.feedth > 0x1194)
6043 *rxgain -= 6;
6044 else if (d.feedth < 0x5dc)
6045 *rxgain += 3;
6046 if (cnt == 0) {
6047 if (d.feedth <= 0x5dc) {
6048 d.multipler = 1;
6049 cnt++;
6050 } else
6051 d.multipler = 2;
6052 } else if (cnt == 2)
6053 d.multipler = 1;
6054 }
6055 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6056 } while (++cnt < repeat);
6057}
6058
6059static struct bwn_lo_calib *
6060bwn_lo_calibset(struct bwn_mac *mac,
6061 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6062{
6063 struct bwn_phy *phy = &mac->mac_phy;
6064 struct bwn_phy_g *pg = &phy->phy_g;
6065 struct bwn_loctl loctl = { 0, 0 };
6066 struct bwn_lo_calib *cal;
6067 struct bwn_lo_g_value sval = { 0 };
6068 int rxgain;
6069 uint16_t pad, reg, value;
6070
6071 sval.old_channel = phy->chan;
6072 bwn_mac_suspend(mac);
6073 bwn_lo_save(mac, &sval);
6074
6075 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6076 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6077 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6078
6079 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6080 if (rfatt->padmix)
6081 rxgain -= pad;
6082 if (BWN_HAS_LOOPBACK(phy))
6083 rxgain += pg->pg_max_lb_gain;
6084 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6085 bwn_phy_g_set_bbatt(mac, bbatt->att);
6086 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6087
6088 bwn_lo_restore(mac, &sval);
6089 bwn_mac_enable(mac);
6090
6091 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6092 if (!cal) {
6093 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6094 return (NULL);
6095 }
6096 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6097 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6098 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6099
6100 BWN_GETTIME(cal->calib_time);
6101
6102 return (cal);
6103}
6104
6105static struct bwn_lo_calib *
6106bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6107 const struct bwn_rfatt *rfatt)
6108{
6109 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6110 struct bwn_lo_calib *c;
6111
6112 TAILQ_FOREACH(c, &lo->calib_list, list) {
6113 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6114 continue;
6115 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6116 continue;
6117 return (c);
6118 }
6119
6120 c = bwn_lo_calibset(mac, bbatt, rfatt);
6121 if (!c)
6122 return (NULL);
6123 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6124
6125 return (c);
6126}
6127
6128static void
6129bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6130{
6131 struct bwn_phy *phy = &mac->mac_phy;
6132 struct bwn_phy_g *pg = &phy->phy_g;
6133 struct bwn_softc *sc = mac->mac_sc;
6134 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6135 const struct bwn_rfatt *rfatt;
6136 const struct bwn_bbatt *bbatt;
6137 uint64_t pvector;
6138 int i;
6139 int rf_offset, bb_offset;
6140 uint8_t changed = 0;
6141
6142 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6143 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6144 ("%s:%d: fail", __func__, __LINE__));
6145
6146 pvector = lo->power_vector;
6147 if (!update && !pvector)
6148 return;
6149
6150 bwn_mac_suspend(mac);
6151
6152 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6153 struct bwn_lo_calib *cal;
6154 int idx;
6155 uint16_t val;
6156
6157 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6158 continue;
6159 bb_offset = i / lo->rfatt.len;
6160 rf_offset = i % lo->rfatt.len;
6161 bbatt = &(lo->bbatt.array[bb_offset]);
6162 rfatt = &(lo->rfatt.array[rf_offset]);
6163
6164 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6165 if (!cal) {
6166 device_printf(sc->sc_dev, "LO: Could not "
6167 "calibrate DC table entry\n");
6168 continue;
6169 }
6170 val = (uint8_t)(cal->ctl.q);
6171 val |= ((uint8_t)(cal->ctl.i)) << 4;
6172 free(cal, M_DEVBUF);
6173
6174 idx = i / 2;
6175 if (i % 2)
6176 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6177 | ((val & 0x00ff) << 8);
6178 else
6179 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6180 | (val & 0x00ff);
6181 changed = 1;
6182 }
6183 if (changed) {
6184 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6185 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6186 }
6187 bwn_mac_enable(mac);
6188}
6189
6190static void
6191bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6192{
6193
6194 if (!rf->padmix)
6195 return;
6196 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6197 rf->att = 4;
6198}
6199
6200static void
6201bwn_lo_g_adjust(struct bwn_mac *mac)
6202{
6203 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6204 struct bwn_lo_calib *cal;
6205 struct bwn_rfatt rf;
6206
6207 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6208 bwn_lo_fixup_rfatt(&rf);
6209
6210 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6211 if (!cal)
6212 return;
6213 bwn_lo_write(mac, &cal->ctl);
6214}
6215
6216static void
6217bwn_lo_g_init(struct bwn_mac *mac)
6218{
6219
6220 if (!bwn_has_hwpctl(mac))
6221 return;
6222
6223 bwn_lo_get_powervector(mac);
6224 bwn_phy_g_dc_lookup_init(mac, 1);
6225}
6226
6227void
6228bwn_mac_suspend(struct bwn_mac *mac)
6229{
6230 struct bwn_softc *sc = mac->mac_sc;
6231 int i;
6232 uint32_t tmp;
6233
6234 KASSERT(mac->mac_suspended >= 0,

--- 43 unchanged lines hidden (view full) ---

6278 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6279 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6280 BWN_READ_4(mac, BWN_MACCTL);
6281 BWN_READ_4(mac, BWN_INTR_REASON);
6282 bwn_psctl(mac, 0);
6283 }
6284}
6285
3532void
3533bwn_mac_suspend(struct bwn_mac *mac)
3534{
3535 struct bwn_softc *sc = mac->mac_sc;
3536 int i;
3537 uint32_t tmp;
3538
3539 KASSERT(mac->mac_suspended >= 0,

--- 43 unchanged lines hidden (view full) ---

3583 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
3584 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
3585 BWN_READ_4(mac, BWN_MACCTL);
3586 BWN_READ_4(mac, BWN_INTR_REASON);
3587 bwn_psctl(mac, 0);
3588 }
3589}
3590
6286static void
3591void
6287bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6288{
6289 struct bwn_softc *sc = mac->mac_sc;
6290 int i;
6291 uint16_t ucstat;
6292
6293 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6294 ("%s:%d: fail", __func__, __LINE__));

--- 12 unchanged lines hidden (view full) ---

6307 BWN_SHARED_UCODESTAT);
6308 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6309 break;
6310 DELAY(10);
6311 }
6312 }
6313}
6314
3592bwn_psctl(struct bwn_mac *mac, uint32_t flags)
3593{
3594 struct bwn_softc *sc = mac->mac_sc;
3595 int i;
3596 uint16_t ucstat;
3597
3598 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
3599 ("%s:%d: fail", __func__, __LINE__));

--- 12 unchanged lines hidden (view full) ---

3612 BWN_SHARED_UCODESTAT);
3613 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
3614 break;
3615 DELAY(10);
3616 }
3617 }
3618}
3619
6315static int16_t
6316bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6317{
6318
6319 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6320 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6321}
6322
6323static void
6324bwn_nrssi_threshold(struct bwn_mac *mac)
6325{
6326 struct bwn_phy *phy = &mac->mac_phy;
6327 struct bwn_phy_g *pg = &phy->phy_g;
6328 struct bwn_softc *sc = mac->mac_sc;
6329 int32_t a, b;
6330 int16_t tmp16;
6331 uint16_t tmpu16;
6332
6333 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6334
6335 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6336 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6337 a = 0x13;
6338 b = 0x12;
6339 } else {
6340 a = 0xe;
6341 b = 0x11;
6342 }
6343
6344 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6345 a += (pg->pg_nrssi[0] << 6);
6346 a += (a < 32) ? 31 : 32;
6347 a = a >> 6;
6348 a = MIN(MAX(a, -31), 31);
6349
6350 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6351 b += (pg->pg_nrssi[0] << 6);
6352 if (b < 32)
6353 b += 31;
6354 else
6355 b += 32;
6356 b = b >> 6;
6357 b = MIN(MAX(b, -31), 31);
6358
6359 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6360 tmpu16 |= ((uint32_t)b & 0x0000003f);
6361 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6362 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6363 return;
6364 }
6365
6366 tmp16 = bwn_nrssi_read(mac, 0x20);
6367 if (tmp16 >= 0x20)
6368 tmp16 -= 0x40;
6369 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6370}
6371
6372static void
6373bwn_nrssi_slope_11g(struct bwn_mac *mac)
6374{
6375#define SAVE_RF_MAX 3
6376#define SAVE_PHY_COMM_MAX 4
6377#define SAVE_PHY3_MAX 8
6378 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6379 { 0x7a, 0x52, 0x43 };
6380 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6381 { 0x15, 0x5a, 0x59, 0x58 };
6382 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6383 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6384 0x0801, 0x0060, 0x0014, 0x0478
6385 };
6386 struct bwn_phy *phy = &mac->mac_phy;
6387 struct bwn_phy_g *pg = &phy->phy_g;
6388 int32_t i, tmp32, phy3_idx = 0;
6389 uint16_t delta, tmp;
6390 uint16_t save_rf[SAVE_RF_MAX];
6391 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6392 uint16_t save_phy3[SAVE_PHY3_MAX];
6393 uint16_t ant_div, phy0, chan_ex;
6394 int16_t nrssi0, nrssi1;
6395
6396 KASSERT(phy->type == BWN_PHYTYPE_G,
6397 ("%s:%d: fail", __func__, __LINE__));
6398
6399 if (phy->rf_rev >= 9)
6400 return;
6401 if (phy->rf_rev == 8)
6402 bwn_nrssi_offset(mac);
6403
6404 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6405 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6406
6407 /*
6408 * Save RF/PHY registers for later restoration
6409 */
6410 ant_div = BWN_READ_2(mac, 0x03e2);
6411 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6412 for (i = 0; i < SAVE_RF_MAX; ++i)
6413 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6414 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6415 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6416
6417 phy0 = BWN_READ_2(mac, BWN_PHY0);
6418 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6419 if (phy->rev >= 3) {
6420 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6421 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6422 BWN_PHY_WRITE(mac, 0x002e, 0);
6423 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6424 switch (phy->rev) {
6425 case 4:
6426 case 6:
6427 case 7:
6428 BWN_PHY_SET(mac, 0x0478, 0x0100);
6429 BWN_PHY_SET(mac, 0x0801, 0x0040);
6430 break;
6431 case 3:
6432 case 5:
6433 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6434 break;
6435 }
6436 BWN_PHY_SET(mac, 0x0060, 0x0040);
6437 BWN_PHY_SET(mac, 0x0014, 0x0200);
6438 }
6439 /*
6440 * Calculate nrssi0
6441 */
6442 BWN_RF_SET(mac, 0x007a, 0x0070);
6443 bwn_set_all_gains(mac, 0, 8, 0);
6444 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6445 if (phy->rev >= 2) {
6446 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6447 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6448 }
6449 BWN_RF_SET(mac, 0x007a, 0x0080);
6450 DELAY(20);
6451
6452 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6453 if (nrssi0 >= 0x0020)
6454 nrssi0 -= 0x0040;
6455
6456 /*
6457 * Calculate nrssi1
6458 */
6459 BWN_RF_MASK(mac, 0x007a, 0x007f);
6460 if (phy->rev >= 2)
6461 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6462
6463 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6464 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6465 BWN_RF_SET(mac, 0x007a, 0x000f);
6466 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6467 if (phy->rev >= 2) {
6468 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6469 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6470 }
6471
6472 bwn_set_all_gains(mac, 3, 0, 1);
6473 if (phy->rf_rev == 8) {
6474 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6475 } else {
6476 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6477 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6478 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6479 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6480 }
6481 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6482 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6483 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6484 DELAY(20);
6485 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6486
6487 /*
6488 * Install calculated narrow RSSI values
6489 */
6490 if (nrssi1 >= 0x0020)
6491 nrssi1 -= 0x0040;
6492 if (nrssi0 == nrssi1)
6493 pg->pg_nrssi_slope = 0x00010000;
6494 else
6495 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6496 if (nrssi0 >= -4) {
6497 pg->pg_nrssi[0] = nrssi1;
6498 pg->pg_nrssi[1] = nrssi0;
6499 }
6500
6501 /*
6502 * Restore saved RF/PHY registers
6503 */
6504 if (phy->rev >= 3) {
6505 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6506 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6507 save_phy3[phy3_idx]);
6508 }
6509 }
6510 if (phy->rev >= 2) {
6511 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6512 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6513 }
6514
6515 for (i = 0; i < SAVE_RF_MAX; ++i)
6516 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6517
6518 BWN_WRITE_2(mac, 0x03e2, ant_div);
6519 BWN_WRITE_2(mac, 0x03e6, phy0);
6520 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6521
6522 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6523 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6524
6525 bwn_spu_workaround(mac, phy->chan);
6526 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6527 bwn_set_original_gains(mac);
6528 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6529 if (phy->rev >= 3) {
6530 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6531 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6532 save_phy3[phy3_idx]);
6533 }
6534 }
6535
6536 delta = 0x1f - pg->pg_nrssi[0];
6537 for (i = 0; i < 64; i++) {
6538 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6539 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6540 pg->pg_nrssi_lt[i] = tmp32;
6541 }
6542
6543 bwn_nrssi_threshold(mac);
6544#undef SAVE_RF_MAX
6545#undef SAVE_PHY_COMM_MAX
6546#undef SAVE_PHY3_MAX
6547}
6548
6549static void
6550bwn_nrssi_offset(struct bwn_mac *mac)
6551{
6552#define SAVE_RF_MAX 2
6553#define SAVE_PHY_COMM_MAX 10
6554#define SAVE_PHY6_MAX 8
6555 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6556 { 0x7a, 0x43 };
6557 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6558 0x0001, 0x0811, 0x0812, 0x0814,
6559 0x0815, 0x005a, 0x0059, 0x0058,
6560 0x000a, 0x0003
6561 };
6562 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6563 0x002e, 0x002f, 0x080f, 0x0810,
6564 0x0801, 0x0060, 0x0014, 0x0478
6565 };
6566 struct bwn_phy *phy = &mac->mac_phy;
6567 int i, phy6_idx = 0;
6568 uint16_t save_rf[SAVE_RF_MAX];
6569 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6570 uint16_t save_phy6[SAVE_PHY6_MAX];
6571 int16_t nrssi;
6572 uint16_t saved = 0xffff;
6573
6574 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6575 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6576 for (i = 0; i < SAVE_RF_MAX; ++i)
6577 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6578
6579 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6580 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6581 BWN_PHY_SET(mac, 0x0811, 0x000c);
6582 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6583 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6584 if (phy->rev >= 6) {
6585 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6586 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6587
6588 BWN_PHY_WRITE(mac, 0x002e, 0);
6589 BWN_PHY_WRITE(mac, 0x002f, 0);
6590 BWN_PHY_WRITE(mac, 0x080f, 0);
6591 BWN_PHY_WRITE(mac, 0x0810, 0);
6592 BWN_PHY_SET(mac, 0x0478, 0x0100);
6593 BWN_PHY_SET(mac, 0x0801, 0x0040);
6594 BWN_PHY_SET(mac, 0x0060, 0x0040);
6595 BWN_PHY_SET(mac, 0x0014, 0x0200);
6596 }
6597 BWN_RF_SET(mac, 0x007a, 0x0070);
6598 BWN_RF_SET(mac, 0x007a, 0x0080);
6599 DELAY(30);
6600
6601 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6602 if (nrssi >= 0x20)
6603 nrssi -= 0x40;
6604 if (nrssi == 31) {
6605 for (i = 7; i >= 4; i--) {
6606 BWN_RF_WRITE(mac, 0x007b, i);
6607 DELAY(20);
6608 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6609 0x003f);
6610 if (nrssi >= 0x20)
6611 nrssi -= 0x40;
6612 if (nrssi < 31 && saved == 0xffff)
6613 saved = i;
6614 }
6615 if (saved == 0xffff)
6616 saved = 4;
6617 } else {
6618 BWN_RF_MASK(mac, 0x007a, 0x007f);
6619 if (phy->rev != 1) {
6620 BWN_PHY_SET(mac, 0x0814, 0x0001);
6621 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6622 }
6623 BWN_PHY_SET(mac, 0x0811, 0x000c);
6624 BWN_PHY_SET(mac, 0x0812, 0x000c);
6625 BWN_PHY_SET(mac, 0x0811, 0x0030);
6626 BWN_PHY_SET(mac, 0x0812, 0x0030);
6627 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6628 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6629 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6630 if (phy->rev == 0)
6631 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6632 else
6633 BWN_PHY_SET(mac, 0x000a, 0x2000);
6634 if (phy->rev != 1) {
6635 BWN_PHY_SET(mac, 0x0814, 0x0004);
6636 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6637 }
6638 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6639 BWN_RF_SET(mac, 0x007a, 0x000f);
6640 bwn_set_all_gains(mac, 3, 0, 1);
6641 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6642 DELAY(30);
6643 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6644 if (nrssi >= 0x20)
6645 nrssi -= 0x40;
6646 if (nrssi == -32) {
6647 for (i = 0; i < 4; i++) {
6648 BWN_RF_WRITE(mac, 0x007b, i);
6649 DELAY(20);
6650 nrssi = (int16_t)((BWN_PHY_READ(mac,
6651 0x047f) >> 8) & 0x003f);
6652 if (nrssi >= 0x20)
6653 nrssi -= 0x40;
6654 if (nrssi > -31 && saved == 0xffff)
6655 saved = i;
6656 }
6657 if (saved == 0xffff)
6658 saved = 3;
6659 } else
6660 saved = 0;
6661 }
6662 BWN_RF_WRITE(mac, 0x007b, saved);
6663
6664 /*
6665 * Restore saved RF/PHY registers
6666 */
6667 if (phy->rev >= 6) {
6668 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6669 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6670 save_phy6[phy6_idx]);
6671 }
6672 }
6673 if (phy->rev != 1) {
6674 for (i = 3; i < 5; i++)
6675 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6676 save_phy_comm[i]);
6677 }
6678 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6679 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6680
6681 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6682 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6683
6684 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6685 BWN_PHY_SET(mac, 0x0429, 0x8000);
6686 bwn_set_original_gains(mac);
6687 if (phy->rev >= 6) {
6688 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6689 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6690 save_phy6[phy6_idx]);
6691 }
6692 }
6693
6694 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
6695 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
6696 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
6697}
6698
6699static void
6700bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
6701 int16_t third)
6702{
6703 struct bwn_phy *phy = &mac->mac_phy;
6704 uint16_t i;
6705 uint16_t start = 0x08, end = 0x18;
6706 uint16_t tmp;
6707 uint16_t table;
6708
6709 if (phy->rev <= 1) {
6710 start = 0x10;
6711 end = 0x20;
6712 }
6713
6714 table = BWN_OFDMTAB_GAINX;
6715 if (phy->rev <= 1)
6716 table = BWN_OFDMTAB_GAINX_R1;
6717 for (i = 0; i < 4; i++)
6718 bwn_ofdmtab_write_2(mac, table, i, first);
6719
6720 for (i = start; i < end; i++)
6721 bwn_ofdmtab_write_2(mac, table, i, second);
6722
6723 if (third != -1) {
6724 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
6725 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
6726 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
6727 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
6728 }
6729 bwn_dummy_transmission(mac, 0, 1);
6730}
6731
6732static void
6733bwn_set_original_gains(struct bwn_mac *mac)
6734{
6735 struct bwn_phy *phy = &mac->mac_phy;
6736 uint16_t i, tmp;
6737 uint16_t table;
6738 uint16_t start = 0x0008, end = 0x0018;
6739
6740 if (phy->rev <= 1) {
6741 start = 0x0010;
6742 end = 0x0020;
6743 }
6744
6745 table = BWN_OFDMTAB_GAINX;
6746 if (phy->rev <= 1)
6747 table = BWN_OFDMTAB_GAINX_R1;
6748 for (i = 0; i < 4; i++) {
6749 tmp = (i & 0xfffc);
6750 tmp |= (i & 0x0001) << 1;
6751 tmp |= (i & 0x0002) >> 1;
6752
6753 bwn_ofdmtab_write_2(mac, table, i, tmp);
6754 }
6755
6756 for (i = start; i < end; i++)
6757 bwn_ofdmtab_write_2(mac, table, i, i - start);
6758
6759 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
6760 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
6761 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
6762 bwn_dummy_transmission(mac, 0, 1);
6763}
6764
6765static void
6766bwn_phy_hwpctl_init(struct bwn_mac *mac)
6767{
6768 struct bwn_phy *phy = &mac->mac_phy;
6769 struct bwn_phy_g *pg = &phy->phy_g;
6770 struct bwn_rfatt old_rfatt, rfatt;
6771 struct bwn_bbatt old_bbatt, bbatt;
6772 struct bwn_softc *sc = mac->mac_sc;
6773 uint8_t old_txctl = 0;
6774
6775 KASSERT(phy->type == BWN_PHYTYPE_G,
6776 ("%s:%d: fail", __func__, __LINE__));
6777
6778 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
6779 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
6780 return;
6781
6782 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
6783
6784 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
6785
6786 if (!phy->gmode)
6787 return;
6788 bwn_hwpctl_early_init(mac);
6789 if (pg->pg_curtssi == 0) {
6790 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
6791 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
6792 } else {
6793 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
6794 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
6795 old_txctl = pg->pg_txctl;
6796
6797 bbatt.att = 11;
6798 if (phy->rf_rev == 8) {
6799 rfatt.att = 15;
6800 rfatt.padmix = 1;
6801 } else {
6802 rfatt.att = 9;
6803 rfatt.padmix = 0;
6804 }
6805 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
6806 }
6807 bwn_dummy_transmission(mac, 0, 1);
6808 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
6809 if (phy->rf_ver == 0x2050 && phy->analog == 0)
6810 BWN_RF_MASK(mac, 0x0076, 0xff7b);
6811 else
6812 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
6813 &old_rfatt, old_txctl);
6814 }
6815 bwn_hwpctl_init_gphy(mac);
6816
6817 /* clear TSSI */
6818 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
6819 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
6820 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
6821 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
6822}
6823
6824static void
6825bwn_hwpctl_early_init(struct bwn_mac *mac)
6826{
6827 struct bwn_phy *phy = &mac->mac_phy;
6828
6829 if (!bwn_has_hwpctl(mac)) {
6830 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
6831 return;
6832 }
6833
6834 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
6835 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
6836 BWN_PHY_SET(mac, 0x047c, 0x0002);
6837 BWN_PHY_SET(mac, 0x047a, 0xf000);
6838 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
6839 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
6840 BWN_PHY_SET(mac, 0x005d, 0x8000);
6841 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
6842 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
6843 BWN_PHY_SET(mac, 0x0036, 0x0400);
6844 } else {
6845 BWN_PHY_SET(mac, 0x0036, 0x0200);
6846 BWN_PHY_SET(mac, 0x0036, 0x0400);
6847 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
6848 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
6849 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
6850 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
6851 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
6852 }
6853}
6854
6855static void
6856bwn_hwpctl_init_gphy(struct bwn_mac *mac)
6857{
6858 struct bwn_phy *phy = &mac->mac_phy;
6859 struct bwn_phy_g *pg = &phy->phy_g;
6860 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6861 int i;
6862 uint16_t nr_written = 0, tmp, value;
6863 uint8_t rf, bb;
6864
6865 if (!bwn_has_hwpctl(mac)) {
6866 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
6867 return;
6868 }
6869
6870 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
6871 (pg->pg_idletssi - pg->pg_curtssi));
6872 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
6873 (pg->pg_idletssi - pg->pg_curtssi));
6874
6875 for (i = 0; i < 32; i++)
6876 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
6877 for (i = 32; i < 64; i++)
6878 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
6879 for (i = 0; i < 64; i += 2) {
6880 value = (uint16_t) pg->pg_tssi2dbm[i];
6881 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
6882 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
6883 }
6884
6885 for (rf = 0; rf < lo->rfatt.len; rf++) {
6886 for (bb = 0; bb < lo->bbatt.len; bb++) {
6887 if (nr_written >= 0x40)
6888 return;
6889 tmp = lo->bbatt.array[bb].att;
6890 tmp <<= 8;
6891 if (phy->rf_rev == 8)
6892 tmp |= 0x50;
6893 else
6894 tmp |= 0x40;
6895 tmp |= lo->rfatt.array[rf].att;
6896 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
6897 nr_written++;
6898 }
6899 }
6900
6901 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
6902 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
6903
6904 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
6905 BWN_PHY_SET(mac, 0x0478, 0x0800);
6906 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
6907 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6908
6909 bwn_phy_g_dc_lookup_init(mac, 1);
6910 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
6911}
6912
6913static void
6914bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
6915{
6916 struct bwn_softc *sc = mac->mac_sc;
6917
6918 if (spu != 0)
6919 bwn_spu_workaround(mac, channel);
6920
6921 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
6922
6923 if (channel == 14) {
6924 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
6925 bwn_hf_write(mac,
6926 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
6927 else
6928 bwn_hf_write(mac,
6929 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
6930 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6931 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
6932 return;
6933 }
6934
6935 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6936 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
6937}
6938
6939static uint16_t
6940bwn_phy_g_chan2freq(uint8_t channel)
6941{
6942 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
6943
6944 KASSERT(channel >= 1 && channel <= 14,
6945 ("%s:%d: fail", __func__, __LINE__));
6946
6947 return (bwn_phy_g_rf_channels[channel - 1]);
6948}
6949
6950static void
6951bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6952 const struct bwn_rfatt *rfatt, uint8_t txctl)
6953{
6954 struct bwn_phy *phy = &mac->mac_phy;
6955 struct bwn_phy_g *pg = &phy->phy_g;
6956 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6957 uint16_t bb, rf;
6958 uint16_t tx_bias, tx_magn;
6959
6960 bb = bbatt->att;
6961 rf = rfatt->att;
6962 tx_bias = lo->tx_bias;
6963 tx_magn = lo->tx_magn;
6964 if (tx_bias == 0xff)
6965 tx_bias = 0;
6966
6967 pg->pg_txctl = txctl;
6968 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
6969 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
6970 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
6971 bwn_phy_g_set_bbatt(mac, bb);
6972 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
6973 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
6974 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
6975 else {
6976 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
6977 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
6978 }
6979 if (BWN_HAS_TXMAG(phy))
6980 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
6981 else
6982 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
6983 bwn_lo_g_adjust(mac);
6984}
6985
6986static void
6987bwn_phy_g_set_bbatt(struct bwn_mac *mac,
6988 uint16_t bbatt)
6989{
6990 struct bwn_phy *phy = &mac->mac_phy;
6991
6992 if (phy->analog == 0) {
6993 BWN_WRITE_2(mac, BWN_PHY0,
6994 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
6995 return;
6996 }
6997 if (phy->analog > 1) {
6998 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
6999 return;
7000 }
7001 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7002}
7003
7004static uint16_t
7005bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7006{
7007 struct bwn_phy *phy = &mac->mac_phy;
7008 struct bwn_phy_g *pg = &phy->phy_g;
7009 struct bwn_softc *sc = mac->mac_sc;
7010 int max_lb_gain;
7011 uint16_t extlna;
7012 uint16_t i;
7013
7014 if (phy->gmode == 0)
7015 return (0);
7016
7017 if (BWN_HAS_LOOPBACK(phy)) {
7018 max_lb_gain = pg->pg_max_lb_gain;
7019 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7020 if (max_lb_gain >= 0x46) {
7021 extlna = 0x3000;
7022 max_lb_gain -= 0x46;
7023 } else if (max_lb_gain >= 0x3a) {
7024 extlna = 0x1000;
7025 max_lb_gain -= 0x3a;
7026 } else if (max_lb_gain >= 0x2e) {
7027 extlna = 0x2000;
7028 max_lb_gain -= 0x2e;
7029 } else {
7030 extlna = 0;
7031 max_lb_gain -= 0x10;
7032 }
7033
7034 for (i = 0; i < 16; i++) {
7035 max_lb_gain -= (i * 6);
7036 if (max_lb_gain < 6)
7037 break;
7038 }
7039
7040 if ((phy->rev < 7) ||
7041 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7042 if (reg == BWN_PHY_RFOVER) {
7043 return (0x1b3);
7044 } else if (reg == BWN_PHY_RFOVERVAL) {
7045 extlna |= (i << 8);
7046 switch (lpd) {
7047 case BWN_LPD(0, 1, 1):
7048 return (0x0f92);
7049 case BWN_LPD(0, 0, 1):
7050 case BWN_LPD(1, 0, 1):
7051 return (0x0092 | extlna);
7052 case BWN_LPD(1, 0, 0):
7053 return (0x0093 | extlna);
7054 }
7055 KASSERT(0 == 1,
7056 ("%s:%d: fail", __func__, __LINE__));
7057 }
7058 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7059 } else {
7060 if (reg == BWN_PHY_RFOVER)
7061 return (0x9b3);
7062 if (reg == BWN_PHY_RFOVERVAL) {
7063 if (extlna)
7064 extlna |= 0x8000;
7065 extlna |= (i << 8);
7066 switch (lpd) {
7067 case BWN_LPD(0, 1, 1):
7068 return (0x8f92);
7069 case BWN_LPD(0, 0, 1):
7070 return (0x8092 | extlna);
7071 case BWN_LPD(1, 0, 1):
7072 return (0x2092 | extlna);
7073 case BWN_LPD(1, 0, 0):
7074 return (0x2093 | extlna);
7075 }
7076 KASSERT(0 == 1,
7077 ("%s:%d: fail", __func__, __LINE__));
7078 }
7079 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7080 }
7081 return (0);
7082 }
7083
7084 if ((phy->rev < 7) ||
7085 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7086 if (reg == BWN_PHY_RFOVER) {
7087 return (0x1b3);
7088 } else if (reg == BWN_PHY_RFOVERVAL) {
7089 switch (lpd) {
7090 case BWN_LPD(0, 1, 1):
7091 return (0x0fb2);
7092 case BWN_LPD(0, 0, 1):
7093 return (0x00b2);
7094 case BWN_LPD(1, 0, 1):
7095 return (0x30b2);
7096 case BWN_LPD(1, 0, 0):
7097 return (0x30b3);
7098 }
7099 KASSERT(0 == 1,
7100 ("%s:%d: fail", __func__, __LINE__));
7101 }
7102 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7103 } else {
7104 if (reg == BWN_PHY_RFOVER) {
7105 return (0x9b3);
7106 } else if (reg == BWN_PHY_RFOVERVAL) {
7107 switch (lpd) {
7108 case BWN_LPD(0, 1, 1):
7109 return (0x8fb2);
7110 case BWN_LPD(0, 0, 1):
7111 return (0x80b2);
7112 case BWN_LPD(1, 0, 1):
7113 return (0x20b2);
7114 case BWN_LPD(1, 0, 0):
7115 return (0x20b3);
7116 }
7117 KASSERT(0 == 1,
7118 ("%s:%d: fail", __func__, __LINE__));
7119 }
7120 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7121 }
7122 return (0);
7123}
7124
7125static void
7126bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7127{
7128
7129 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7130 return;
7131 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7132 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7133 DELAY(1000);
7134 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7135}
7136
7137static int
7138bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7139{
7140 struct bwn_softc *sc = mac->mac_sc;
7141 struct bwn_fw *fw = &mac->mac_fw;
7142 const uint8_t rev = siba_get_revid(sc->sc_dev);
7143 const char *filename;
7144 uint32_t high;

--- 380 unchanged lines hidden (view full) ---

7525 return (0);
7526fail:
7527 device_printf(sc->sc_dev, "initvals: invalid format\n");
7528 return (EPROTO);
7529#undef GET_NEXTIV16
7530#undef GET_NEXTIV32
7531}
7532
3620static int
3621bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
3622{
3623 struct bwn_softc *sc = mac->mac_sc;
3624 struct bwn_fw *fw = &mac->mac_fw;
3625 const uint8_t rev = siba_get_revid(sc->sc_dev);
3626 const char *filename;
3627 uint32_t high;

--- 380 unchanged lines hidden (view full) ---

4008 return (0);
4009fail:
4010 device_printf(sc->sc_dev, "initvals: invalid format\n");
4011 return (EPROTO);
4012#undef GET_NEXTIV16
4013#undef GET_NEXTIV32
4014}
4015
7533static int
4016int
7534bwn_switch_channel(struct bwn_mac *mac, int chan)
7535{
7536 struct bwn_phy *phy = &(mac->mac_phy);
7537 struct bwn_softc *sc = mac->mac_sc;
7538 struct ieee80211com *ic = &sc->sc_ic;
7539 uint16_t channelcookie, savedcookie;
7540 int error;
7541

--- 2027 unchanged lines hidden (view full) ---

9569 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9570 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9571 dr->dr_curslot = slot;
9572 dr->dr_usedslot++;
9573
9574 return (slot);
9575}
9576
4017bwn_switch_channel(struct bwn_mac *mac, int chan)
4018{
4019 struct bwn_phy *phy = &(mac->mac_phy);
4020 struct bwn_softc *sc = mac->mac_sc;
4021 struct ieee80211com *ic = &sc->sc_ic;
4022 uint16_t channelcookie, savedcookie;
4023 int error;
4024

--- 2027 unchanged lines hidden (view full) ---

6052 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
6053 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
6054 dr->dr_curslot = slot;
6055 dr->dr_usedslot++;
6056
6057 return (slot);
6058}
6059
9577static int
9578bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9579{
9580 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9581 unsigned int a, b, c, d;
9582 unsigned int avg;
9583 uint32_t tmp;
9584
9585 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9586 a = tmp & 0xff;
9587 b = (tmp >> 8) & 0xff;
9588 c = (tmp >> 16) & 0xff;
9589 d = (tmp >> 24) & 0xff;
9590 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9591 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9592 return (ENOENT);
9593 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9594 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9595 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9596
9597 if (ofdm) {
9598 a = (a + 32) & 0x3f;
9599 b = (b + 32) & 0x3f;
9600 c = (c + 32) & 0x3f;
9601 d = (d + 32) & 0x3f;
9602 }
9603
9604 avg = (a + b + c + d + 2) / 4;
9605 if (ofdm) {
9606 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9607 & BWN_HF_4DB_CCK_POWERBOOST)
9608 avg = (avg >= 13) ? (avg - 13) : 0;
9609 }
9610 return (avg);
9611}
9612
9613static void
9614bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9615{
9616 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9617 int rfatt = *rfattp;
9618 int bbatt = *bbattp;
9619
9620 while (1) {
9621 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9622 break;
9623 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9624 break;
9625 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9626 break;
9627 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9628 break;
9629 if (bbatt > lo->bbatt.max) {
9630 bbatt -= 4;
9631 rfatt += 1;
9632 continue;
9633 }
9634 if (bbatt < lo->bbatt.min) {
9635 bbatt += 4;
9636 rfatt -= 1;
9637 continue;
9638 }
9639 if (rfatt > lo->rfatt.max) {
9640 rfatt -= 1;
9641 bbatt += 4;
9642 continue;
9643 }
9644 if (rfatt < lo->rfatt.min) {
9645 rfatt += 1;
9646 bbatt -= 4;
9647 continue;
9648 }
9649 break;
9650 }
9651
9652 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9653 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9654}
9655
9656static void
9657bwn_phy_lock(struct bwn_mac *mac)
9658{
9659 struct bwn_softc *sc = mac->mac_sc;
9660 struct ieee80211com *ic = &sc->sc_ic;
9661
9662 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9663 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9664
9665 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9666 bwn_psctl(mac, BWN_PS_AWAKE);
9667}
9668
9669static void
9670bwn_phy_unlock(struct bwn_mac *mac)
9671{
9672 struct bwn_softc *sc = mac->mac_sc;
9673 struct ieee80211com *ic = &sc->sc_ic;
9674
9675 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9676 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9677
9678 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9679 bwn_psctl(mac, 0);
9680}
9681
9682static void
9683bwn_rf_lock(struct bwn_mac *mac)
9684{
9685
9686 BWN_WRITE_4(mac, BWN_MACCTL,
9687 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
9688 BWN_READ_4(mac, BWN_MACCTL);
9689 DELAY(10);
9690}
9691
9692static void
9693bwn_rf_unlock(struct bwn_mac *mac)
9694{
9695
9696 BWN_READ_2(mac, BWN_PHYVER);
9697 BWN_WRITE_4(mac, BWN_MACCTL,
9698 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
9699}
9700
9701static struct bwn_pio_txqueue *
9702bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
9703 struct bwn_pio_txpkt **pack)
9704{
9705 struct bwn_pio *pio = &mac->mac_method.pio;
9706 struct bwn_pio_txqueue *tq = NULL;
9707 unsigned int index;
9708

--- 738 unchanged lines hidden ---
6060static struct bwn_pio_txqueue *
6061bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
6062 struct bwn_pio_txpkt **pack)
6063{
6064 struct bwn_pio *pio = &mac->mac_method.pio;
6065 struct bwn_pio_txqueue *tq = NULL;
6066 unsigned int index;
6067

--- 738 unchanged lines hidden ---