bwi.c revision 1.114
1/*	$OpenBSD: bwi.c,v 1.114 2015/01/10 10:38:12 stsp Exp $	*/
2
3/*
4 * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
5 *
6 * This code is derived from software contributed to The DragonFly Project
7 * by Sepherosa Ziehau <sepherosa@gmail.com>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 * 3. Neither the name of The DragonFly Project nor the names of its
20 *    contributors may be used to endorse or promote products derived
21 *    from this software without specific, prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $
37 */
38
39#include "bpfilter.h"
40
41#include <sys/param.h>
42#include <sys/types.h>
43
44#include <sys/device.h>
45#include <sys/kernel.h>
46#include <sys/malloc.h>
47#include <sys/mbuf.h>
48#include <sys/socket.h>
49#include <sys/sockio.h>
50#include <sys/systm.h>
51#include <sys/endian.h>
52
53#include <machine/bus.h>
54#include <machine/intr.h>
55
56#include <net/if.h>
57#include <net/if_dl.h>
58#include <net/if_media.h>
59
60#if NBPFILTER > 0
61#include <net/bpf.h>
62#endif
63
64#include <netinet/in.h>
65#include <netinet/if_ether.h>
66
67#include <net80211/ieee80211_var.h>
68#include <net80211/ieee80211_amrr.h>
69#include <net80211/ieee80211_radiotap.h>
70
71#include <dev/ic/bwireg.h>
72#include <dev/ic/bwivar.h>
73
74#include <uvm/uvm_extern.h>
75
76#ifdef BWI_DEBUG
77int bwi_debug = 1;
78#define DPRINTF(l, x...)	do { if ((l) <= bwi_debug) printf(x); } while (0)
79#else
80#define DPRINTF(l, x...)
81#endif
82
83/* XXX temporary porting goop */
84#include <dev/pci/pcireg.h>
85#include <dev/pci/pcidevs.h>
86
87/* XXX does not belong here */
88#define IEEE80211_OFDM_PLCP_RATE_MASK	0x0000000f
89#define IEEE80211_OFDM_PLCP_LEN_MASK	0x0001ffe0
90
91/*
92 * Contention window (slots).
93 */
94#define IEEE80211_CW_MAX	1023	/* aCWmax */
95#define IEEE80211_CW_MIN_0	31	/* DS/CCK aCWmin, ERP aCWmin(0) */
96#define IEEE80211_CW_MIN_1	15	/* OFDM aCWmin, ERP aCWmin(1) */
97
98#define __unused __attribute__((__unused__))
99
100extern int ticks;
101
102/* XXX end porting goop */
103
104/* MAC */
105struct bwi_retry_lim {
106	uint16_t	shretry;
107	uint16_t	shretry_fb;
108	uint16_t	lgretry;
109	uint16_t	lgretry_fb;
110};
111
112struct bwi_clock_freq {
113	uint		clkfreq_min;
114	uint		clkfreq_max;
115};
116
117/* XXX does not belong here */
118struct ieee80211_ds_plcp_hdr {
119	uint8_t		i_signal;
120	uint8_t		i_service;
121	uint16_t	i_length;
122	uint16_t	i_crc;
123} __packed;
124
125enum bwi_modtype {
126	IEEE80211_MODTYPE_DS	= 0,	/* DS/CCK modulation */
127	IEEE80211_MODTYPE_PBCC	= 1,	/* PBCC modulation */
128	IEEE80211_MODTYPE_OFDM	= 2	/* OFDM modulation */
129};
130#define IEEE80211_MODTYPE_CCK   IEEE80211_MODTYPE_DS
131
132/* MAC */
133void		 bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
134void		 bwi_hostflags_write(struct bwi_mac *, uint64_t);
135uint64_t	 bwi_hostflags_read(struct bwi_mac *);
136uint16_t	 bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
137uint32_t	 bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
138void		 bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
139		     uint16_t);
140void		 bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
141		     uint32_t);
142int		 bwi_mac_lateattach(struct bwi_mac *);
143int		 bwi_mac_init(struct bwi_mac *);
144void		 bwi_mac_reset(struct bwi_mac *, int);
145void		 bwi_mac_set_tpctl_11bg(struct bwi_mac *,
146		     const struct bwi_tpctl *);
147int		 bwi_mac_test(struct bwi_mac *);
148void		 bwi_mac_setup_tpctl(struct bwi_mac *);
149void		 bwi_mac_dummy_xmit(struct bwi_mac *);
150void		 bwi_mac_init_tpctl_11bg(struct bwi_mac *);
151void		 bwi_mac_detach(struct bwi_mac *);
152int		 bwi_get_firmware(const char *, const uint8_t *, size_t,
153		     size_t *, size_t *);
154int		 bwi_fwimage_is_valid(struct bwi_softc *, uint8_t *,
155		     size_t, char *, uint8_t);
156int		 bwi_mac_fw_alloc(struct bwi_mac *);
157void		 bwi_mac_fw_free(struct bwi_mac *);
158int		 bwi_mac_fw_load(struct bwi_mac *);
159int		 bwi_mac_gpio_init(struct bwi_mac *);
160int		 bwi_mac_gpio_fini(struct bwi_mac *);
161int		 bwi_mac_fw_load_iv(struct bwi_mac *, uint8_t *, size_t);
162int		 bwi_mac_fw_init(struct bwi_mac *);
163void		 bwi_mac_opmode_init(struct bwi_mac *);
164void		 bwi_mac_hostflags_init(struct bwi_mac *);
165void		 bwi_mac_bss_param_init(struct bwi_mac *);
166void		 bwi_mac_set_retry_lim(struct bwi_mac *,
167		     const struct bwi_retry_lim *);
168void		 bwi_mac_set_ackrates(struct bwi_mac *,
169		     const struct ieee80211_rateset *);
170int		 bwi_mac_start(struct bwi_mac *);
171int		 bwi_mac_stop(struct bwi_mac *);
172int		 bwi_mac_config_ps(struct bwi_mac *);
173void		 bwi_mac_reset_hwkeys(struct bwi_mac *);
174void		 bwi_mac_shutdown(struct bwi_mac *);
175int		 bwi_mac_get_property(struct bwi_mac *);
176void		 bwi_mac_updateslot(struct bwi_mac *, int);
177int		 bwi_mac_attach(struct bwi_softc *, int, uint8_t);
178void		 bwi_mac_balance_atten(int *, int *);
179void		 bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
180void		 bwi_mac_calibrate_txpower(struct bwi_mac *,
181		     enum bwi_txpwrcb_type);
182void		 bwi_mac_lock(struct bwi_mac *);
183void		 bwi_mac_unlock(struct bwi_mac *);
184void		 bwi_mac_set_promisc(struct bwi_mac *, int);
185
186/* PHY */
187void		 bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
188uint16_t	 bwi_phy_read(struct bwi_mac *, uint16_t);
189int		 bwi_phy_attach(struct bwi_mac *);
190void		 bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
191int		 bwi_phy_calibrate(struct bwi_mac *);
192void		 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
193void		 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
194void		 bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
195int16_t		 bwi_nrssi_read(struct bwi_mac *, uint16_t);
196void		 bwi_phy_init_11a(struct bwi_mac *);
197void		 bwi_phy_init_11g(struct bwi_mac *);
198void		 bwi_phy_init_11b_rev2(struct bwi_mac *);
199void		 bwi_phy_init_11b_rev4(struct bwi_mac *);
200void		 bwi_phy_init_11b_rev5(struct bwi_mac *);
201void		 bwi_phy_init_11b_rev6(struct bwi_mac *);
202void		 bwi_phy_config_11g(struct bwi_mac *);
203void		 bwi_phy_config_agc(struct bwi_mac *);
204void		 bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
205void		 bwi_phy_clear_state(struct bwi_phy *);
206
207/* RF */
208int16_t		 bwi_nrssi_11g(struct bwi_mac *);
209struct bwi_rf_lo
210		*bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
211int		 bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
212void		 bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
213uint16_t	 bwi_rf_read(struct bwi_mac *, uint16_t);
214int		 bwi_rf_attach(struct bwi_mac *);
215void		 bwi_rf_set_chan(struct bwi_mac *, uint, int);
216void		 bwi_rf_get_gains(struct bwi_mac *);
217void		 bwi_rf_init(struct bwi_mac *);
218void		 bwi_rf_off_11a(struct bwi_mac *);
219void		 bwi_rf_off_11bg(struct bwi_mac *);
220void		 bwi_rf_off_11g_rev5(struct bwi_mac *);
221void		 bwi_rf_workaround(struct bwi_mac *, uint);
222struct bwi_rf_lo
223		*bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
224void		 bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
225void		 bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
226int		 bwi_rf_gain_max_reached(struct bwi_mac *, int);
227uint16_t	 bwi_bitswap4(uint16_t);
228uint16_t	 bwi_phy812_value(struct bwi_mac *, uint16_t);
229void		 bwi_rf_init_bcm2050(struct bwi_mac *);
230uint16_t	 bwi_rf_calibval(struct bwi_mac *);
231int32_t		 _bwi_adjust_devide(int32_t, int32_t);
232int		 bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
233int		 bwi_rf_map_txpower(struct bwi_mac *);
234void		 bwi_rf_lo_update_11g(struct bwi_mac *);
235uint32_t	 bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
236uint16_t	 bwi_rf_get_tp_ctrl2(struct bwi_mac *);
237uint8_t		 _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
238void		 bwi_rf_lo_measure_11g(struct bwi_mac *,
239		     const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
240void		 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
241void		 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
242void		 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
243void		 bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
244void		 bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
245void		 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
246int32_t		 _nrssi_threshold(const struct bwi_rf *, int32_t);
247void		 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
248void		 bwi_rf_clear_tssi(struct bwi_mac *);
249void		 bwi_rf_clear_state(struct bwi_rf *);
250void		 bwi_rf_on_11a(struct bwi_mac *);
251void		 bwi_rf_on_11bg(struct bwi_mac *);
252void		 bwi_rf_set_ant_mode(struct bwi_mac *, int);
253int		 bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
254int		 bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
255int		 bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
256		     const struct bwi_rxbuf_hdr *);
257int		 bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
258		     const struct bwi_rxbuf_hdr *);
259int		 bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
260		     const struct bwi_rxbuf_hdr *);
261uint16_t	 bwi_rf_lo_measure_11b(struct bwi_mac *);
262void		 bwi_rf_lo_update_11b(struct bwi_mac *);
263
264/* INTERFACE */
265uint16_t	 bwi_read_sprom(struct bwi_softc *, uint16_t);
266void		 bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
267		     int, bus_addr_t, int, int);
268void		 bwi_power_on(struct bwi_softc *, int);
269int		 bwi_power_off(struct bwi_softc *, int);
270int		 bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
271		     struct bwi_regwin **);
272int		 bwi_regwin_select(struct bwi_softc *, int);
273void		 bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
274void		 bwi_led_attach(struct bwi_softc *);
275void		 bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
276uint16_t	 bwi_led_onoff(struct bwi_led *, uint16_t, int);
277void		 bwi_led_event(struct bwi_softc *, int);
278void		 bwi_led_blink_start(struct bwi_softc *, int, int);
279void		 bwi_led_blink_next(void *);
280void		 bwi_led_blink_end(void *);
281int		 bwi_bbp_attach(struct bwi_softc *);
282int		 bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
283void		 bwi_get_card_flags(struct bwi_softc *);
284void		 bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
285void		 bwi_get_clock_freq(struct bwi_softc *,
286		     struct bwi_clock_freq *);
287int		 bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
288int		 bwi_set_clock_delay(struct bwi_softc *);
289int		 bwi_ioctl(struct ifnet *, u_long, caddr_t);
290void		 bwi_start(struct ifnet *);
291void		 bwi_watchdog(struct ifnet *);
292void		 bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
293void		 bwi_init_statechg(struct bwi_softc *, int);
294int		 bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
295int		 bwi_media_change(struct ifnet *);
296void		 bwi_iter_func(void *, struct ieee80211_node *);
297void		 bwi_amrr_timeout(void *);
298void		 bwi_newassoc(struct ieee80211com *, struct ieee80211_node *,
299		     int);
300struct ieee80211_node
301		*bwi_node_alloc(struct ieee80211com *ic);
302int		 bwi_dma_alloc(struct bwi_softc *);
303void		 bwi_dma_free(struct bwi_softc *);
304int		 bwi_dma_ring_alloc(struct bwi_softc *,
305		     struct bwi_ring_data *, bus_size_t, uint32_t);
306int		 bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
307		     bus_size_t);
308void		 bwi_dma_txstats_free(struct bwi_softc *);
309int		 bwi_dma_mbuf_create30(struct bwi_softc *);
310int		 bwi_dma_mbuf_create(struct bwi_softc *);
311void		 bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
312void		 bwi_enable_intrs(struct bwi_softc *, uint32_t);
313void		 bwi_disable_intrs(struct bwi_softc *, uint32_t);
314int		 bwi_init_tx_ring32(struct bwi_softc *, int);
315void		 bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
316		     bus_addr_t, int, int);
317int		 bwi_init_rx_ring32(struct bwi_softc *);
318int		 bwi_init_txstats32(struct bwi_softc *);
319void		 bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
320void		 bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
321		     int, bus_addr_t, int);
322int		 bwi_init_tx_ring64(struct bwi_softc *, int);
323int		 bwi_init_rx_ring64(struct bwi_softc *);
324int		 bwi_init_txstats64(struct bwi_softc *);
325void		 bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
326void		 bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
327		     int, bus_addr_t, int);
328int		 bwi_newbuf30(struct bwi_softc *, int, int);
329int		 bwi_newbuf(struct bwi_softc *, int, int);
330void		 bwi_set_addr_filter(struct bwi_softc *, uint16_t,
331		     const uint8_t *);
332int		 bwi_set_chan(struct bwi_softc *, uint8_t);
333void		 bwi_next_scan(void *);
334int		 bwi_rxeof(struct bwi_softc *, int);
335int		 bwi_rxeof32(struct bwi_softc *);
336int		 bwi_rxeof64(struct bwi_softc *);
337void		 bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
338void		 bwi_free_txstats32(struct bwi_softc *);
339void		 bwi_free_rx_ring32(struct bwi_softc *);
340void		 bwi_free_tx_ring32(struct bwi_softc *, int);
341void		 bwi_free_txstats64(struct bwi_softc *);
342void		 bwi_free_rx_ring64(struct bwi_softc *);
343void		 bwi_free_tx_ring64(struct bwi_softc *, int);
344uint8_t		 bwi_plcp2rate(uint32_t, enum ieee80211_phymode);
345void		 bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
346void		 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
347		     uint8_t);
348void		 bwi_plcp_header(void *, int, uint8_t);
349int		 bwi_encap(struct bwi_softc *, int, struct mbuf *,
350		     struct ieee80211_node *);
351void		 bwi_start_tx32(struct bwi_softc *, uint32_t, int);
352void		 bwi_start_tx64(struct bwi_softc *, uint32_t, int);
353void		 bwi_txeof_status32(struct bwi_softc *);
354void		 bwi_txeof_status64(struct bwi_softc *);
355void		 _bwi_txeof(struct bwi_softc *, uint16_t);
356void		 bwi_txeof_status(struct bwi_softc *, int);
357void		 bwi_txeof(struct bwi_softc *);
358int		 bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
359void		 bwi_bbp_power_off(struct bwi_softc *);
360int		 bwi_get_pwron_delay(struct bwi_softc *sc);
361int		 bwi_bus_attach(struct bwi_softc *);
362const char 	*bwi_regwin_name(const struct bwi_regwin *);
363int		 bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
364uint32_t	 bwi_regwin_disable_bits(struct bwi_softc *);
365void		 bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
366		     uint32_t);
367void		 bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
368		     uint32_t);
369void		 bwi_set_bssid(struct bwi_softc *, const uint8_t *);
370void		 bwi_updateslot(struct ieee80211com *);
371void		 bwi_calibrate(void *);
372int		 bwi_calc_rssi(struct bwi_softc *,
373		     const struct bwi_rxbuf_hdr *);
374uint8_t		 bwi_ack_rate(struct ieee80211_node *, uint8_t);
375uint16_t	 bwi_txtime(struct ieee80211com *, struct ieee80211_node *,
376		     uint, uint8_t, uint32_t);
377enum bwi_modtype
378		 bwi_rate2modtype(uint8_t);
379
380
381static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 };
382
383#define SUP_BPHY(num)	{ .rev = num, .init = bwi_phy_init_11b_rev##num }
384
385static const struct {
386	uint8_t	rev;
387	void	(*init)(struct bwi_mac *);
388} bwi_sup_bphy[] = {
389	SUP_BPHY(2),
390	SUP_BPHY(4),
391	SUP_BPHY(5),
392	SUP_BPHY(6)
393};
394
395#undef SUP_BPHY
396
397#define BWI_PHYTBL_WRSSI	0x1000
398#define BWI_PHYTBL_NOISE_SCALE	0x1400
399#define BWI_PHYTBL_NOISE	0x1800
400#define BWI_PHYTBL_ROTOR	0x2000
401#define BWI_PHYTBL_DELAY	0x2400
402#define BWI_PHYTBL_RSSI		0x4000
403#define BWI_PHYTBL_SIGMA_SQ	0x5000
404#define BWI_PHYTBL_WRSSI_REV1	0x5400
405#define BWI_PHYTBL_FREQ		0x5800
406
407static const uint16_t	bwi_phy_freq_11g_rev1[] =
408	{ BWI_PHY_FREQ_11G_REV1 };
409static const uint16_t	bwi_phy_noise_11g_rev1[] =
410	{ BWI_PHY_NOISE_11G_REV1 };
411static const uint16_t	bwi_phy_noise_11g[] =
412	{ BWI_PHY_NOISE_11G };
413static const uint32_t	bwi_phy_rotor_11g_rev1[] =
414	{ BWI_PHY_ROTOR_11G_REV1 };
415static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
416	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
417static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
418	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
419static const uint16_t	bwi_phy_noise_scale_11g[] =
420	{ BWI_PHY_NOISE_SCALE_11G };
421static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
422	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
423static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
424	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
425static const uint32_t	bwi_phy_delay_11g_rev1[] =
426	{ BWI_PHY_DELAY_11G_REV1 };
427
428/* RF */
429#define RF_LO_WRITE(mac, lo)	bwi_rf_lo_write((mac), (lo))
430
431#define BWI_RF_2GHZ_CHAN(chan) \
432	(ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
433
434#define BWI_DEFAULT_IDLE_TSSI	52
435
436struct rf_saveregs {
437	uint16_t	phy_01;
438	uint16_t	phy_03;
439	uint16_t	phy_0a;
440	uint16_t	phy_15;
441	uint16_t	phy_2a;
442	uint16_t	phy_30;
443	uint16_t	phy_35;
444	uint16_t	phy_60;
445	uint16_t	phy_429;
446	uint16_t	phy_802;
447	uint16_t	phy_811;
448	uint16_t	phy_812;
449	uint16_t	phy_814;
450	uint16_t	phy_815;
451
452	uint16_t	rf_43;
453	uint16_t	rf_52;
454	uint16_t	rf_7a;
455};
456
457#define SAVE_RF_REG(mac, regs, n)	(regs)->rf_##n = RF_READ((mac), 0x##n)
458#define RESTORE_RF_REG(mac, regs, n)	RF_WRITE((mac), 0x##n, (regs)->rf_##n)
459
460#define SAVE_PHY_REG(mac, regs, n)	(regs)->phy_##n = PHY_READ((mac), 0x##n)
461#define RESTORE_PHY_REG(mac, regs, n)	PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
462
463static const int8_t	bwi_txpower_map_11b[BWI_TSSI_MAX] =
464	{ BWI_TXPOWER_MAP_11B };
465static const int8_t	bwi_txpower_map_11g[BWI_TSSI_MAX] =
466	{ BWI_TXPOWER_MAP_11G };
467
468/* IF_BWI */
469
470struct bwi_myaddr_bssid {
471	uint8_t		myaddr[IEEE80211_ADDR_LEN];
472	uint8_t		bssid[IEEE80211_ADDR_LEN];
473} __packed;
474
475#define IEEE80211_DS_PLCP_SERVICE_LOCKED	0x04
476#define IEEE80211_DS_PLCL_SERVICE_PBCC		0x08
477#define IEEE80211_DS_PLCP_SERVICE_LENEXT5	0x20
478#define IEEE80211_DS_PLCP_SERVICE_LENEXT6	0x40
479#define IEEE80211_DS_PLCP_SERVICE_LENEXT7	0x80
480
481struct cfdriver bwi_cd = {
482	NULL, "bwi", DV_IFNET
483};
484
485static const struct {
486	uint16_t	did_min;
487	uint16_t	did_max;
488	uint16_t	bbp_id;
489} bwi_bbpid_map[] = {
490	{ 0x4301, 0x4301, 0x4301 },
491	{ 0x4305, 0x4307, 0x4307 },
492	{ 0x4402, 0x4403, 0x4402 },
493	{ 0x4610, 0x4615, 0x4610 },
494	{ 0x4710, 0x4715, 0x4710 },
495	{ 0x4720, 0x4725, 0x4309 }
496};
497
498static const struct {
499	uint16_t	bbp_id;
500	int		nregwin;
501} bwi_regwin_count[] = {
502	{ 0x4301, 5 },
503	{ 0x4306, 6 },
504	{ 0x4307, 5 },
505	{ 0x4310, 8 },
506	{ 0x4401, 3 },
507	{ 0x4402, 3 },
508	{ 0x4610, 9 },
509	{ 0x4704, 9 },
510	{ 0x4710, 9 },
511	{ 0x5365, 7 }
512};
513
514#define CLKSRC(src) 				\
515[BWI_CLKSRC_ ## src] = {			\
516	.freq_min = BWI_CLKSRC_ ##src## _FMIN,	\
517	.freq_max = BWI_CLKSRC_ ##src## _FMAX	\
518}
519
520static const struct {
521	uint	freq_min;
522	uint	freq_max;
523} bwi_clkfreq[BWI_CLKSRC_MAX] = {
524	CLKSRC(LP_OSC),
525	CLKSRC(CS_OSC),
526	CLKSRC(PCI)
527};
528
529#undef CLKSRC
530
531#define VENDOR_LED_ACT(vendor)				\
532{							\
533	.vid = PCI_VENDOR_##vendor,			\
534	.led_act = { BWI_VENDOR_LED_ACT_##vendor }	\
535}
536
537const struct {
538	uint16_t	vid;
539	uint8_t		led_act[BWI_LED_MAX];
540} bwi_vendor_led_act[] = {
541	VENDOR_LED_ACT(COMPAQ),
542	VENDOR_LED_ACT(LINKSYS)
543};
544
545const uint8_t bwi_default_led_act[BWI_LED_MAX] =
546	{ BWI_VENDOR_LED_ACT_DEFAULT };
547
548#undef VENDOR_LED_ACT
549
550const struct {
551	int	on_dur;
552	int	off_dur;
553} bwi_led_duration[109] = {
554	{ 400, 100 }, {   0,   0 }, { 150 ,  75 }, {   0,   0 }, {  90,  45 },
555	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
556	{   0,   0 }, {  66,  34 }, {  53,   26 }, {   0,   0 }, {   0,   0 },
557	{   0,   0 }, {   0,   0 }, {   0,    0 }, {  42,  21 }, {   0,   0 },
558	{   0,   0 }, {   0,   0 }, {  35,   17 }, {   0,   0 }, {  32,  16 },
559	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
560	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
561	{   0,   0 }, {  21,  10 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
562	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
563	{   0,   0 }, {   0,   0 }, {   0,    0 }, {  16,   8 }, {   0,   0 },
564	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
565	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
566	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
567	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
568	{   0,   0 }, {   0,   0 }, {  11,    5 }, {   0,   0 }, {   0,   0 },
569	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
570	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
571	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
572	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
573	{   0,   0 }, {   9,   4 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
574	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   0,   0 }, {   0,   0 },
575	{   0,   0 }, {   0,   0 }, {   0,    0 }, {   7,   3 }
576};
577
578static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
579
580
581/* CODE */
582
583int
584bwi_intr(void *xsc)
585{
586	struct bwi_softc *sc = xsc;
587	struct bwi_mac *mac;
588	struct ifnet *ifp = &sc->sc_ic.ic_if;
589	uint32_t intr_status;
590	uint32_t txrx_intr_status[BWI_TXRX_NRING];
591	int i, txrx_error, tx = 0, rx_data = -1;
592
593	if ((ifp->if_flags & IFF_RUNNING) == 0)
594		return (0);
595
596	/*
597	 * Get interrupt status
598	 */
599	intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
600	if (intr_status == 0xffffffff)	/* Not for us */
601		return (0);
602
603	intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
604	if (intr_status == 0)		/* Nothing is interesting */
605		return (0);
606
607	DPRINTF(2, "%s: intr status 0x%08x\n",
608	    sc->sc_dev.dv_xname, intr_status);
609
610	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
611	mac = (struct bwi_mac *)sc->sc_cur_regwin;
612
613	txrx_error = 0;
614
615	for (i = 0; i < BWI_TXRX_NRING; ++i) {
616		uint32_t mask;
617
618		if (BWI_TXRX_IS_RX(i))
619			mask = BWI_TXRX_RX_INTRS;
620		else
621			mask = BWI_TXRX_TX_INTRS;
622
623		txrx_intr_status[i] =
624		    CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
625
626		if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
627			printf("%s: intr fatal TX/RX (%d) error 0x%08x\n",
628			    sc->sc_dev.dv_xname, i, txrx_intr_status[i]);
629			txrx_error = 1;
630		}
631	}
632
633	/*
634	 * Acknowledge interrupt
635	 */
636	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
637
638	for (i = 0; i < BWI_TXRX_NRING; ++i)
639		CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), txrx_intr_status[i]);
640
641	/* Disable all interrupts */
642	bwi_disable_intrs(sc, BWI_ALL_INTRS);
643
644	if (intr_status & BWI_INTR_PHY_TXERR) {
645		if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
646			printf("intr PHY TX error\n");
647			/* XXX to netisr0? */
648			bwi_init_statechg(sc, 0);
649			return (1);
650		}
651	}
652
653	if (txrx_error) {
654		/* TODO: reset device */
655	}
656
657	if (intr_status & BWI_INTR_TBTT)
658		bwi_mac_config_ps(mac);
659
660	if (intr_status & BWI_INTR_EO_ATIM)
661		printf("%s: EO_ATIM\n", sc->sc_dev.dv_xname);
662
663	if (intr_status & BWI_INTR_PMQ) {
664		for (;;) {
665			if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) == 0)
666				break;
667		}
668		CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
669	}
670
671	if (intr_status & BWI_INTR_NOISE)
672		printf("%s: intr noise\n", sc->sc_dev.dv_xname);
673
674	if (txrx_intr_status[0] & BWI_TXRX_INTR_RX)
675		rx_data = sc->sc_rxeof(sc);
676
677	if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
678		sc->sc_txeof_status(sc);
679		tx = 1;
680	}
681
682	if (intr_status & BWI_INTR_TX_DONE) {
683		bwi_txeof(sc);
684		tx = 1;
685	}
686
687	/* Re-enable interrupts */
688	bwi_enable_intrs(sc, BWI_INIT_INTRS);
689
690	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
691		int evt = BWI_LED_EVENT_NONE;
692
693		if (tx && rx_data > 0) {
694			if (sc->sc_rx_rate > sc->sc_tx_rate)
695				evt = BWI_LED_EVENT_RX;
696			else
697				evt = BWI_LED_EVENT_TX;
698		} else if (tx) {
699			evt = BWI_LED_EVENT_TX;
700		} else if (rx_data > 0) {
701			evt = BWI_LED_EVENT_RX;
702		} else if (rx_data == 0) {
703			evt = BWI_LED_EVENT_POLL;
704		}
705
706		if (evt != BWI_LED_EVENT_NONE)
707			bwi_led_event(sc, evt);
708	}
709
710	return (1);
711}
712
713int
714bwi_attach(struct bwi_softc *sc)
715{
716	struct ieee80211com *ic = &sc->sc_ic;
717	struct ifnet *ifp = &ic->ic_if;
718	struct bwi_mac *mac;
719	struct bwi_phy *phy;
720	int i, error;
721
722	DPRINTF(1, "\n");
723
724	/* Initialize LED vars */
725	sc->sc_led_idle = (2350 * hz) / 1000;
726	sc->sc_led_blink = 1;
727
728	/* AMRR rate control */
729	sc->sc_amrr.amrr_min_success_threshold = 1;
730	sc->sc_amrr.amrr_max_success_threshold = 15;
731	timeout_set(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
732
733	timeout_set(&sc->sc_scan_ch, bwi_next_scan, sc);
734	timeout_set(&sc->sc_calib_ch, bwi_calibrate, sc);
735
736	bwi_power_on(sc, 1);
737
738	error = bwi_bbp_attach(sc);
739	if (error)
740		goto fail;
741
742	error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
743	if (error)
744		goto fail;
745
746	if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
747		error = bwi_set_clock_delay(sc);
748		if (error)
749			goto fail;
750
751		error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
752		if (error)
753			goto fail;
754
755		error = bwi_get_pwron_delay(sc);
756		if (error)
757			goto fail;
758	}
759
760	error = bwi_bus_attach(sc);
761	if (error)
762		goto fail;
763
764	bwi_get_card_flags(sc);
765
766	bwi_led_attach(sc);
767
768	for (i = 0; i < sc->sc_nmac; ++i) {
769		struct bwi_regwin *old;
770
771		mac = &sc->sc_mac[i];
772		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
773		if (error)
774			goto fail;
775
776		error = bwi_mac_lateattach(mac);
777		if (error)
778			goto fail;
779
780		error = bwi_regwin_switch(sc, old, NULL);
781		if (error)
782			goto fail;
783	}
784
785	/*
786	 * XXX First MAC is known to exist
787	 * TODO2
788	 */
789	mac = &sc->sc_mac[0];
790	phy = &mac->mac_phy;
791
792	bwi_bbp_power_off(sc);
793
794	error = bwi_dma_alloc(sc);
795	if (error)
796		goto fail;
797
798	/* setup interface */
799	ifp->if_softc = sc;
800	ifp->if_ioctl = bwi_ioctl;
801	ifp->if_start = bwi_start;
802	ifp->if_watchdog = bwi_watchdog;
803	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
804	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
805	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
806	IFQ_SET_READY(&ifp->if_snd);
807
808	/* Get locale */
809	sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
810	    BWI_SPROM_CARD_INFO_LOCALE);
811	DPRINTF(1, "%s: locale: %d\n", sc->sc_dev.dv_xname, sc->sc_locale);
812
813	/*
814	 * Setup ratesets, phytype, channels and get MAC address
815	 */
816	if (phy->phy_mode == IEEE80211_MODE_11B ||
817	    phy->phy_mode == IEEE80211_MODE_11G) {
818	    	uint16_t chan_flags;
819
820		ic->ic_sup_rates[IEEE80211_MODE_11B] =
821		    ieee80211_std_rateset_11b;
822
823		if (phy->phy_mode == IEEE80211_MODE_11B) {
824			chan_flags = IEEE80211_CHAN_B;
825			ic->ic_phytype = IEEE80211_T_DS;
826		} else {
827			chan_flags = IEEE80211_CHAN_CCK |
828			    IEEE80211_CHAN_OFDM |
829			    IEEE80211_CHAN_DYN |
830			    IEEE80211_CHAN_2GHZ;
831			ic->ic_phytype = IEEE80211_T_OFDM;
832			ic->ic_sup_rates[IEEE80211_MODE_11G] =
833			    ieee80211_std_rateset_11g;
834		}
835
836		/* XXX depend on locale */
837		for (i = 1; i <= 14; ++i) {
838			ic->ic_channels[i].ic_freq =
839				ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
840			ic->ic_channels[i].ic_flags = chan_flags;
841		}
842
843		bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr);
844		if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
845			bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr);
846			if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
847				printf("%s: invalid MAC address: %s\n",
848				    sc->sc_dev.dv_xname,
849				    ether_sprintf(ic->ic_myaddr));
850			}
851		}
852	} else if (phy->phy_mode == IEEE80211_MODE_11A) {
853		/* TODO: 11A */
854		error = ENXIO;
855		goto fail;
856	} else
857		panic("unknown phymode %d", phy->phy_mode);
858
859	printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
860
861	sc->sc_fw_version = BWI_FW_VERSION3;
862	sc->sc_dwell_time = 200;
863
864	ic->ic_caps = IEEE80211_C_SHSLOT |
865	    IEEE80211_C_SHPREAMBLE |
866	    IEEE80211_C_WEP |
867	    IEEE80211_C_RSN |
868	    IEEE80211_C_MONITOR;
869	ic->ic_state = IEEE80211_S_INIT;
870	ic->ic_opmode = IEEE80211_M_STA;
871
872	ic->ic_updateslot = bwi_updateslot;
873
874	if_attach(ifp);
875	ieee80211_ifattach(ifp);
876
877	sc->sc_newstate = ic->ic_newstate;
878	ic->ic_newstate = bwi_newstate;
879	ic->ic_newassoc = bwi_newassoc;
880	ic->ic_node_alloc = bwi_node_alloc;
881
882	ieee80211_media_init(ifp, bwi_media_change, ieee80211_media_status);
883
884	if (error) {
885		ieee80211_ifdetach(ifp);
886		goto fail;
887	}
888
889#if NBPFILTER > 0
890	bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
891	    sizeof(struct ieee80211_frame) + 64);
892
893	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
894	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
895	sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
896
897	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
898	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
899	sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
900#endif
901
902	return (0);
903fail:
904	return (error);
905}
906
907int
908bwi_detach(void *arg)
909{
910	struct bwi_softc *sc = arg;
911	struct ifnet *ifp = &sc->sc_ic.ic_if;
912	int s, i;
913
914	bwi_stop(sc, 1);
915	ieee80211_ifdetach(ifp);
916	if_detach(ifp);
917
918	for (i = 0; i < sc->sc_nmac; ++i)
919		bwi_mac_detach(&sc->sc_mac[i]);
920
921	s = splvm();
922	bwi_dma_free(sc);
923	splx(s);
924	bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
925
926	return (0);
927}
928
929/* MAC */
930
931void
932bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
933{
934	struct bwi_softc *sc = mac->mac_sc;
935
936	if (mac->mac_flags & BWI_MAC_F_BSWAP)
937		val = swap32(val);
938
939	CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
940	CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
941}
942
943void
944bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
945{
946	uint64_t val;
947
948	val = flags & 0xffff;
949	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
950
951	val = (flags >> 16) & 0xffff;
952	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
953
954	/* HI has unclear meaning, so leave it as it is */
955}
956
957uint64_t
958bwi_hostflags_read(struct bwi_mac *mac)
959{
960	uint64_t flags, val;
961
962	/* HI has unclear meaning, so don't touch it */
963	flags = 0;
964
965	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
966	flags |= val << 16;
967
968	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
969	flags |= val;
970
971	return (flags);
972}
973
974uint16_t
975bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
976{
977	struct bwi_softc *sc = mac->mac_sc;
978	uint32_t data_reg;
979	int ofs;
980
981	data_reg = BWI_MOBJ_DATA;
982	ofs = ofs0 / 4;
983
984	if (ofs0 % 4 != 0)
985		data_reg = BWI_MOBJ_DATA_UNALIGN;
986
987	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
988	return (CSR_READ_2(sc, data_reg));
989}
990
991uint32_t
992bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
993{
994	struct bwi_softc *sc = mac->mac_sc;
995	int ofs;
996
997	ofs = ofs0 / 4;
998	if (ofs0 % 4 != 0) {
999		uint32_t ret;
1000
1001		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1002		ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
1003		ret <<= 16;
1004
1005		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1006		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
1007		ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
1008
1009		return (ret);
1010	} else {
1011		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1012		return (CSR_READ_4(sc, BWI_MOBJ_DATA));
1013	}
1014}
1015
1016void
1017bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
1018    uint16_t v)
1019{
1020	struct bwi_softc *sc = mac->mac_sc;
1021	uint32_t data_reg;
1022	int ofs;
1023
1024	data_reg = BWI_MOBJ_DATA;
1025	ofs = ofs0 / 4;
1026
1027	if (ofs0 % 4 != 0)
1028		data_reg = BWI_MOBJ_DATA_UNALIGN;
1029
1030	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1031	CSR_WRITE_2(sc, data_reg, v);
1032}
1033
1034void
1035bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
1036    uint32_t v)
1037{
1038	struct bwi_softc *sc = mac->mac_sc;
1039	int ofs;
1040
1041	ofs = ofs0 / 4;
1042	if (ofs0 % 4 != 0) {
1043		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1044		CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
1045		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1046		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
1047		CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
1048	} else {
1049		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1050		CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
1051	}
1052}
1053
1054int
1055bwi_mac_lateattach(struct bwi_mac *mac)
1056{
1057	int error;
1058
1059	if (mac->mac_rev >= 5)
1060		CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
1061
1062	bwi_mac_reset(mac, 1);
1063
1064	error = bwi_phy_attach(mac);
1065	if (error)
1066		return (error);
1067
1068	error = bwi_rf_attach(mac);
1069	if (error)
1070		return (error);
1071
1072	/* Link 11B/G PHY, unlink 11A PHY */
1073	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
1074		bwi_mac_reset(mac, 0);
1075	else
1076		bwi_mac_reset(mac, 1);
1077
1078	error = bwi_mac_test(mac);
1079	if (error)
1080		return (error);
1081
1082	error = bwi_mac_get_property(mac);
1083	if (error)
1084		return (error);
1085
1086	error = bwi_rf_map_txpower(mac);
1087	if (error)
1088		return (error);
1089
1090	bwi_rf_off(mac);
1091	CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
1092	bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
1093
1094	return (0);
1095}
1096
1097int
1098bwi_mac_init(struct bwi_mac *mac)
1099{
1100	struct bwi_softc *sc = mac->mac_sc;
1101	int error, i;
1102
1103	/* Clear MAC/PHY/RF states */
1104	bwi_mac_setup_tpctl(mac);
1105	bwi_rf_clear_state(&mac->mac_rf);
1106	bwi_phy_clear_state(&mac->mac_phy);
1107
1108	/* Enable MAC and linked it to PHY */
1109	if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
1110		bwi_mac_reset(mac, 1);
1111
1112	/* Initialize backplane */
1113	error = bwi_bus_init(sc, mac);
1114	if (error)
1115		return (error);
1116
1117	/* XXX work around for hardware bugs? */
1118	if (sc->sc_bus_regwin.rw_rev <= 5 &&
1119	    sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
1120		CSR_SETBITS_4(sc, BWI_CONF_LO,
1121		__SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
1122		__SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
1123	}
1124
1125	/* Calibrate PHY */
1126	error = bwi_phy_calibrate(mac);
1127	if (error) {
1128		printf("%s: PHY calibrate failed\n", sc->sc_dev.dv_xname);
1129		return (error);
1130	}
1131
1132	/* Prepare to initialize firmware */
1133	CSR_WRITE_4(sc, BWI_MAC_STATUS,
1134	    BWI_MAC_STATUS_UCODE_JUMP0 |
1135	    BWI_MAC_STATUS_IHREN);
1136
1137	/*
1138	 * Load and initialize firmwares
1139	 */
1140	error = bwi_mac_fw_alloc(mac);
1141	if (error)
1142		return (error);
1143
1144	error = bwi_mac_fw_load(mac);
1145	if (error)
1146		return (error);
1147
1148	error = bwi_mac_gpio_init(mac);
1149	if (error)
1150		return (error);
1151
1152	error = bwi_mac_fw_init(mac);
1153	if (error)
1154		return (error);
1155
1156	/*
1157	 * Turn on RF
1158	 */
1159	bwi_rf_on(mac);
1160
1161	/* TODO: LED, hardware rf enabled is only related to LED setting */
1162
1163	/*
1164	 * Initialize PHY
1165	 */
1166	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1167	bwi_phy_init(mac);
1168
1169	/* TODO: interference mitigation */
1170
1171	/*
1172	 * Setup antenna mode
1173	 */
1174	bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
1175
1176	/*
1177	 * Initialize operation mode (RX configuration)
1178	 */
1179	bwi_mac_opmode_init(mac);
1180
1181	/* XXX what's these */
1182	if (mac->mac_rev < 3) {
1183		CSR_WRITE_2(sc, 0x60e, 0);
1184		CSR_WRITE_2(sc, 0x610, 0x8000);
1185		CSR_WRITE_2(sc, 0x604, 0);
1186		CSR_WRITE_2(sc, 0x606, 0x200);
1187	} else {
1188		CSR_WRITE_4(sc, 0x188, 0x80000000);
1189		CSR_WRITE_4(sc, 0x18c, 0x2000000);
1190	}
1191
1192	/*
1193	 * Initialize TX/RX interrupts' mask
1194	 */
1195	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
1196	for (i = 0; i < BWI_TXRX_NRING; ++i) {
1197		uint32_t intrs;
1198
1199		if (BWI_TXRX_IS_RX(i))
1200			intrs = BWI_TXRX_RX_INTRS;
1201		else
1202			intrs = BWI_TXRX_TX_INTRS;
1203		CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
1204	}
1205
1206	/* XXX what's this */
1207	CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
1208
1209	/* Setup MAC power up delay */
1210	CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
1211
1212	/* Set MAC regwin revision */
1213	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
1214
1215	/*
1216	 * Initialize host flags
1217	 */
1218	bwi_mac_hostflags_init(mac);
1219
1220	/*
1221	 * Initialize BSS parameters
1222	 */
1223	bwi_mac_bss_param_init(mac);
1224
1225	/*
1226	 * Initialize TX rings
1227	 */
1228	for (i = 0; i < BWI_TX_NRING; ++i) {
1229		error = sc->sc_init_tx_ring(sc, i);
1230		if (error) {
1231			printf("%s: can't initialize %dth TX ring\n",
1232			    sc->sc_dev.dv_xname, i);
1233			return (error);
1234		}
1235	}
1236
1237	/*
1238	 * Initialize RX ring
1239	 */
1240	error = sc->sc_init_rx_ring(sc);
1241	if (error) {
1242		printf("%s: can't initialize RX ring\n", sc->sc_dev.dv_xname);
1243		return (error);
1244	}
1245
1246	/*
1247	 * Initialize TX stats if the current MAC uses that
1248	 */
1249	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
1250		error = sc->sc_init_txstats(sc);
1251		if (error) {
1252			printf("%s: can't initialize TX stats ring\n",
1253			    sc->sc_dev.dv_xname);
1254			return (error);
1255		}
1256	}
1257
1258	/* XXX what's these */
1259	CSR_WRITE_2(sc, 0x612, 0x50);	/* Force Pre-TBTT to 80? */
1260	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
1261	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
1262
1263	mac->mac_flags |= BWI_MAC_F_INITED;
1264
1265	return (0);
1266}
1267
1268void
1269bwi_mac_reset(struct bwi_mac *mac, int link_phy)
1270{
1271	struct bwi_softc *sc = mac->mac_sc;
1272	uint32_t flags, state_lo, status;
1273
1274	flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
1275	if (link_phy)
1276		flags |= BWI_STATE_LO_FLAG_PHYLNK;
1277	bwi_regwin_enable(sc, &mac->mac_regwin, flags);
1278	DELAY(2000);
1279
1280	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
1281	state_lo |= BWI_STATE_LO_GATED_CLOCK;
1282	state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
1283			       BWI_STATE_LO_FLAGS_MASK);
1284	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1285	/* Flush pending bus write */
1286	CSR_READ_4(sc, BWI_STATE_LO);
1287	DELAY(1000);
1288
1289	state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
1290	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1291	/* Flush pending bus write */
1292	CSR_READ_4(sc, BWI_STATE_LO);
1293	DELAY(1000);
1294
1295	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1296
1297	status = CSR_READ_4(sc, BWI_MAC_STATUS);
1298	status |= BWI_MAC_STATUS_IHREN;
1299	if (link_phy)
1300		status |= BWI_MAC_STATUS_PHYLNK;
1301	else
1302		status &= ~BWI_MAC_STATUS_PHYLNK;
1303	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
1304
1305	if (link_phy) {
1306		DPRINTF(1, "%s: PHY is linked\n", sc->sc_dev.dv_xname);
1307		mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
1308	} else {
1309		DPRINTF(1, "%s: PHY is unlinked\n", sc->sc_dev.dv_xname);
1310		mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
1311	}
1312}
1313
1314void
1315bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
1316{
1317	struct bwi_rf *rf = &mac->mac_rf;
1318	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1319
1320	if (new_tpctl != NULL) {
1321		KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX);
1322		KASSERT(new_tpctl->rf_atten <=
1323		    (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
1324		    : BWI_RF_ATTEN_MAX1));
1325		KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX);
1326
1327		tpctl->bbp_atten = new_tpctl->bbp_atten;
1328		tpctl->rf_atten = new_tpctl->rf_atten;
1329		tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
1330	}
1331
1332	/* Set BBP attenuation */
1333	bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
1334
1335	/* Set RF attenuation */
1336	RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
1337	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
1338	    tpctl->rf_atten);
1339
1340	/* Set TX power */
1341	if (rf->rf_type == BWI_RF_T_BCM2050) {
1342		RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
1343		    __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
1344	}
1345
1346	/* Adjust RF Local Oscillator */
1347	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
1348		bwi_rf_lo_adjust(mac, tpctl);
1349}
1350
1351int
1352bwi_mac_test(struct bwi_mac *mac)
1353{
1354	struct bwi_softc *sc = mac->mac_sc;
1355	uint32_t orig_val, val;
1356
1357#define TEST_VAL1	0xaa5555aa
1358#define TEST_VAL2	0x55aaaa55
1359	/* Save it for later restoring */
1360	orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1361
1362	/* Test 1 */
1363	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
1364	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1365	if (val != TEST_VAL1) {
1366		printf("%s: TEST1 failed\n", sc->sc_dev.dv_xname);
1367		return (ENXIO);
1368	}
1369
1370	/* Test 2 */
1371	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
1372	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1373	if (val != TEST_VAL2) {
1374		printf("%s: TEST2 failed\n", sc->sc_dev.dv_xname);
1375		return (ENXIO);
1376	}
1377
1378	/* Restore to the original value */
1379	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
1380
1381	val = CSR_READ_4(sc, BWI_MAC_STATUS);
1382	if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
1383		printf("%s: %s failed, MAC status 0x%08x\n",
1384		    sc->sc_dev.dv_xname, __func__, val);
1385		return (ENXIO);
1386	}
1387
1388	val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1389	if (val != 0) {
1390		printf("%s: %s failed, intr status %08x\n",
1391		    sc->sc_dev.dv_xname, __func__, val);
1392		return (ENXIO);
1393	}
1394#undef TEST_VAL2
1395#undef TEST_VAL1
1396
1397	return (0);
1398}
1399
1400void
1401bwi_mac_setup_tpctl(struct bwi_mac *mac)
1402{
1403	struct bwi_softc *sc = mac->mac_sc;
1404	struct bwi_rf *rf = &mac->mac_rf;
1405	struct bwi_phy *phy = &mac->mac_phy;
1406	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1407
1408	/* Calc BBP attenuation */
1409	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
1410		tpctl->bbp_atten = 0;
1411	else
1412		tpctl->bbp_atten = 2;
1413
1414	/* Calc TX power CTRL1?? */
1415	tpctl->tp_ctrl1 = 0;
1416	if (rf->rf_type == BWI_RF_T_BCM2050) {
1417		if (rf->rf_rev == 1)
1418			tpctl->tp_ctrl1 = 3;
1419		else if (rf->rf_rev < 6)
1420			tpctl->tp_ctrl1 = 2;
1421		else if (rf->rf_rev == 8)
1422			tpctl->tp_ctrl1 = 1;
1423	}
1424
1425	/* Empty TX power CTRL2?? */
1426	tpctl->tp_ctrl2 = 0xffff;
1427
1428	/*
1429	 * Calc RF attenuation
1430	 */
1431	if (phy->phy_mode == IEEE80211_MODE_11A) {
1432		tpctl->rf_atten = 0x60;
1433		goto back;
1434	}
1435
1436	if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
1437		tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
1438		goto back;
1439	}
1440
1441	tpctl->rf_atten = 5;
1442
1443	if (rf->rf_type != BWI_RF_T_BCM2050) {
1444		if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
1445			tpctl->rf_atten = 6;
1446		goto back;
1447	}
1448
1449	/*
1450	 * NB: If we reaches here and the card is BRCM_BCM4309G,
1451	 *     then the card's PCI revision must >= 0x51
1452	 */
1453
1454	/* BCM2050 RF */
1455	switch (rf->rf_rev) {
1456	case 1:
1457		if (phy->phy_mode == IEEE80211_MODE_11G) {
1458			if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
1459				tpctl->rf_atten = 3;
1460			else
1461				tpctl->rf_atten = 1;
1462		} else {
1463			if (BWI_IS_BRCM_BCM4309G(sc))
1464				tpctl->rf_atten = 7;
1465			else
1466				tpctl->rf_atten = 6;
1467		}
1468		break;
1469	case 2:
1470		if (phy->phy_mode == IEEE80211_MODE_11G) {
1471			/*
1472			 * NOTE: Order of following conditions is critical
1473			 */
1474			if (BWI_IS_BRCM_BCM4309G(sc))
1475				tpctl->rf_atten = 3;
1476			else if (BWI_IS_BRCM_BU4306(sc))
1477				tpctl->rf_atten = 5;
1478			else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
1479				tpctl->rf_atten = 4;
1480			else
1481				tpctl->rf_atten = 3;
1482		} else {
1483			tpctl->rf_atten = 6;
1484		}
1485		break;
1486	case 4:
1487	case 5:
1488		tpctl->rf_atten = 1;
1489		break;
1490	case 8:
1491		tpctl->rf_atten = 0x1a;
1492		break;
1493	}
1494back:
1495	DPRINTF(1, "%s: bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
1496	    sc->sc_dev.dv_xname, tpctl->bbp_atten, tpctl->rf_atten,
1497	    tpctl->tp_ctrl1, tpctl->tp_ctrl2);
1498}
1499
1500void
1501bwi_mac_dummy_xmit(struct bwi_mac *mac)
1502{
1503#define PACKET_LEN	5
1504	struct bwi_softc *sc = mac->mac_sc;
1505	struct bwi_rf *rf = &mac->mac_rf;
1506	const uint32_t *packet;
1507	uint16_t val_50c;
1508	int wait_max, i;
1509
1510	static const uint32_t	packet_11a[PACKET_LEN] =
1511	    { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1512	static const uint32_t	packet_11bg[PACKET_LEN] =
1513	    { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1514
1515	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
1516		wait_max = 30;
1517		packet = packet_11a;
1518		val_50c = 1;
1519	} else {
1520		wait_max = 250;
1521		packet = packet_11bg;
1522		val_50c = 0;
1523	}
1524
1525	for (i = 0; i < PACKET_LEN; ++i)
1526		TMPLT_WRITE_4(mac, i * 4, packet[i]);
1527
1528	CSR_READ_4(sc, BWI_MAC_STATUS);	/* dummy read */
1529
1530	CSR_WRITE_2(sc, 0x568, 0);
1531	CSR_WRITE_2(sc, 0x7c0, 0);
1532	CSR_WRITE_2(sc, 0x50c, val_50c);
1533	CSR_WRITE_2(sc, 0x508, 0);
1534	CSR_WRITE_2(sc, 0x50a, 0);
1535	CSR_WRITE_2(sc, 0x54c, 0);
1536	CSR_WRITE_2(sc, 0x56a, 0x14);
1537	CSR_WRITE_2(sc, 0x568, 0x826);
1538	CSR_WRITE_2(sc, 0x500, 0);
1539	CSR_WRITE_2(sc, 0x502, 0x30);
1540
1541	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1542		RF_WRITE(mac, 0x51, 0x17);
1543
1544	for (i = 0; i < wait_max; ++i) {
1545		if (CSR_READ_2(sc, 0x50e) & 0x80)
1546			break;
1547		DELAY(10);
1548	}
1549	for (i = 0; i < 10; ++i) {
1550		if (CSR_READ_2(sc, 0x50e) & 0x400)
1551			break;
1552		DELAY(10);
1553	}
1554	for (i = 0; i < 10; ++i) {
1555		if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
1556			break;
1557		DELAY(10);
1558	}
1559
1560	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1561		RF_WRITE(mac, 0x51, 0x37);
1562#undef PACKET_LEN
1563}
1564
1565void
1566bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
1567{
1568	struct bwi_softc *sc = mac->mac_sc;
1569	struct bwi_phy *phy = &mac->mac_phy;
1570	struct bwi_rf *rf = &mac->mac_rf;
1571	struct bwi_tpctl tpctl_orig;
1572	int restore_tpctl = 0;
1573
1574	KASSERT(phy->phy_mode != IEEE80211_MODE_11A);
1575
1576	if (BWI_IS_BRCM_BU4306(sc))
1577		return;
1578
1579	PHY_WRITE(mac, 0x28, 0x8018);
1580	CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
1581
1582	if (phy->phy_mode == IEEE80211_MODE_11G) {
1583		if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
1584			return;
1585		PHY_WRITE(mac, 0x47a, 0xc111);
1586	}
1587	if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
1588		return;
1589
1590	if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
1591	    rf->rf_type == BWI_RF_T_BCM2050) {
1592		RF_SETBITS(mac, 0x76, 0x84);
1593	} else {
1594		struct bwi_tpctl tpctl;
1595
1596		/* Backup original TX power control variables */
1597		bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig));
1598		restore_tpctl = 1;
1599
1600		bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
1601		tpctl.bbp_atten = 11;
1602		tpctl.tp_ctrl1 = 0;
1603#ifdef notyet
1604		if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
1605			tpctl.rf_atten = 31;
1606		else
1607#endif
1608			tpctl.rf_atten = 9;
1609
1610		bwi_mac_set_tpctl_11bg(mac, &tpctl);
1611	}
1612
1613	bwi_mac_dummy_xmit(mac);
1614
1615	mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
1616	rf->rf_base_tssi = PHY_READ(mac, 0x29);
1617	DPRINTF(1, "%s: base tssi %d\n", sc->sc_dev.dv_xname, rf->rf_base_tssi);
1618
1619	if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
1620		printf("%s: base tssi measure failed\n", sc->sc_dev.dv_xname);
1621		mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
1622	}
1623
1624	if (restore_tpctl)
1625		bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
1626	else
1627		RF_CLRBITS(mac, 0x76, 0x84);
1628
1629	bwi_rf_clear_tssi(mac);
1630}
1631
1632void
1633bwi_mac_detach(struct bwi_mac *mac)
1634{
1635	bwi_mac_fw_free(mac);
1636}
1637
1638int
1639bwi_get_firmware(const char *name, const uint8_t *ucode, size_t size_ucode,
1640    size_t *size, size_t *offset)
1641{
1642	int i, nfiles, off = 0, ret = 1;
1643	struct fwheader *h;
1644
1645	if ((h = malloc(sizeof(struct fwheader), M_DEVBUF, M_NOWAIT)) == NULL)
1646		return (ret);
1647
1648	/* get number of firmware files */
1649	bcopy(ucode, &nfiles, sizeof(nfiles));
1650	nfiles = ntohl(nfiles);
1651	off += sizeof(nfiles);
1652
1653	/* parse header and search the firmware */
1654	for (i = 0; i < nfiles && off < size_ucode; i++) {
1655		bzero(h, sizeof(struct fwheader));
1656		bcopy(ucode + off, h, sizeof(struct fwheader));
1657		off += sizeof(struct fwheader);
1658
1659		if (strcmp(name, h->filename) == 0) {
1660			ret = 0;
1661			*size = ntohl(h->filesize);
1662			*offset = ntohl(h->fileoffset);
1663			break;
1664		}
1665	}
1666
1667	free(h, M_DEVBUF, 0);
1668
1669	return (ret);
1670}
1671
1672int
1673bwi_fwimage_is_valid(struct bwi_softc *sc, uint8_t *fw, size_t fw_len,
1674    char *fw_name, uint8_t fw_type)
1675{
1676	const struct bwi_fwhdr *hdr;
1677
1678	if (fw_len < sizeof(*hdr)) {
1679		printf("%s: invalid firmware (%s): invalid size %zu\n",
1680		    sc->sc_dev.dv_xname, fw_name, fw_len);
1681		return (1);
1682	}
1683
1684	hdr = (const struct bwi_fwhdr *)fw;
1685
1686	if (fw_type != BWI_FW_T_IV) {
1687		/*
1688		 * Don't verify IV's size, it has different meaning
1689		 */
1690		if (betoh32(hdr->fw_size) != fw_len - sizeof(*hdr)) {
1691			printf("%s: invalid firmware (%s): size mismatch, "
1692			    "fw %u, real %zu\n",
1693			    sc->sc_dev.dv_xname,
1694			    fw_name,
1695			    betoh32(hdr->fw_size),
1696			    fw_len - sizeof(*hdr));
1697			return (1);
1698		}
1699	}
1700
1701	if (hdr->fw_type != fw_type) {
1702		printf("%s: invalid firmware (%s): type mismatch, "
1703		    "fw \'%c\', target \'%c\'\n",
1704		    sc->sc_dev.dv_xname, fw_name, hdr->fw_type, fw_type);
1705		return (1);
1706	}
1707
1708	if (hdr->fw_gen != BWI_FW_GEN_1) {
1709		printf("%s: invalid firmware (%s): wrong generation, "
1710		    "fw %d, target %d\n",
1711		    sc->sc_dev.dv_xname, fw_name, hdr->fw_gen, BWI_FW_GEN_1);
1712		return (1);
1713	}
1714
1715	return (0);
1716}
1717
1718int
1719bwi_mac_fw_alloc(struct bwi_mac *mac)
1720{
1721	struct bwi_softc *sc = mac->mac_sc;
1722	char *name = "bwi-airforce";
1723	size_t offset;
1724	char fwname[64];
1725	int idx, error;
1726
1727	if (mac->mac_fw == NULL) {
1728		error = loadfirmware(name, &mac->mac_fw, &mac->mac_fw_size);
1729		if (error != 0) {
1730			printf("%s: error %d, could not read firmware %s\n",
1731			    sc->sc_dev.dv_xname, error, name);
1732			mac->mac_fw = NULL;
1733			return (EIO);
1734		}
1735	}
1736
1737	if (mac->mac_ucode == NULL) {
1738		snprintf(fwname, sizeof(fwname), "ucode%d.fw",
1739		    mac->mac_rev >= 5 ? 5 : mac->mac_rev);
1740
1741		error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size,
1742		    &mac->mac_ucode_size, &offset);
1743		if (error != 0) {
1744			printf("%s: error %d, could not read firmware %s!\n",
1745			    sc->sc_dev.dv_xname, error, fwname);
1746			return (ENOMEM);
1747		}
1748		mac->mac_ucode = (mac->mac_fw + offset);
1749		DPRINTF(1, "%s: loaded firmware file %s\n",
1750		    sc->sc_dev.dv_xname, fwname);
1751
1752		if (bwi_fwimage_is_valid(sc, mac->mac_ucode,
1753		    mac->mac_ucode_size, fwname, BWI_FW_T_UCODE))
1754			return (EINVAL);
1755	}
1756
1757	if (mac->mac_pcm == NULL) {
1758		snprintf(fwname, sizeof(fwname), "pcm%d.fw",
1759		    mac->mac_rev < 5 ? 4 : 5);
1760
1761		error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size,
1762		    &mac->mac_pcm_size, &offset);
1763		if (error != 0) {
1764			printf("%s: error %d, could not read firmware %s!\n",
1765			    sc->sc_dev.dv_xname, error, fwname);
1766			return (ENOMEM);
1767		}
1768		mac->mac_pcm = (mac->mac_fw + offset);
1769		DPRINTF(1, "%s: loaded firmware file %s\n",
1770		    sc->sc_dev.dv_xname, fwname);
1771
1772		if (bwi_fwimage_is_valid(sc, mac->mac_pcm,
1773		    mac->mac_pcm_size, fwname, BWI_FW_T_PCM))
1774			return (EINVAL);
1775	}
1776
1777	if (mac->mac_iv == NULL) {
1778		/* TODO: 11A */
1779		if (mac->mac_rev == 2 || mac->mac_rev == 4) {
1780			idx = 2;
1781		} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
1782			idx = 5;
1783		} else {
1784			printf("%s: no suitable IV for MAC rev %d\n",
1785			    sc->sc_dev.dv_xname, mac->mac_rev);
1786			return (ENODEV);
1787		}
1788
1789		snprintf(fwname, sizeof(fwname), "b0g0initvals%d.fw", idx);
1790
1791		error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size,
1792		    &mac->mac_iv_size, &offset);
1793		if (error != 0) {
1794			printf("%s: error %d, could not read firmware %s!\n",
1795			    sc->sc_dev.dv_xname, error, fwname);
1796			return (ENOMEM);
1797		}
1798		mac->mac_iv = (mac->mac_fw + offset);
1799		DPRINTF(1, "%s: loaded firmware file %s\n",
1800		    sc->sc_dev.dv_xname, fwname);
1801
1802		if (bwi_fwimage_is_valid(sc, mac->mac_iv,
1803		    mac->mac_iv_size, fwname, BWI_FW_T_IV))
1804			return (EINVAL);
1805	}
1806
1807	if (mac->mac_iv_ext == NULL) {
1808		/* TODO: 11A */
1809		if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
1810		    mac->mac_rev >= 11) {
1811			/* No extended IV */
1812			goto back;
1813		} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
1814			idx = 5;
1815		} else {
1816			printf("%s: no suitable ExtIV for MAC rev %d\n",
1817			    sc->sc_dev.dv_xname, mac->mac_rev);
1818			return (ENODEV);
1819		}
1820
1821		snprintf(fwname, sizeof(fwname), "b0g0bsinitvals%d.fw", idx);
1822
1823		error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size,
1824		    &mac->mac_iv_ext_size, &offset);
1825		if (error != 0) {
1826			printf("%s: error %d, could not read firmware %s!\n",
1827			    sc->sc_dev.dv_xname, error, fwname);
1828			return (ENOMEM);
1829		}
1830		mac->mac_iv_ext = (mac->mac_fw + offset);
1831		DPRINTF(1, "%s: loaded firmware file %s\n",
1832		    sc->sc_dev.dv_xname, fwname);
1833
1834		if (bwi_fwimage_is_valid(sc, mac->mac_iv_ext,
1835		    mac->mac_iv_ext_size, fwname, BWI_FW_T_IV))
1836			return (EINVAL);
1837	}
1838
1839back:
1840	return (0);
1841}
1842
1843void
1844bwi_mac_fw_free(struct bwi_mac *mac)
1845{
1846	if (mac->mac_fw != NULL) {
1847		free(mac->mac_fw, M_DEVBUF, 0);
1848		mac->mac_fw = NULL;
1849	}
1850}
1851
1852int
1853bwi_mac_fw_load(struct bwi_mac *mac)
1854{
1855	struct bwi_softc *sc = mac->mac_sc;
1856	uint16_t fw_rev;
1857	const uint32_t *fw;
1858	int fw_len, i, error = 0;
1859
1860	/*
1861	 * Load FW image
1862	 */
1863	fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZ);
1864	fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
1865
1866	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1867	    BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
1868	for (i = 0; i < fw_len; ++i) {
1869		CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]));
1870		DELAY(10);
1871	}
1872
1873	/*
1874	 * Load PCM image
1875	 */
1876	fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZ);
1877	fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
1878
1879	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1880	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
1881	CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
1882
1883	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1884	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
1885	for (i = 0; i < fw_len; ++i) {
1886		CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]));
1887		DELAY(10);
1888	}
1889
1890	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
1891	CSR_WRITE_4(sc, BWI_MAC_STATUS,
1892	    BWI_MAC_STATUS_UCODE_START |
1893	    BWI_MAC_STATUS_IHREN |
1894	    BWI_MAC_STATUS_INFRA);
1895
1896#define NRETRY	200
1897	for (i = 0; i < NRETRY; ++i) {
1898		uint32_t intr_status;
1899
1900		intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1901		if (intr_status == BWI_INTR_READY)
1902			break;
1903		DELAY(10);
1904	}
1905	if (i == NRETRY) {
1906		printf("%s: firmware (fw & pcm) loading timed out\n",
1907		    sc->sc_dev.dv_xname);
1908		error = ETIMEDOUT;
1909		goto out;
1910	}
1911#undef NRETRY
1912
1913	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);	/* dummy read */
1914
1915	fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
1916	if (fw_rev > BWI_FW_VERSION3_REVMAX) {
1917		printf("%s: firmware version 4 is not supported yet\n",
1918		    sc->sc_dev.dv_xname);
1919		error = ENODEV;
1920		goto out;
1921	}
1922
1923	DPRINTF(1, "%s: firmware rev 0x%04x, patch level 0x%04x\n",
1924	    sc->sc_dev.dv_xname, fw_rev,
1925	    MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
1926
1927out:
1928	return (error);
1929}
1930
1931int
1932bwi_mac_gpio_init(struct bwi_mac *mac)
1933{
1934	struct bwi_softc *sc = mac->mac_sc;
1935	struct bwi_regwin *old, *gpio_rw;
1936	uint32_t filt, bits;
1937	int error;
1938
1939	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
1940	/* TODO: LED */
1941
1942	CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
1943
1944	filt = 0x1f;
1945	bits = 0xf;
1946	if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
1947		filt |= 0x60;
1948		bits |= 0x60;
1949	}
1950	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1951		CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
1952		filt |= 0x200;
1953		bits |= 0x200;
1954	}
1955
1956	gpio_rw = BWI_GPIO_REGWIN(sc);
1957	error = bwi_regwin_switch(sc, gpio_rw, &old);
1958	if (error)
1959		return (error);
1960
1961	CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
1962
1963	return (bwi_regwin_switch(sc, old, NULL));
1964}
1965
1966int
1967bwi_mac_gpio_fini(struct bwi_mac *mac)
1968{
1969	struct bwi_softc *sc = mac->mac_sc;
1970	struct bwi_regwin *old, *gpio_rw;
1971	int error;
1972
1973	gpio_rw = BWI_GPIO_REGWIN(sc);
1974	error = bwi_regwin_switch(sc, gpio_rw, &old);
1975	if (error)
1976		return (error);
1977
1978	CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
1979
1980	return (bwi_regwin_switch(sc, old, NULL));
1981}
1982
1983int
1984bwi_mac_fw_load_iv(struct bwi_mac *mac, uint8_t *fw, size_t fw_len)
1985{
1986	struct bwi_softc *sc = mac->mac_sc;
1987	const struct bwi_fwhdr *hdr;
1988	const struct bwi_fw_iv *iv;
1989	int n, i, iv_img_size;
1990
1991	/* Get the number of IVs in the IV image */
1992	hdr = (const struct bwi_fwhdr *)fw;
1993	n = betoh32(hdr->fw_iv_cnt);
1994	DPRINTF(1, "%s: IV count %d\n", sc->sc_dev.dv_xname, n);
1995
1996	/* Calculate the IV image size, for later sanity check */
1997	iv_img_size = fw_len - sizeof(*hdr);
1998
1999	/* Locate the first IV */
2000	iv = (const struct bwi_fw_iv *)(fw + sizeof(*hdr));
2001
2002	for (i = 0; i < n; ++i) {
2003		uint16_t iv_ofs, ofs;
2004		int sz = 0;
2005
2006		if (iv_img_size < sizeof(iv->iv_ofs)) {
2007			printf("%s: invalid IV image, ofs\n",
2008			    sc->sc_dev.dv_xname);
2009			return (EINVAL);
2010		}
2011		iv_img_size -= sizeof(iv->iv_ofs);
2012		sz += sizeof(iv->iv_ofs);
2013
2014		iv_ofs = betoh16(iv->iv_ofs);
2015
2016		ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
2017		if (ofs >= 0x1000) {
2018			printf("%s: invalid ofs (0x%04x) for %dth iv\n",
2019			    sc->sc_dev.dv_xname, ofs, i);
2020			return (EINVAL);
2021		}
2022
2023		if (iv_ofs & BWI_FW_IV_IS_32BIT) {
2024			uint32_t val32;
2025
2026			if (iv_img_size < sizeof(iv->iv_val.val32)) {
2027				printf("%s: invalid IV image, val32\n",
2028				    sc->sc_dev.dv_xname);
2029				return (EINVAL);
2030			}
2031			iv_img_size -= sizeof(iv->iv_val.val32);
2032			sz += sizeof(iv->iv_val.val32);
2033
2034			val32 = betoh32(iv->iv_val.val32);
2035			CSR_WRITE_4(sc, ofs, val32);
2036		} else {
2037			uint16_t val16;
2038
2039			if (iv_img_size < sizeof(iv->iv_val.val16)) {
2040				printf("%s: invalid IV image, val16\n",
2041				    sc->sc_dev.dv_xname);
2042				return (EINVAL);
2043			}
2044			iv_img_size -= sizeof(iv->iv_val.val16);
2045			sz += sizeof(iv->iv_val.val16);
2046
2047			val16 = betoh16(iv->iv_val.val16);
2048			CSR_WRITE_2(sc, ofs, val16);
2049		}
2050
2051		iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
2052	}
2053
2054	if (iv_img_size != 0) {
2055		printf("%s: invalid IV image, size left %d\n",
2056		    sc->sc_dev.dv_xname, iv_img_size);
2057		return (EINVAL);
2058	}
2059
2060	return (0);
2061}
2062
2063int
2064bwi_mac_fw_init(struct bwi_mac *mac)
2065{
2066	struct bwi_softc *sc = mac->mac_sc;
2067	int error;
2068
2069	error = bwi_mac_fw_load_iv(mac, mac->mac_iv, mac->mac_iv_size);
2070	if (error) {
2071		printf("%s: load IV failed\n", sc->sc_dev.dv_xname);
2072		return (error);
2073	}
2074
2075	if (mac->mac_iv_ext != NULL) {
2076		error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext,
2077		    mac->mac_iv_ext_size);
2078		if (error)
2079			printf("%s: load ExtIV failed\n", sc->sc_dev.dv_xname);
2080	}
2081
2082	return (error);
2083}
2084
2085void
2086bwi_mac_opmode_init(struct bwi_mac *mac)
2087{
2088	struct bwi_softc *sc = mac->mac_sc;
2089	struct ieee80211com *ic = &sc->sc_ic;
2090	uint32_t mac_status;
2091	uint16_t pre_tbtt;
2092
2093	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
2094	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
2095	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
2096
2097	/* Set probe resp timeout to infinite */
2098	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
2099
2100	/*
2101	 * TODO: factor out following part
2102	 */
2103
2104	mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
2105	mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
2106	    BWI_MAC_STATUS_PASS_CTL |
2107	    BWI_MAC_STATUS_PASS_BADPLCP |
2108	    BWI_MAC_STATUS_PASS_BADFCS |
2109	    BWI_MAC_STATUS_PROMISC);
2110	mac_status |= BWI_MAC_STATUS_INFRA;
2111
2112	/* Always turn on PROMISC on old hardware */
2113	if (mac->mac_rev < 5)
2114		mac_status |= BWI_MAC_STATUS_PROMISC;
2115
2116	switch (ic->ic_opmode) {
2117#ifndef IEEE80211_STA_ONLY
2118	case IEEE80211_M_IBSS:
2119		mac_status &= ~BWI_MAC_STATUS_INFRA;
2120		break;
2121	case IEEE80211_M_HOSTAP:
2122		mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
2123		break;
2124#endif
2125	case IEEE80211_M_MONITOR:
2126#if 0
2127		/* Do you want data from your microwave oven? */
2128		mac_status |= BWI_MAC_STATUS_PASS_CTL |
2129			      BWI_MAC_STATUS_PASS_BADPLCP |
2130			      BWI_MAC_STATUS_PASS_BADFCS;
2131#else
2132		mac_status |= BWI_MAC_STATUS_PASS_CTL;
2133#endif
2134		/* Promisc? */
2135		break;
2136	default:
2137		break;
2138	}
2139
2140	if (ic->ic_if.if_flags & IFF_PROMISC)
2141		mac_status |= BWI_MAC_STATUS_PROMISC;
2142
2143	CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
2144
2145#ifndef IEEE80211_STA_ONLY
2146	if (ic->ic_opmode != IEEE80211_M_IBSS &&
2147	    ic->ic_opmode != IEEE80211_M_HOSTAP) {
2148#endif
2149		if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
2150			pre_tbtt = 100;
2151		else
2152			pre_tbtt = 50;
2153#ifndef IEEE80211_STA_ONLY
2154	} else
2155		pre_tbtt = 2;
2156#endif
2157	CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
2158}
2159
2160void
2161bwi_mac_hostflags_init(struct bwi_mac *mac)
2162{
2163	struct bwi_softc *sc = mac->mac_sc;
2164	struct bwi_phy *phy = &mac->mac_phy;
2165	struct bwi_rf *rf = &mac->mac_rf;
2166	uint64_t host_flags;
2167
2168	if (phy->phy_mode == IEEE80211_MODE_11A)
2169		return;
2170
2171	host_flags = HFLAGS_READ(mac);
2172	host_flags |= BWI_HFLAG_SYM_WA;
2173
2174	if (phy->phy_mode == IEEE80211_MODE_11G) {
2175		if (phy->phy_rev == 1)
2176			host_flags |= BWI_HFLAG_GDC_WA;
2177		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
2178			host_flags |= BWI_HFLAG_OFDM_PA;
2179	} else if (phy->phy_mode == IEEE80211_MODE_11B) {
2180		if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
2181			host_flags &= ~BWI_HFLAG_GDC_WA;
2182	} else {
2183		panic("unknown PHY mode %u", phy->phy_mode);
2184	}
2185
2186	HFLAGS_WRITE(mac, host_flags);
2187}
2188
2189void
2190bwi_mac_bss_param_init(struct bwi_mac *mac)
2191{
2192	struct bwi_softc *sc = mac->mac_sc;
2193	struct bwi_phy *phy = &mac->mac_phy;
2194	struct bwi_retry_lim lim;
2195	uint16_t cw_min;
2196
2197	/*
2198	 * Set short/long retry limits
2199	 */
2200	bzero(&lim, sizeof(lim));
2201	lim.shretry = BWI_SHRETRY;
2202	lim.shretry_fb = BWI_SHRETRY_FB;
2203	lim.lgretry = BWI_LGRETRY;
2204	lim.lgretry_fb = BWI_LGRETRY_FB;
2205	bwi_mac_set_retry_lim(mac, &lim);
2206
2207	/*
2208	 * Implicitly prevent firmware from sending probe response
2209	 * by setting its "probe response timeout" to 1us.
2210	 */
2211	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
2212
2213	/*
2214	 * XXX MAC level acknowledge and CW min/max should depend
2215	 * on the char rateset of the IBSS/BSS to join.
2216	 */
2217
2218	/*
2219	 * Set MAC level acknowledge rates
2220	 */
2221	bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]);
2222
2223	/*
2224	 * Set CW min
2225	 */
2226	if (phy->phy_mode == IEEE80211_MODE_11B)
2227		cw_min = IEEE80211_CW_MIN_0;
2228	else
2229		cw_min = IEEE80211_CW_MIN_1;
2230	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
2231
2232	/*
2233	 * Set CW max
2234	 */
2235	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
2236	    IEEE80211_CW_MAX);
2237}
2238
2239void
2240bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
2241{
2242	/* Short/Long retry limit */
2243	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
2244	    lim->shretry);
2245	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
2246	    lim->lgretry);
2247
2248	/* Short/Long retry fallback limit */
2249	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
2250	    lim->shretry_fb);
2251	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
2252	    lim->lgretry_fb);
2253}
2254
2255void
2256bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs)
2257{
2258	struct bwi_softc *sc;
2259	int i;
2260
2261	sc = mac->mac_sc;
2262
2263	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
2264
2265	/* XXX not standard conforming */
2266	for (i = 0; i < rs->rs_nrates; ++i) {
2267		enum bwi_modtype modtype;
2268		uint16_t ofs;
2269
2270		modtype = bwi_rate2modtype(rs->rs_rates[i]);
2271		switch (modtype) {
2272		case IEEE80211_MODTYPE_DS:
2273			ofs = 0x4c0;
2274			ofs += (ieee80211_rate2plcp(rs->rs_rates[i],
2275			    IEEE80211_MODE_11B) & 0xf) * 2;
2276			break;
2277		case IEEE80211_MODTYPE_OFDM:
2278			ofs = 0x480;
2279			ofs += (ieee80211_rate2plcp(rs->rs_rates[i],
2280			    IEEE80211_MODE_11G) & 0xf) * 2;
2281			break;
2282		default:
2283			panic("unsupported modtype %u", modtype);
2284		}
2285
2286		MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
2287		    MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
2288	}
2289}
2290
2291int
2292bwi_mac_start(struct bwi_mac *mac)
2293{
2294	struct bwi_softc *sc = mac->mac_sc;
2295
2296	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2297	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
2298
2299	/* Flush pending bus writes */
2300	CSR_READ_4(sc, BWI_MAC_STATUS);
2301	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
2302
2303	return (bwi_mac_config_ps(mac));
2304}
2305
2306int
2307bwi_mac_stop(struct bwi_mac *mac)
2308{
2309	struct bwi_softc *sc = mac->mac_sc;
2310	int error, i;
2311
2312	error = bwi_mac_config_ps(mac);
2313	if (error)
2314		return (error);
2315
2316	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2317
2318	/* Flush pending bus write */
2319	CSR_READ_4(sc, BWI_MAC_STATUS);
2320
2321#define NRETRY	10000
2322	for (i = 0; i < NRETRY; ++i) {
2323		if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
2324			break;
2325		DELAY(1);
2326	}
2327	if (i == NRETRY) {
2328		printf("%s: can't stop MAC\n", sc->sc_dev.dv_xname);
2329		return (ETIMEDOUT);
2330	}
2331#undef NRETRY
2332
2333	return (0);
2334}
2335
2336int
2337bwi_mac_config_ps(struct bwi_mac *mac)
2338{
2339	struct bwi_softc *sc = mac->mac_sc;
2340	uint32_t status;
2341
2342	status = CSR_READ_4(sc, BWI_MAC_STATUS);
2343
2344	status &= ~BWI_MAC_STATUS_HW_PS;
2345	status |= BWI_MAC_STATUS_WAKEUP;
2346	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
2347
2348	/* Flush pending bus write */
2349	CSR_READ_4(sc, BWI_MAC_STATUS);
2350
2351	if (mac->mac_rev >= 5) {
2352		int i;
2353
2354#define NRETRY	100
2355		for (i = 0; i < NRETRY; ++i) {
2356			if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
2357			    BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
2358				break;
2359			DELAY(10);
2360		}
2361		if (i == NRETRY) {
2362			printf("%s: config PS failed\n", sc->sc_dev.dv_xname);
2363			return (ETIMEDOUT);
2364		}
2365#undef NRETRY
2366	}
2367	return (0);
2368}
2369
2370void
2371bwi_mac_reset_hwkeys(struct bwi_mac *mac)
2372{
2373	/* TODO: firmware crypto */
2374	MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
2375}
2376
2377void
2378bwi_mac_shutdown(struct bwi_mac *mac)
2379{
2380	struct bwi_softc *sc = mac->mac_sc;
2381	int i;
2382
2383	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
2384		sc->sc_free_txstats(sc);
2385
2386	sc->sc_free_rx_ring(sc);
2387
2388	for (i = 0; i < BWI_TX_NRING; ++i)
2389		sc->sc_free_tx_ring(sc, i);
2390
2391	bwi_rf_off(mac);
2392
2393	/* TODO: LED */
2394
2395	bwi_mac_gpio_fini(mac);
2396
2397	bwi_rf_off(mac); /* XXX again */
2398	CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
2399	bwi_regwin_disable(sc, &mac->mac_regwin, 0);
2400
2401	mac->mac_flags &= ~BWI_MAC_F_INITED;
2402}
2403
2404int
2405bwi_mac_get_property(struct bwi_mac *mac)
2406{
2407	struct bwi_softc *sc = mac->mac_sc;
2408	enum bwi_bus_space old_bus_space;
2409	uint32_t val;
2410
2411	/*
2412	 * Byte swap
2413	 */
2414	val = CSR_READ_4(sc, BWI_MAC_STATUS);
2415	if (val & BWI_MAC_STATUS_BSWAP) {
2416		DPRINTF(1, "%s: need byte swap\n", sc->sc_dev.dv_xname);
2417		mac->mac_flags |= BWI_MAC_F_BSWAP;
2418	}
2419
2420	/*
2421	 * DMA address space
2422	 */
2423	old_bus_space = sc->sc_bus_space;
2424
2425	val = CSR_READ_4(sc, BWI_STATE_HI);
2426	if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
2427	    BWI_STATE_HI_FLAG_64BIT) {
2428		/* 64bit address */
2429		sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
2430		DPRINTF(1, "%s: 64bit bus space\n", sc->sc_dev.dv_xname);
2431	} else {
2432		uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
2433
2434		CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
2435		if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
2436			/* 32bit address */
2437			sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
2438			DPRINTF(1, "%s: 32bit bus space\n",
2439			    sc->sc_dev.dv_xname);
2440		} else {
2441			/* 30bit address */
2442			sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
2443			DPRINTF(1, "%s: 30bit bus space\n",
2444			    sc->sc_dev.dv_xname);
2445		}
2446	}
2447
2448	if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
2449		printf("%s: MACs bus space mismatch!\n", sc->sc_dev.dv_xname);
2450		return (ENXIO);
2451	}
2452
2453	return (0);
2454}
2455
2456#define IEEE80211_DUR_SLOT	20	/* DS/CCK slottime, ERP long slottime */
2457#define IEEE80211_DUR_SHSLOT	9	/* ERP short slottime */
2458
2459void
2460bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
2461{
2462	struct bwi_softc *sc;
2463	uint16_t slot_time;
2464
2465	sc = mac->mac_sc;
2466
2467	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
2468
2469	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
2470		return;
2471
2472	if (shslot)
2473		slot_time = IEEE80211_DUR_SHSLOT;
2474	else
2475		slot_time = IEEE80211_DUR_SLOT;
2476
2477	CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
2478	    slot_time + BWI_MAC_SLOTTIME_ADJUST);
2479	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
2480}
2481
2482int
2483bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
2484{
2485	struct bwi_mac *mac;
2486	int i;
2487
2488	KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0);
2489
2490	if (sc->sc_nmac == BWI_MAC_MAX) {
2491		printf("%s: too many MACs\n", sc->sc_dev.dv_xname);
2492		return (0);
2493	}
2494
2495	/*
2496	 * More than one MAC is only supported by BCM4309
2497	 */
2498	if (sc->sc_nmac != 0 &&
2499	    sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) {
2500		DPRINTF(1, "%s: ignore second MAC\n", sc->sc_dev.dv_xname);
2501		return (0);
2502	}
2503
2504	mac = &sc->sc_mac[sc->sc_nmac];
2505
2506	/* XXX will this happen? */
2507	if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
2508		printf("%s: %dth MAC already attached\n",
2509		    sc->sc_dev.dv_xname, sc->sc_nmac);
2510		return (0);
2511	}
2512
2513	/*
2514	 * Test whether the revision of this MAC is supported
2515	 */
2516	for (i = 0; i < nitems(bwi_sup_macrev); ++i) {
2517		if (bwi_sup_macrev[i] == rev)
2518			break;
2519	}
2520	if (i == nitems(bwi_sup_macrev)) {
2521		printf("%s: MAC rev %u is not supported\n",
2522		    sc->sc_dev.dv_xname, rev);
2523		return (ENXIO);
2524	}
2525
2526	BWI_CREATE_MAC(mac, sc, id, rev);
2527	sc->sc_nmac++;
2528
2529	if (mac->mac_rev < 5) {
2530		mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
2531		DPRINTF(1, "%s: has TX stats\n", sc->sc_dev.dv_xname);
2532	} else {
2533		mac->mac_flags |= BWI_MAC_F_PHYE_RESET;
2534	}
2535
2536	return (0);
2537}
2538
2539void
2540bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
2541{
2542	int bbp_atten, rf_atten, rf_atten_lim = -1;
2543
2544	bbp_atten = *bbp_atten0;
2545	rf_atten = *rf_atten0;
2546
2547	/*
2548	 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
2549	 * as much as BBP attenuation, so we try our best to keep RF
2550	 * attenuation within range.  BBP attenuation will be clamped
2551	 * later if it is out of range during balancing.
2552	 *
2553	 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
2554	 */
2555
2556	/*
2557	 * Use BBP attenuation to balance RF attenuation
2558	 */
2559	if (rf_atten < 0)
2560		rf_atten_lim = 0;
2561	else if (rf_atten > BWI_RF_ATTEN_MAX0)
2562		rf_atten_lim = BWI_RF_ATTEN_MAX0;
2563
2564	if (rf_atten_lim >= 0) {
2565		bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
2566		rf_atten = rf_atten_lim;
2567	}
2568
2569	/*
2570	 * If possible, use RF attenuation to balance BBP attenuation
2571	 * NOTE: RF attenuation is still kept within range.
2572	 */
2573	while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
2574		bbp_atten -= BWI_RF_ATTEN_FACTOR;
2575		++rf_atten;
2576	}
2577	while (rf_atten > 0 && bbp_atten < 0) {
2578		bbp_atten += BWI_RF_ATTEN_FACTOR;
2579		--rf_atten;
2580	}
2581
2582	/* RF attenuation MUST be within range */
2583	KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0);
2584
2585	/*
2586	 * Clamp BBP attenuation
2587	 */
2588	if (bbp_atten < 0)
2589		bbp_atten = 0;
2590	else if (bbp_atten > BWI_BBP_ATTEN_MAX)
2591		bbp_atten = BWI_BBP_ATTEN_MAX;
2592
2593	*rf_atten0 = rf_atten;
2594	*bbp_atten0 = bbp_atten;
2595}
2596
2597void
2598bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
2599{
2600	struct bwi_softc *sc = mac->mac_sc;
2601	struct bwi_rf *rf = &mac->mac_rf;
2602	struct bwi_tpctl tpctl;
2603	int bbp_atten, rf_atten, tp_ctrl1;
2604
2605	bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
2606
2607	/* NOTE: Use signed value to do calculation */
2608	bbp_atten = tpctl.bbp_atten;
2609	rf_atten = tpctl.rf_atten;
2610	tp_ctrl1 = tpctl.tp_ctrl1;
2611
2612	bbp_atten += bbp_atten_adj;
2613	rf_atten += rf_atten_adj;
2614
2615	bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2616
2617	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
2618		if (rf_atten <= 1) {
2619			if (tp_ctrl1 == 0) {
2620				tp_ctrl1 = 3;
2621				bbp_atten += 2;
2622				rf_atten += 2;
2623			} else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
2624				bbp_atten +=
2625				(BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
2626				rf_atten = 2;
2627			}
2628		} else if (rf_atten > 4 && tp_ctrl1 != 0) {
2629			tp_ctrl1 = 0;
2630			if (bbp_atten < 3) {
2631				bbp_atten += 2;
2632				rf_atten -= 3;
2633			} else {
2634				bbp_atten -= 2;
2635				rf_atten -= 2;
2636			}
2637		}
2638		bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2639	}
2640
2641	tpctl.bbp_atten = bbp_atten;
2642	tpctl.rf_atten = rf_atten;
2643	tpctl.tp_ctrl1 = tp_ctrl1;
2644
2645	bwi_mac_lock(mac);
2646	bwi_mac_set_tpctl_11bg(mac, &tpctl);
2647	bwi_mac_unlock(mac);
2648}
2649
2650/*
2651 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
2652 */
2653void
2654bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type)
2655{
2656	struct bwi_softc *sc = mac->mac_sc;
2657	struct bwi_rf *rf = &mac->mac_rf;
2658	int8_t tssi[4], tssi_avg, cur_txpwr;
2659	int error, i, ofdm_tssi;
2660	int txpwr_diff, rf_atten_adj, bbp_atten_adj;
2661
2662	if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
2663		DPRINTF(1, "%s: tpctl error happened, can't set txpower\n",
2664		    sc->sc_dev.dv_xname);
2665		return;
2666	}
2667
2668	if (BWI_IS_BRCM_BU4306(sc)) {
2669		DPRINTF(1, "%s: BU4306, can't set txpower\n",
2670		    sc->sc_dev.dv_xname);
2671		return;
2672	}
2673
2674	/*
2675	 * Save latest TSSI and reset the related memory objects
2676	 */
2677	ofdm_tssi = 0;
2678	error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
2679	if (error) {
2680		DPRINTF(1, "%s: no DS tssi\n", sc->sc_dev.dv_xname);
2681
2682		if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) {
2683			if (type == BWI_TXPWR_FORCE) {
2684				rf_atten_adj = 0;
2685				bbp_atten_adj = 1;
2686				goto calib;
2687			} else {
2688				return;
2689			}
2690		}
2691
2692		error = bwi_rf_get_latest_tssi(mac, tssi,
2693		    BWI_COMM_MOBJ_TSSI_OFDM);
2694		if (error) {
2695			DPRINTF(1, "%s: no OFDM tssi\n", sc->sc_dev.dv_xname);
2696			if (type == BWI_TXPWR_FORCE) {
2697				rf_atten_adj = 0;
2698				bbp_atten_adj = 1;
2699				goto calib;
2700			} else {
2701				return;
2702			}
2703		}
2704
2705		for (i = 0; i < 4; ++i) {
2706			tssi[i] += 0x20;
2707			tssi[i] &= 0x3f;
2708		}
2709		ofdm_tssi = 1;
2710	}
2711	bwi_rf_clear_tssi(mac);
2712
2713	DPRINTF(1, "%s: tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
2714	    sc->sc_dev.dv_xname, tssi[0], tssi[1], tssi[2], tssi[3]);
2715
2716	/*
2717	 * Calculate RF/BBP attenuation adjustment based on
2718	 * the difference between desired TX power and sampled
2719	 * TX power.
2720	 */
2721	/* +8 == "each incremented by 1/2" */
2722	tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
2723	if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
2724		tssi_avg -= 13;
2725
2726	DPRINTF(1, "%s: tssi avg %d\n", sc->sc_dev.dv_xname, tssi_avg);
2727
2728	error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
2729	if (error)
2730		return;
2731	DPRINTF(1, "%s: current txpower %d\n", sc->sc_dev.dv_xname, cur_txpwr);
2732
2733	txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
2734
2735	rf_atten_adj = -howmany(txpwr_diff, 8);
2736
2737	if (type == BWI_TXPWR_INIT) {
2738		/*
2739		 * Move toward EEPROM max TX power as fast as we can
2740		 */
2741		bbp_atten_adj = -txpwr_diff;
2742	} else {
2743		bbp_atten_adj = -(txpwr_diff / 2);
2744	}
2745	bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
2746
2747	if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
2748		DPRINTF(1, "%s: no need to adjust RF/BBP attenuation\n",
2749		    sc->sc_dev.dv_xname);
2750		/* TODO: LO */
2751		return;
2752	}
2753
2754calib:
2755	DPRINTF(1, "%s: rf atten adjust %d, bbp atten adjust %d\n",
2756	    sc->sc_dev.dv_xname, rf_atten_adj, bbp_atten_adj);
2757	bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
2758	/* TODO: LO */
2759}
2760
2761void
2762bwi_mac_lock(struct bwi_mac *mac)
2763{
2764	struct bwi_softc *sc = mac->mac_sc;
2765
2766	KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0);
2767
2768	if (mac->mac_rev < 3)
2769		bwi_mac_stop(mac);
2770	else
2771#ifndef IEEE80211_STA_ONLY
2772	if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP)
2773#endif
2774		bwi_mac_config_ps(mac);
2775
2776	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
2777
2778	/* Flush pending bus write */
2779	CSR_READ_4(sc, BWI_MAC_STATUS);
2780	DELAY(10);
2781
2782	mac->mac_flags |= BWI_MAC_F_LOCKED;
2783}
2784
2785void
2786bwi_mac_unlock(struct bwi_mac *mac)
2787{
2788	struct bwi_softc *sc = mac->mac_sc;
2789
2790	KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED);
2791
2792	CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
2793
2794	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
2795
2796	if (mac->mac_rev < 3)
2797		bwi_mac_start(mac);
2798	else
2799#ifndef IEEE80211_STA_ONLY
2800	if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP)
2801#endif
2802		bwi_mac_config_ps(mac);
2803
2804	mac->mac_flags &= ~BWI_MAC_F_LOCKED;
2805}
2806
2807void
2808bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
2809{
2810	struct bwi_softc *sc = mac->mac_sc;
2811
2812	if (mac->mac_rev < 5) /* Promisc is always on */
2813		return;
2814
2815	if (promisc)
2816		CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
2817	else
2818		CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
2819}
2820
2821/* PHY */
2822
2823void
2824bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
2825{
2826	struct bwi_softc *sc = mac->mac_sc;
2827
2828	/* TODO: 11A */
2829	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
2830	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
2831}
2832
2833uint16_t
2834bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
2835{
2836	struct bwi_softc *sc = mac->mac_sc;
2837
2838	/* TODO: 11A */
2839	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
2840	return (CSR_READ_2(sc, BWI_PHY_DATA));
2841}
2842
2843int
2844bwi_phy_attach(struct bwi_mac *mac)
2845{
2846	struct bwi_softc *sc = mac->mac_sc;
2847	struct bwi_phy *phy = &mac->mac_phy;
2848	uint8_t phyrev, phytype, phyver;
2849	uint16_t val;
2850	int i;
2851
2852	/* Get PHY type/revision/version */
2853	val = CSR_READ_2(sc, BWI_PHYINFO);
2854	phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
2855	phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
2856	phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
2857	DPRINTF(1, "%s: PHY type %d, rev %d, ver %d\n",
2858	    sc->sc_dev.dv_xname, phytype, phyrev, phyver);
2859
2860	/*
2861	 * Verify whether the revision of the PHY type is supported
2862	 * Convert PHY type to ieee80211_phymode
2863	 */
2864	switch (phytype) {
2865	case BWI_PHYINFO_TYPE_11A:
2866		if (phyrev >= 4) {
2867			printf("%s: unsupported 11A PHY, rev %u\n",
2868			    sc->sc_dev.dv_xname, phyrev);
2869			return (ENXIO);
2870		}
2871		phy->phy_init = bwi_phy_init_11a;
2872		phy->phy_mode = IEEE80211_MODE_11A;
2873		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
2874		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
2875		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
2876		break;
2877	case BWI_PHYINFO_TYPE_11B:
2878		for (i = 0; i < nitems(bwi_sup_bphy); ++i) {
2879			if (phyrev == bwi_sup_bphy[i].rev) {
2880				phy->phy_init = bwi_sup_bphy[i].init;
2881				break;
2882			}
2883		}
2884		if (i == nitems(bwi_sup_bphy)) {
2885			printf("%s: unsupported 11B PHY, rev %u\n",
2886			    sc->sc_dev.dv_xname, phyrev);
2887			return (ENXIO);
2888		}
2889		phy->phy_mode = IEEE80211_MODE_11B;
2890		break;
2891	case BWI_PHYINFO_TYPE_11G:
2892		if (phyrev > 8) {
2893			printf("%s: unsupported 11G PHY, rev %u\n",
2894			    sc->sc_dev.dv_xname, phyrev);
2895			return (ENXIO);
2896		}
2897		phy->phy_init = bwi_phy_init_11g;
2898		phy->phy_mode = IEEE80211_MODE_11G;
2899		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
2900		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
2901		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
2902		break;
2903	default:
2904		printf("%s: unsupported PHY type %d\n",
2905		    sc->sc_dev.dv_xname, phytype);
2906		return (ENXIO);
2907	}
2908	phy->phy_rev = phyrev;
2909	phy->phy_version = phyver;
2910
2911	return (0);
2912}
2913
2914void
2915bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
2916{
2917	struct bwi_phy *phy = &mac->mac_phy;
2918	uint16_t mask = 0x000f;
2919
2920	if (phy->phy_version == 0) {
2921		CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
2922		    __SHIFTIN(bbp_atten, mask));
2923	} else {
2924		if (phy->phy_version > 1)
2925			mask <<= 2;
2926		else
2927			mask <<= 3;
2928		PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
2929		    __SHIFTIN(bbp_atten, mask));
2930	}
2931}
2932
2933int
2934bwi_phy_calibrate(struct bwi_mac *mac)
2935{
2936	struct bwi_phy *phy = &mac->mac_phy;
2937
2938	/* Dummy read */
2939	CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
2940
2941	/* Don't re-init */
2942	if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
2943		return (0);
2944
2945	if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
2946		bwi_mac_reset(mac, 0);
2947		bwi_phy_init_11g(mac);
2948		bwi_mac_reset(mac, 1);
2949	}
2950
2951	phy->phy_flags |= BWI_PHY_F_CALIBRATED;
2952
2953	return (0);
2954}
2955
2956void
2957bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
2958{
2959	struct bwi_phy *phy = &mac->mac_phy;
2960
2961	KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0);
2962	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
2963	PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
2964}
2965
2966void
2967bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
2968{
2969	struct bwi_phy *phy = &mac->mac_phy;
2970
2971	KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
2972	    phy->phy_tbl_ctrl != 0);
2973
2974	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
2975	PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
2976	PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
2977}
2978
2979void
2980bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
2981{
2982	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
2983	PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
2984}
2985
2986int16_t
2987bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
2988{
2989	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
2990	return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA));
2991}
2992
2993void
2994bwi_phy_init_11a(struct bwi_mac *mac)
2995{
2996	/* TODO: 11A */
2997}
2998
2999void
3000bwi_phy_init_11g(struct bwi_mac *mac)
3001{
3002	struct bwi_softc *sc = mac->mac_sc;
3003	struct bwi_phy *phy = &mac->mac_phy;
3004	struct bwi_rf *rf = &mac->mac_rf;
3005	const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
3006
3007	if (phy->phy_rev == 1)
3008		bwi_phy_init_11b_rev5(mac);
3009	else
3010		bwi_phy_init_11b_rev6(mac);
3011
3012	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
3013		bwi_phy_config_11g(mac);
3014
3015	if (phy->phy_rev >= 2) {
3016		PHY_WRITE(mac, 0x814, 0);
3017		PHY_WRITE(mac, 0x815, 0);
3018
3019		if (phy->phy_rev == 2) {
3020			PHY_WRITE(mac, 0x811, 0);
3021			PHY_WRITE(mac, 0x15, 0xc0);
3022		} else if (phy->phy_rev > 5) {
3023			PHY_WRITE(mac, 0x811, 0x400);
3024			PHY_WRITE(mac, 0x15, 0xc0);
3025		}
3026	}
3027
3028	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
3029		uint16_t val;
3030
3031		val = PHY_READ(mac, 0x400) & 0xff;
3032		if (val == 3 || val == 5) {
3033			PHY_WRITE(mac, 0x4c2, 0x1816);
3034			PHY_WRITE(mac, 0x4c3, 0x8006);
3035			if (val == 5) {
3036				PHY_FILT_SETBITS(mac, 0x4cc,
3037						 0xff, 0x1f00);
3038			}
3039		}
3040	}
3041
3042	if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
3043	    phy->phy_rev >= 2)
3044		PHY_WRITE(mac, 0x47e, 0x78);
3045
3046	if (rf->rf_rev == 8) {
3047		PHY_SETBITS(mac, 0x801, 0x80);
3048		PHY_SETBITS(mac, 0x43e, 0x4);
3049	}
3050
3051	if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
3052		bwi_rf_get_gains(mac);
3053
3054	if (rf->rf_rev != 8)
3055		bwi_rf_init(mac);
3056
3057	if (tpctl->tp_ctrl2 == 0xffff) {
3058		bwi_rf_lo_update(mac);
3059	} else {
3060		if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
3061			RF_WRITE(mac, 0x52,
3062			    (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
3063		} else {
3064			RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
3065		}
3066
3067		if (phy->phy_rev >= 6) {
3068			PHY_FILT_SETBITS(mac, 0x36, 0xfff,
3069			    tpctl->tp_ctrl2 << 12);
3070		}
3071
3072		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
3073			PHY_WRITE(mac, 0x2e, 0x8075);
3074		else
3075			PHY_WRITE(mac, 0x2e, 0x807f);
3076
3077		if (phy->phy_rev < 2)
3078			PHY_WRITE(mac, 0x2f, 0x101);
3079		else
3080			PHY_WRITE(mac, 0x2f, 0x202);
3081	}
3082
3083	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3084		bwi_rf_lo_adjust(mac, tpctl);
3085		PHY_WRITE(mac, 0x80f, 0x8078);
3086	}
3087
3088	if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
3089		bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
3090		bwi_rf_set_nrssi_thr(mac);
3091	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3092		if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
3093			KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI);
3094			bwi_rf_calc_nrssi_slope(mac);
3095		} else {
3096			KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI);
3097			bwi_rf_set_nrssi_thr(mac);
3098		}
3099	}
3100
3101	if (rf->rf_rev == 8)
3102		PHY_WRITE(mac, 0x805, 0x3230);
3103
3104	bwi_mac_init_tpctl_11bg(mac);
3105
3106	if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
3107		PHY_CLRBITS(mac, 0x429, 0x4000);
3108		PHY_CLRBITS(mac, 0x4c3, 0x8000);
3109	}
3110}
3111
3112void
3113bwi_phy_init_11b_rev2(struct bwi_mac *mac)
3114{
3115	struct bwi_softc *sc;
3116
3117	sc = mac->mac_sc;
3118
3119	/* TODO: 11B */
3120	printf("%s: %s is not implemented yet\n",
3121	    sc->sc_dev.dv_xname, __func__);
3122}
3123
3124void
3125bwi_phy_init_11b_rev4(struct bwi_mac *mac)
3126{
3127	struct bwi_softc *sc = mac->mac_sc;
3128	struct bwi_rf *rf = &mac->mac_rf;
3129	uint16_t val, ofs;
3130	u_int chan;
3131
3132	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
3133
3134	PHY_WRITE(mac, 0x20, 0x301c);
3135	PHY_WRITE(mac, 0x26, 0);
3136	PHY_WRITE(mac, 0x30, 0xc6);
3137	PHY_WRITE(mac, 0x88, 0x3e00);
3138
3139	for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
3140		PHY_WRITE(mac, 0x89 + ofs, val);
3141
3142	CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
3143
3144	chan = rf->rf_curchan;
3145	if (chan == IEEE80211_CHAN_ANY)
3146		chan = 6;	/* Force to channel 6 */
3147	bwi_rf_set_chan(mac, chan, 0);
3148
3149	if (rf->rf_type != BWI_RF_T_BCM2050) {
3150		RF_WRITE(mac, 0x75, 0x80);
3151		RF_WRITE(mac, 0x79, 0x81);
3152	}
3153
3154	RF_WRITE(mac, 0x50, 0x20);
3155	RF_WRITE(mac, 0x50, 0x23);
3156
3157	if (rf->rf_type == BWI_RF_T_BCM2050) {
3158		RF_WRITE(mac, 0x50, 0x20);
3159		RF_WRITE(mac, 0x5a, 0x70);
3160		RF_WRITE(mac, 0x5b, 0x7b);
3161		RF_WRITE(mac, 0x5c, 0xb0);
3162		RF_WRITE(mac, 0x7a, 0xf);
3163		PHY_WRITE(mac, 0x38, 0x677);
3164		bwi_rf_init_bcm2050(mac);
3165	}
3166
3167	PHY_WRITE(mac, 0x14, 0x80);
3168	PHY_WRITE(mac, 0x32, 0xca);
3169	if (rf->rf_type == BWI_RF_T_BCM2050)
3170		PHY_WRITE(mac, 0x32, 0xe0);
3171	PHY_WRITE(mac, 0x35, 0x7c2);
3172
3173	bwi_rf_lo_update(mac);
3174
3175	PHY_WRITE(mac, 0x26, 0xcc00);
3176	if (rf->rf_type == BWI_RF_T_BCM2050)
3177		PHY_WRITE(mac, 0x26, 0xce00);
3178
3179	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
3180
3181	PHY_WRITE(mac, 0x2a, 0x88a3);
3182	if (rf->rf_type == BWI_RF_T_BCM2050)
3183		PHY_WRITE(mac, 0x2a, 0x88c2);
3184
3185	bwi_mac_set_tpctl_11bg(mac, NULL);
3186	if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
3187		bwi_rf_calc_nrssi_slope(mac);
3188		bwi_rf_set_nrssi_thr(mac);
3189	}
3190	bwi_mac_init_tpctl_11bg(mac);
3191}
3192
3193void
3194bwi_phy_init_11b_rev5(struct bwi_mac *mac)
3195{
3196	struct bwi_softc *sc = mac->mac_sc;
3197	struct bwi_rf *rf = &mac->mac_rf;
3198	struct bwi_phy *phy = &mac->mac_phy;
3199	uint orig_chan;
3200
3201	if (phy->phy_version == 1)
3202		RF_SETBITS(mac, 0x7a, 0x50);
3203
3204	if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
3205	    sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
3206		uint16_t ofs, val;
3207
3208		val = 0x2120;
3209		for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
3210			PHY_WRITE(mac, ofs, val);
3211			val += 0x202;
3212		}
3213	}
3214
3215	PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
3216
3217	if (rf->rf_type == BWI_RF_T_BCM2050)
3218		PHY_WRITE(mac, 0x38, 0x667);
3219
3220	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3221		if (rf->rf_type == BWI_RF_T_BCM2050) {
3222			RF_SETBITS(mac, 0x7a, 0x20);
3223			RF_SETBITS(mac, 0x51, 0x4);
3224		}
3225
3226		CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
3227
3228		PHY_SETBITS(mac, 0x802, 0x100);
3229		PHY_SETBITS(mac, 0x42b, 0x2000);
3230		PHY_WRITE(mac, 0x1c, 0x186a);
3231
3232		PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
3233		PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
3234		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
3235	}
3236
3237	/* TODO: bad_frame_preempt? */
3238
3239	if (phy->phy_version == 1) {
3240	    	PHY_WRITE(mac, 0x26, 0xce00);
3241		PHY_WRITE(mac, 0x21, 0x3763);
3242		PHY_WRITE(mac, 0x22, 0x1bc3);
3243		PHY_WRITE(mac, 0x23, 0x6f9);
3244		PHY_WRITE(mac, 0x24, 0x37e);
3245	} else
3246		PHY_WRITE(mac, 0x26, 0xcc00);
3247	PHY_WRITE(mac, 0x30, 0xc6);
3248
3249	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
3250
3251	if (phy->phy_version == 1)
3252		PHY_WRITE(mac, 0x20, 0x3e1c);
3253	else
3254		PHY_WRITE(mac, 0x20, 0x301c);
3255
3256	if (phy->phy_version == 0)
3257		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
3258
3259	/* Force to channel 7 */
3260	orig_chan = rf->rf_curchan;
3261	bwi_rf_set_chan(mac, 7, 0);
3262
3263	if (rf->rf_type != BWI_RF_T_BCM2050) {
3264		RF_WRITE(mac, 0x75, 0x80);
3265		RF_WRITE(mac, 0x79, 0x81);
3266	}
3267
3268	RF_WRITE(mac, 0x50, 0x20);
3269	RF_WRITE(mac, 0x50, 0x23);
3270
3271	if (rf->rf_type == BWI_RF_T_BCM2050) {
3272		RF_WRITE(mac, 0x50, 0x20);
3273		RF_WRITE(mac, 0x5a, 0x70);
3274	}
3275
3276	RF_WRITE(mac, 0x5b, 0x7b);
3277	RF_WRITE(mac, 0x5c, 0xb0);
3278	RF_SETBITS(mac, 0x7a, 0x7);
3279
3280	bwi_rf_set_chan(mac, orig_chan, 0);
3281
3282	PHY_WRITE(mac, 0x14, 0x80);
3283	PHY_WRITE(mac, 0x32, 0xca);
3284	PHY_WRITE(mac, 0x2a, 0x88a3);
3285
3286	bwi_mac_set_tpctl_11bg(mac, NULL);
3287
3288	if (rf->rf_type == BWI_RF_T_BCM2050)
3289		RF_WRITE(mac, 0x5d, 0xd);
3290
3291	CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
3292}
3293
3294void
3295bwi_phy_init_11b_rev6(struct bwi_mac *mac)
3296{
3297	struct bwi_softc *sc = mac->mac_sc;
3298	struct bwi_rf *rf = &mac->mac_rf;
3299	struct bwi_phy *phy = &mac->mac_phy;
3300	uint16_t val, ofs;
3301	uint orig_chan;
3302
3303	PHY_WRITE(mac, 0x3e, 0x817a);
3304	RF_SETBITS(mac, 0x7a, 0x58);
3305
3306	if (rf->rf_rev == 4 || rf->rf_rev == 5) {
3307		RF_WRITE(mac, 0x51, 0x37);
3308		RF_WRITE(mac, 0x52, 0x70);
3309		RF_WRITE(mac, 0x53, 0xb3);
3310		RF_WRITE(mac, 0x54, 0x9b);
3311		RF_WRITE(mac, 0x5a, 0x88);
3312		RF_WRITE(mac, 0x5b, 0x88);
3313		RF_WRITE(mac, 0x5d, 0x88);
3314		RF_WRITE(mac, 0x5e, 0x88);
3315		RF_WRITE(mac, 0x7d, 0x88);
3316		HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
3317	} else if (rf->rf_rev == 8) {
3318		RF_WRITE(mac, 0x51, 0);
3319		RF_WRITE(mac, 0x52, 0x40);
3320		RF_WRITE(mac, 0x53, 0xb7);
3321		RF_WRITE(mac, 0x54, 0x98);
3322		RF_WRITE(mac, 0x5a, 0x88);
3323		RF_WRITE(mac, 0x5b, 0x6b);
3324		RF_WRITE(mac, 0x5c, 0xf);
3325		if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
3326			RF_WRITE(mac, 0x5d, 0xfa);
3327			RF_WRITE(mac, 0x5e, 0xd8);
3328		} else {
3329			RF_WRITE(mac, 0x5d, 0xf5);
3330			RF_WRITE(mac, 0x5e, 0xb8);
3331		}
3332		RF_WRITE(mac, 0x73, 0x3);
3333		RF_WRITE(mac, 0x7d, 0xa8);
3334		RF_WRITE(mac, 0x7c, 0x1);
3335		RF_WRITE(mac, 0x7e, 0x8);
3336	}
3337
3338	val = 0x1e1f;
3339	for (ofs = 0x88; ofs < 0x98; ++ofs) {
3340		PHY_WRITE(mac, ofs, val);
3341		val -= 0x202;
3342	}
3343
3344	val = 0x3e3f;
3345	for (ofs = 0x98; ofs < 0xa8; ++ofs) {
3346		PHY_WRITE(mac, ofs, val);
3347		val -= 0x202;
3348	}
3349
3350	val = 0x2120;
3351	for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
3352		PHY_WRITE(mac, ofs, (val & 0x3f3f));
3353		val += 0x202;
3354
3355		/* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */
3356		DELAY(10);
3357	}
3358
3359	if (phy->phy_mode == IEEE80211_MODE_11G) {
3360		RF_SETBITS(mac, 0x7a, 0x20);
3361		RF_SETBITS(mac, 0x51, 0x4);
3362		PHY_SETBITS(mac, 0x802, 0x100);
3363		PHY_SETBITS(mac, 0x42b, 0x2000);
3364		PHY_WRITE(mac, 0x5b, 0);
3365		PHY_WRITE(mac, 0x5c, 0);
3366	}
3367
3368	/* Force to channel 7 */
3369	orig_chan = rf->rf_curchan;
3370	if (orig_chan >= 8)
3371		bwi_rf_set_chan(mac, 1, 0);
3372	else
3373		bwi_rf_set_chan(mac, 13, 0);
3374
3375	RF_WRITE(mac, 0x50, 0x20);
3376	RF_WRITE(mac, 0x50, 0x23);
3377
3378	DELAY(40);
3379
3380	if (rf->rf_rev < 6 || rf->rf_rev == 8) {
3381		RF_SETBITS(mac, 0x7c, 0x2);
3382		RF_WRITE(mac, 0x50, 0x20);
3383	}
3384	if (rf->rf_rev <= 2) {
3385		RF_WRITE(mac, 0x7c, 0x20);
3386		RF_WRITE(mac, 0x5a, 0x70);
3387		RF_WRITE(mac, 0x5b, 0x7b);
3388		RF_WRITE(mac, 0x5c, 0xb0);
3389	}
3390
3391	RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
3392
3393	bwi_rf_set_chan(mac, orig_chan, 0);
3394
3395	PHY_WRITE(mac, 0x14, 0x200);
3396	if (rf->rf_rev >= 6)
3397		PHY_WRITE(mac, 0x2a, 0x88c2);
3398	else
3399		PHY_WRITE(mac, 0x2a, 0x8ac0);
3400	PHY_WRITE(mac, 0x38, 0x668);
3401
3402	bwi_mac_set_tpctl_11bg(mac, NULL);
3403
3404	if (rf->rf_rev <= 5) {
3405		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
3406		if (rf->rf_rev <= 2)
3407			RF_WRITE(mac, 0x5d, 0xd);
3408	}
3409
3410	if (phy->phy_version == 4) {
3411		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
3412		PHY_CLRBITS(mac, 0x61, 0xf000);
3413	} else {
3414		PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
3415	}
3416
3417	if (phy->phy_mode == IEEE80211_MODE_11B) {
3418		CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
3419		PHY_WRITE(mac, 0x16, 0x410);
3420		PHY_WRITE(mac, 0x17, 0x820);
3421		PHY_WRITE(mac, 0x62, 0x7);
3422
3423		bwi_rf_init_bcm2050(mac);
3424		bwi_rf_lo_update(mac);
3425		if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
3426			bwi_rf_calc_nrssi_slope(mac);
3427			bwi_rf_set_nrssi_thr(mac);
3428		}
3429		bwi_mac_init_tpctl_11bg(mac);
3430	} else
3431		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
3432}
3433
3434void
3435bwi_phy_config_11g(struct bwi_mac *mac)
3436{
3437	struct bwi_softc *sc = mac->mac_sc;
3438	struct bwi_phy *phy = &mac->mac_phy;
3439	const uint16_t *tbl;
3440	uint16_t wrd_ofs1, wrd_ofs2;
3441	int i, n;
3442
3443	if (phy->phy_rev == 1) {
3444		PHY_WRITE(mac, 0x406, 0x4f19);
3445		PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
3446		PHY_WRITE(mac, 0x42c, 0x5a);
3447		PHY_WRITE(mac, 0x427, 0x1a);
3448
3449		/* Fill frequency table */
3450		for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) {
3451			bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
3452			    bwi_phy_freq_11g_rev1[i]);
3453		}
3454
3455		/* Fill noise table */
3456		for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) {
3457			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3458			    bwi_phy_noise_11g_rev1[i]);
3459		}
3460
3461		/* Fill rotor table */
3462		for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) {
3463			/* NB: data length is 4 bytes */
3464			bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
3465			    bwi_phy_rotor_11g_rev1[i]);
3466		}
3467	} else {
3468		bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
3469
3470		if (phy->phy_rev == 2) {
3471			PHY_WRITE(mac, 0x4c0, 0x1861);
3472			PHY_WRITE(mac, 0x4c1, 0x271);
3473		} else if (phy->phy_rev > 2) {
3474			PHY_WRITE(mac, 0x4c0, 0x98);
3475			PHY_WRITE(mac, 0x4c1, 0x70);
3476			PHY_WRITE(mac, 0x4c9, 0x80);
3477		}
3478		PHY_SETBITS(mac, 0x42b, 0x800);
3479
3480		/* Fill RSSI table */
3481		for (i = 0; i < 64; ++i)
3482			bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
3483
3484		/* Fill noise table */
3485		for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) {
3486			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3487			    bwi_phy_noise_11g[i]);
3488		}
3489	}
3490
3491	/*
3492	 * Fill noise scale table
3493	 */
3494	if (phy->phy_rev <= 2) {
3495		tbl = bwi_phy_noise_scale_11g_rev2;
3496		n = nitems(bwi_phy_noise_scale_11g_rev2);
3497	} else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
3498		tbl = bwi_phy_noise_scale_11g_rev7;
3499		n = nitems(bwi_phy_noise_scale_11g_rev7);
3500	} else {
3501		tbl = bwi_phy_noise_scale_11g;
3502		n = nitems(bwi_phy_noise_scale_11g);
3503	}
3504	for (i = 0; i < n; ++i)
3505		bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
3506
3507	/*
3508	 * Fill sigma square table
3509	 */
3510	if (phy->phy_rev == 2) {
3511		tbl = bwi_phy_sigma_sq_11g_rev2;
3512		n = nitems(bwi_phy_sigma_sq_11g_rev2);
3513	} else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
3514		tbl = bwi_phy_sigma_sq_11g_rev7;
3515		n = nitems(bwi_phy_sigma_sq_11g_rev7);
3516	} else {
3517		tbl = NULL;
3518		n = 0;
3519	}
3520	for (i = 0; i < n; ++i)
3521		bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
3522
3523	if (phy->phy_rev == 1) {
3524		/* Fill delay table */
3525		for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) {
3526			bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
3527			    bwi_phy_delay_11g_rev1[i]);
3528		}
3529
3530		/* Fill WRSSI (Wide-Band RSSI) table */
3531		for (i = 4; i < 20; ++i)
3532			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
3533
3534		bwi_phy_config_agc(mac);
3535
3536		wrd_ofs1 = 0x5001;
3537		wrd_ofs2 = 0x5002;
3538	} else {
3539		/* Fill WRSSI (Wide-Band RSSI) table */
3540		for (i = 0; i < 0x20; ++i)
3541			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
3542
3543		bwi_phy_config_agc(mac);
3544
3545		PHY_READ(mac, 0x400);	/* Dummy read */
3546		PHY_WRITE(mac, 0x403, 0x1000);
3547		bwi_tbl_write_2(mac, 0x3c02, 0xf);
3548		bwi_tbl_write_2(mac, 0x3c03, 0x14);
3549
3550		wrd_ofs1 = 0x401;
3551		wrd_ofs2 = 0x402;
3552	}
3553
3554	if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
3555		bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
3556		bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
3557	}
3558
3559	/* phy->phy_flags & BWI_PHY_F_LINKED ? */
3560	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
3561		PHY_WRITE(mac, 0x46e, 0x3cf);
3562}
3563#undef N
3564
3565/*
3566 * Configure Automatic Gain Controller
3567 */
3568void
3569bwi_phy_config_agc(struct bwi_mac *mac)
3570{
3571	struct bwi_phy *phy = &mac->mac_phy;
3572	uint16_t ofs;
3573
3574	ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
3575
3576	bwi_tbl_write_2(mac, ofs, 0xfe);
3577	bwi_tbl_write_2(mac, ofs + 1, 0xd);
3578	bwi_tbl_write_2(mac, ofs + 2, 0x13);
3579	bwi_tbl_write_2(mac, ofs + 3, 0x19);
3580
3581	if (phy->phy_rev == 1) {
3582		bwi_tbl_write_2(mac, 0x1800, 0x2710);
3583		bwi_tbl_write_2(mac, 0x1801, 0x9b83);
3584		bwi_tbl_write_2(mac, 0x1802, 0x9b83);
3585		bwi_tbl_write_2(mac, 0x1803, 0xf8d);
3586		PHY_WRITE(mac, 0x455, 0x4);
3587	}
3588
3589	PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
3590	PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
3591	PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
3592	PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
3593
3594	RF_SETBITS(mac, 0x7a, 0x8);
3595
3596	PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
3597	PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
3598	PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
3599	PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
3600
3601	if (phy->phy_rev == 1)
3602		PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
3603
3604	PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
3605	PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
3606	PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
3607	PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
3608	PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
3609	PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
3610	PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
3611	PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
3612	PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
3613
3614	if (phy->phy_rev == 1) {
3615		PHY_WRITE(mac, 0x430, 0x92b);
3616		PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
3617	} else {
3618		PHY_CLRBITS(mac, 0x41b, 0x1e);
3619		PHY_WRITE(mac, 0x41f, 0x287a);
3620		PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
3621
3622		if (phy->phy_rev >= 6) {
3623			PHY_WRITE(mac, 0x422, 0x287a);
3624			PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
3625		}
3626	}
3627
3628	PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
3629	PHY_WRITE(mac, 0x48e, 0x1c00);
3630
3631	if (phy->phy_rev == 1) {
3632		PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
3633		PHY_WRITE(mac, 0x48b, 0x5e);
3634		PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
3635		PHY_WRITE(mac, 0x48d, 0x2);
3636	}
3637
3638	bwi_tbl_write_2(mac, ofs + 0x800, 0);
3639	bwi_tbl_write_2(mac, ofs + 0x801, 7);
3640	bwi_tbl_write_2(mac, ofs + 0x802, 16);
3641	bwi_tbl_write_2(mac, ofs + 0x803, 28);
3642
3643	if (phy->phy_rev >= 6) {
3644		PHY_CLRBITS(mac, 0x426, 0x3);
3645		PHY_CLRBITS(mac, 0x426, 0x1000);
3646	}
3647}
3648
3649void
3650bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
3651{
3652	struct bwi_phy *phy = &mac->mac_phy;
3653	uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
3654	int i;
3655
3656	if (phy->phy_rev <= 1) {
3657		tbl_gain_ofs1 = 0x5000;
3658		tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
3659	} else {
3660		tbl_gain_ofs1 = 0x400;
3661		tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
3662	}
3663
3664	for (i = 0; i < 4; ++i) {
3665		if (gains != NULL) {
3666			tbl_gain = gains->tbl_gain1;
3667		} else {
3668			/* Bit swap */
3669			tbl_gain = (i & 0x1) << 1;
3670			tbl_gain |= (i & 0x2) >> 1;
3671		}
3672		bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
3673	}
3674
3675	for (i = 0; i < 16; ++i) {
3676		if (gains != NULL)
3677			tbl_gain = gains->tbl_gain2;
3678		else
3679			tbl_gain = i;
3680		bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
3681	}
3682
3683	if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
3684		uint16_t phy_gain1, phy_gain2;
3685
3686		if (gains != NULL) {
3687			phy_gain1 =
3688			((uint16_t)gains->phy_gain << 14) |
3689			((uint16_t)gains->phy_gain << 6);
3690			phy_gain2 = phy_gain1;
3691		} else {
3692			phy_gain1 = 0x4040;
3693			phy_gain2 = 0x4000;
3694		}
3695		PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
3696		PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
3697		PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
3698	}
3699	bwi_mac_dummy_xmit(mac);
3700}
3701
3702void
3703bwi_phy_clear_state(struct bwi_phy *phy)
3704{
3705	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
3706}
3707
3708/* RF */
3709
3710int16_t
3711bwi_nrssi_11g(struct bwi_mac *mac)
3712{
3713	int16_t val;
3714
3715#define NRSSI_11G_MASK		0x3f00
3716	val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
3717	if (val >= 32)
3718		val -= 64;
3719
3720	return (val);
3721#undef NRSSI_11G_MASK
3722}
3723
3724struct bwi_rf_lo *
3725bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
3726{
3727	int n;
3728
3729	n = rf_atten + (14 * (bbp_atten / 2));
3730	KASSERT(n < BWI_RFLO_MAX);
3731
3732	return (&mac->mac_rf.rf_lo[n]);
3733}
3734
3735int
3736bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
3737{
3738	struct bwi_rf *rf = &mac->mac_rf;
3739	int idx;
3740
3741	idx = lo - rf->rf_lo;
3742	KASSERT(idx >= 0 && idx < BWI_RFLO_MAX);
3743
3744	return (isset(rf->rf_lo_used, idx));
3745}
3746
3747void
3748bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
3749{
3750	struct bwi_softc *sc = mac->mac_sc;
3751
3752	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3753	CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
3754}
3755
3756uint16_t
3757bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
3758{
3759	struct bwi_rf *rf = &mac->mac_rf;
3760	struct bwi_softc *sc = mac->mac_sc;
3761
3762	ctrl |= rf->rf_ctrl_rd;
3763	if (rf->rf_ctrl_adj) {
3764		/* XXX */
3765		if (ctrl < 0x70)
3766			ctrl += 0x80;
3767		else if (ctrl < 0x80)
3768			ctrl += 0x70;
3769	}
3770
3771	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3772	return (CSR_READ_2(sc, BWI_RF_DATA_LO));
3773}
3774
3775int
3776bwi_rf_attach(struct bwi_mac *mac)
3777{
3778	struct bwi_softc *sc = mac->mac_sc;
3779	struct bwi_phy *phy = &mac->mac_phy;
3780	struct bwi_rf *rf = &mac->mac_rf;
3781	uint16_t type, manu;
3782	uint8_t rev;
3783
3784	/*
3785	 * Get RF manufacture/type/revision
3786	 */
3787	if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
3788		/*
3789		 * Fake a BCM2050 RF
3790		 */
3791		manu = BWI_RF_MANUFACT_BCM;
3792		type = BWI_RF_T_BCM2050;
3793		if (sc->sc_bbp_rev == 0)
3794			rev = 3;
3795		else if (sc->sc_bbp_rev == 1)
3796			rev = 4;
3797		else
3798			rev = 5;
3799	} else {
3800		uint32_t val;
3801
3802		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
3803		val = CSR_READ_2(sc, BWI_RF_DATA_HI);
3804		val <<= 16;
3805
3806		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
3807		val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
3808
3809		manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
3810		type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
3811		rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
3812	}
3813	DPRINTF(1, "%s: RF manu 0x%03x, type 0x%04x, rev %u\n",
3814	    sc->sc_dev.dv_xname, manu, type, rev);
3815
3816	/*
3817	 * Verify whether the RF is supported
3818	 */
3819	rf->rf_ctrl_rd = 0;
3820	rf->rf_ctrl_adj = 0;
3821	switch (phy->phy_mode) {
3822	case IEEE80211_MODE_11A:
3823		if (manu != BWI_RF_MANUFACT_BCM ||
3824		    type != BWI_RF_T_BCM2060 ||
3825		    rev != 1) {
3826			printf("%s: only BCM2060 rev 1 RF is supported for "
3827			    "11A PHY\n", sc->sc_dev.dv_xname);
3828			return (ENXIO);
3829		}
3830		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
3831		rf->rf_on = bwi_rf_on_11a;
3832		rf->rf_off = bwi_rf_off_11a;
3833		rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
3834		break;
3835	case IEEE80211_MODE_11B:
3836		if (type == BWI_RF_T_BCM2050) {
3837			rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
3838			rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
3839		} else if (type == BWI_RF_T_BCM2053) {
3840			rf->rf_ctrl_adj = 1;
3841			rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
3842		} else {
3843			printf("%s: only BCM2050/BCM2053 RF is supported "
3844			    "for supported for 11B PHY\n", sc->sc_dev.dv_xname);
3845			return (ENXIO);
3846		}
3847		rf->rf_on = bwi_rf_on_11bg;
3848		rf->rf_off = bwi_rf_off_11bg;
3849		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
3850		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
3851		if (phy->phy_rev == 6)
3852			rf->rf_lo_update = bwi_rf_lo_update_11g;
3853		else
3854			rf->rf_lo_update = bwi_rf_lo_update_11b;
3855		break;
3856	case IEEE80211_MODE_11G:
3857		if (type != BWI_RF_T_BCM2050) {
3858			printf("%s: only BCM2050 RF is supported for 11G "
3859			    "PHY\n", sc->sc_dev.dv_xname);
3860			return (ENXIO);
3861		}
3862		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
3863		rf->rf_on = bwi_rf_on_11bg;
3864		if (mac->mac_rev >= 5)
3865			rf->rf_off = bwi_rf_off_11g_rev5;
3866		else
3867			rf->rf_off = bwi_rf_off_11bg;
3868		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
3869		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
3870		rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
3871		rf->rf_lo_update = bwi_rf_lo_update_11g;
3872		break;
3873	default:
3874		printf("%s: unsupported PHY mode\n", sc->sc_dev.dv_xname);
3875		return (ENXIO);
3876	}
3877
3878	rf->rf_type = type;
3879	rf->rf_rev = rev;
3880	rf->rf_manu = manu;
3881	rf->rf_curchan = IEEE80211_CHAN_ANY;
3882	rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
3883
3884	return (0);
3885}
3886
3887void
3888bwi_rf_set_chan(struct bwi_mac *mac, uint chan, int work_around)
3889{
3890	struct bwi_softc *sc = mac->mac_sc;
3891
3892	if (chan == IEEE80211_CHAN_ANY)
3893		return;
3894
3895	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
3896
3897	/* TODO: 11A */
3898
3899	if (work_around)
3900		bwi_rf_workaround(mac, chan);
3901
3902	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
3903
3904	if (chan == 14) {
3905		if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
3906			HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
3907		else
3908			HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
3909		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
3910	} else {
3911		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
3912	}
3913	DELAY(8000);	/* DELAY(2000); */
3914
3915	mac->mac_rf.rf_curchan = chan;
3916}
3917
3918void
3919bwi_rf_get_gains(struct bwi_mac *mac)
3920{
3921#define SAVE_PHY_MAX	15
3922#define SAVE_RF_MAX	3
3923	struct bwi_softc *sc;
3924	struct bwi_phy *phy = &mac->mac_phy;
3925	struct bwi_rf *rf = &mac->mac_rf;
3926	uint16_t save_phy[SAVE_PHY_MAX];
3927	uint16_t save_rf[SAVE_RF_MAX];
3928	uint16_t trsw;
3929	int i, j, loop1_max, loop1, loop2;
3930
3931	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
3932	    { 0x52, 0x43, 0x7a };
3933	static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
3934	    0x0429, 0x0001, 0x0811, 0x0812,
3935	    0x0814, 0x0815, 0x005a, 0x0059,
3936	    0x0058, 0x000a, 0x0003, 0x080f,
3937	    0x0810, 0x002b, 0x0015
3938	};
3939
3940	sc = mac->mac_sc;
3941
3942	/*
3943	 * Save PHY/RF registers for later restoration
3944	 */
3945	for (i = 0; i < SAVE_PHY_MAX; ++i)
3946		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
3947	PHY_READ(mac, 0x2d); /* dummy read */
3948
3949	for (i = 0; i < SAVE_RF_MAX; ++i)
3950		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
3951
3952	PHY_CLRBITS(mac, 0x429, 0xc000);
3953	PHY_SETBITS(mac, 0x1, 0x8000);
3954
3955	PHY_SETBITS(mac, 0x811, 0x2);
3956	PHY_CLRBITS(mac, 0x812, 0x2);
3957	PHY_SETBITS(mac, 0x811, 0x1);
3958	PHY_CLRBITS(mac, 0x812, 0x1);
3959
3960	PHY_SETBITS(mac, 0x814, 0x1);
3961	PHY_CLRBITS(mac, 0x815, 0x1);
3962	PHY_SETBITS(mac, 0x814, 0x2);
3963	PHY_CLRBITS(mac, 0x815, 0x2);
3964
3965	PHY_SETBITS(mac, 0x811, 0xc);
3966	PHY_SETBITS(mac, 0x812, 0xc);
3967	PHY_SETBITS(mac, 0x811, 0x30);
3968	PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
3969
3970	PHY_WRITE(mac, 0x5a, 0x780);
3971	PHY_WRITE(mac, 0x59, 0xc810);
3972	PHY_WRITE(mac, 0x58, 0xd);
3973	PHY_SETBITS(mac, 0xa, 0x2000);
3974
3975	PHY_SETBITS(mac, 0x814, 0x4);
3976	PHY_CLRBITS(mac, 0x815, 0x4);
3977
3978	PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
3979
3980	if (rf->rf_rev == 8) {
3981		loop1_max = 15;
3982		RF_WRITE(mac, 0x43, loop1_max);
3983	} else {
3984		loop1_max = 9;
3985	    	RF_WRITE(mac, 0x52, 0x0);
3986		RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
3987	}
3988
3989	bwi_phy_set_bbp_atten(mac, 11);
3990
3991	if (phy->phy_rev >= 3)
3992		PHY_WRITE(mac, 0x80f, 0xc020);
3993	else
3994		PHY_WRITE(mac, 0x80f, 0x8020);
3995	PHY_WRITE(mac, 0x810, 0);
3996
3997	PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
3998	PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
3999	PHY_SETBITS(mac, 0x811, 0x100);
4000	PHY_CLRBITS(mac, 0x812, 0x3000);
4001
4002	if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
4003	    phy->phy_rev >= 7) {
4004		PHY_SETBITS(mac, 0x811, 0x800);
4005		PHY_SETBITS(mac, 0x812, 0x8000);
4006	}
4007	RF_CLRBITS(mac, 0x7a, 0xff08);
4008
4009	/*
4010	 * Find out 'loop1/loop2', which will be used to calculate
4011	 * max loopback gain later
4012	 */
4013	j = 0;
4014	for (i = 0; i < loop1_max; ++i) {
4015		for (j = 0; j < 16; ++j) {
4016			RF_WRITE(mac, 0x43, i);
4017
4018			if (bwi_rf_gain_max_reached(mac, j))
4019				goto loop1_exit;
4020		}
4021	}
4022loop1_exit:
4023	loop1 = i;
4024	loop2 = j;
4025
4026	/*
4027	 * Find out 'trsw', which will be used to calculate
4028	 * TRSW(TX/RX switch) RX gain later
4029	 */
4030	if (loop2 >= 8) {
4031		PHY_SETBITS(mac, 0x812, 0x30);
4032		trsw = 0x1b;
4033		for (i = loop2 - 8; i < 16; ++i) {
4034			trsw -= 3;
4035			if (bwi_rf_gain_max_reached(mac, i))
4036				break;
4037		}
4038	} else {
4039		trsw = 0x18;
4040	}
4041
4042	/*
4043	 * Restore saved PHY/RF registers
4044	 */
4045	/* First 4 saved PHY registers need special processing */
4046	for (i = 4; i < SAVE_PHY_MAX; ++i)
4047		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
4048
4049	bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
4050
4051	for (i = 0; i < SAVE_RF_MAX; ++i)
4052		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
4053
4054	PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
4055	DELAY(10);
4056	PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
4057	PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
4058	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
4059	PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
4060
4061	/*
4062	 * Calculate gains
4063	 */
4064	rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
4065	rf->rf_rx_gain = trsw * 2;
4066	DPRINTF(1, "%s: lo gain: %u, rx gain: %u\n",
4067	    sc->sc_dev.dv_xname, rf->rf_lo_gain, rf->rf_rx_gain);
4068
4069#undef SAVE_RF_MAX
4070#undef SAVE_PHY_MAX
4071}
4072
4073void
4074bwi_rf_init(struct bwi_mac *mac)
4075{
4076	struct bwi_rf *rf = &mac->mac_rf;
4077
4078	if (rf->rf_type == BWI_RF_T_BCM2060) {
4079		/* TODO: 11A */
4080	} else {
4081		if (rf->rf_flags & BWI_RF_F_INITED)
4082			RF_WRITE(mac, 0x78, rf->rf_calib);
4083		else
4084			bwi_rf_init_bcm2050(mac);
4085	}
4086}
4087
4088void
4089bwi_rf_off_11a(struct bwi_mac *mac)
4090{
4091	RF_WRITE(mac, 0x4, 0xff);
4092	RF_WRITE(mac, 0x5, 0xfb);
4093
4094	PHY_SETBITS(mac, 0x10, 0x8);
4095	PHY_SETBITS(mac, 0x11, 0x8);
4096
4097	PHY_WRITE(mac, 0x15, 0xaa00);
4098}
4099
4100void
4101bwi_rf_off_11bg(struct bwi_mac *mac)
4102{
4103	PHY_WRITE(mac, 0x15, 0xaa00);
4104}
4105
4106void
4107bwi_rf_off_11g_rev5(struct bwi_mac *mac)
4108{
4109	PHY_SETBITS(mac, 0x811, 0x8c);
4110	PHY_CLRBITS(mac, 0x812, 0x8c);
4111}
4112
4113void
4114bwi_rf_workaround(struct bwi_mac *mac, uint chan)
4115{
4116	struct bwi_softc *sc = mac->mac_sc;
4117	struct bwi_rf *rf = &mac->mac_rf;
4118
4119	if (chan == IEEE80211_CHAN_ANY) {
4120		printf("%s: %s invalid channel!\n",
4121		    sc->sc_dev.dv_xname, __func__);
4122		return;
4123	}
4124
4125	if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
4126		return;
4127
4128	if (chan <= 10)
4129		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
4130	else
4131		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
4132	DELAY(1000);
4133	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
4134}
4135
4136struct bwi_rf_lo *
4137bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
4138{
4139	uint16_t rf_atten, bbp_atten;
4140	int remap_rf_atten;
4141
4142	remap_rf_atten = 1;
4143	if (tpctl == NULL) {
4144		bbp_atten = 2;
4145		rf_atten = 3;
4146	} else {
4147		if (tpctl->tp_ctrl1 == 3)
4148			remap_rf_atten = 0;
4149
4150		bbp_atten = tpctl->bbp_atten;
4151		rf_atten = tpctl->rf_atten;
4152
4153		if (bbp_atten > 6)
4154			bbp_atten = 6;
4155	}
4156
4157	if (remap_rf_atten) {
4158#define MAP_MAX	10
4159		static const uint16_t map[MAP_MAX] =
4160		{ 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
4161#if 0
4162		KASSERT(rf_atten < MAP_MAX);
4163		rf_atten = map[rf_atten];
4164#else
4165		if (rf_atten >= MAP_MAX) {
4166			rf_atten = 0;	/* XXX */
4167		} else {
4168			rf_atten = map[rf_atten];
4169		}
4170#endif
4171#undef MAP_MAX
4172	}
4173
4174	return (bwi_get_rf_lo(mac, rf_atten, bbp_atten));
4175}
4176
4177void
4178bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
4179{
4180	const struct bwi_rf_lo *lo;
4181
4182	lo = bwi_rf_lo_find(mac, tpctl);
4183	RF_LO_WRITE(mac, lo);
4184}
4185
4186void
4187bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
4188{
4189	uint16_t val;
4190
4191	val = (uint8_t)lo->ctrl_lo;
4192	val |= ((uint8_t)lo->ctrl_hi) << 8;
4193
4194	PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
4195}
4196
4197int
4198bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
4199{
4200	PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
4201	PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
4202	PHY_SETBITS(mac, 0x15, 0xf000);
4203
4204	DELAY(20);
4205
4206	return ((PHY_READ(mac, 0x2d) >= 0xdfc));
4207}
4208
4209/* XXX use bitmap array */
4210uint16_t
4211bwi_bitswap4(uint16_t val)
4212{
4213	uint16_t ret;
4214
4215	ret = (val & 0x8) >> 3;
4216	ret |= (val & 0x4) >> 1;
4217	ret |= (val & 0x2) << 1;
4218	ret |= (val & 0x1) << 3;
4219
4220	return (ret);
4221}
4222
4223uint16_t
4224bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
4225{
4226	struct bwi_softc *sc = mac->mac_sc;
4227	struct bwi_phy *phy = &mac->mac_phy;
4228	struct bwi_rf *rf = &mac->mac_rf;
4229	uint16_t lo_gain, ext_lna, loop;
4230
4231	if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
4232		return (0);
4233
4234	lo_gain = rf->rf_lo_gain;
4235	if (rf->rf_rev == 8)
4236		lo_gain += 0x3e;
4237	else
4238		lo_gain += 0x26;
4239
4240	if (lo_gain >= 0x46) {
4241		lo_gain -= 0x46;
4242		ext_lna = 0x3000;
4243	} else if (lo_gain >= 0x3a) {
4244		lo_gain -= 0x3a;
4245		ext_lna = 0x1000;
4246	} else if (lo_gain >= 0x2e) {
4247		lo_gain -= 0x2e;
4248		ext_lna = 0x2000;
4249	} else {
4250		lo_gain -= 0x10;
4251		ext_lna = 0;
4252	}
4253
4254	for (loop = 0; loop < 16; ++loop) {
4255		lo_gain -= (6 * loop);
4256		if (lo_gain < 6)
4257			break;
4258	}
4259
4260	if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
4261		if (ext_lna)
4262			ext_lna |= 0x8000;
4263		ext_lna |= (loop << 8);
4264		switch (lpd) {
4265		case 0x011:
4266			return (0x8f92);
4267		case 0x001:
4268			return ((0x8092 | ext_lna));
4269		case 0x101:
4270			return ((0x2092 | ext_lna));
4271		case 0x100:
4272			return ((0x2093 | ext_lna));
4273		default:
4274			panic("unsupported lpd");
4275		}
4276	} else {
4277		ext_lna |= (loop << 8);
4278		switch (lpd) {
4279		case 0x011:
4280			return (0xf92);
4281		case 0x001:
4282		case 0x101:
4283			return ((0x92 | ext_lna));
4284		case 0x100:
4285			return ((0x93 | ext_lna));
4286		default:
4287			panic("unsupported lpd");
4288		}
4289	}
4290
4291	panic("never reached");
4292
4293	return (0);
4294}
4295
4296void
4297bwi_rf_init_bcm2050(struct bwi_mac *mac)
4298{
4299#define SAVE_RF_MAX		3
4300#define SAVE_PHY_COMM_MAX	4
4301#define SAVE_PHY_11G_MAX	6
4302	uint16_t save_rf[SAVE_RF_MAX];
4303	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
4304	uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
4305	uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
4306	uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
4307	uint16_t phy812_val;
4308	uint16_t calib;
4309	uint32_t test_lim, test;
4310	struct bwi_softc *sc = mac->mac_sc;
4311	struct bwi_phy *phy = &mac->mac_phy;
4312	struct bwi_rf *rf = &mac->mac_rf;
4313	int i;
4314
4315	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4316	    { 0x0043, 0x0051, 0x0052 };
4317	static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
4318	    { 0x0015, 0x005a, 0x0059, 0x0058 };
4319	static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
4320	    { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
4321
4322	/*
4323	 * Save registers for later restoring
4324	 */
4325	for (i = 0; i < SAVE_RF_MAX; ++i)
4326		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4327	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
4328		save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
4329
4330	if (phy->phy_mode == IEEE80211_MODE_11B) {
4331		phyr_30 = PHY_READ(mac, 0x30);
4332		bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
4333
4334		PHY_WRITE(mac, 0x30, 0xff);
4335		CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
4336	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4337		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4338			save_phy_11g[i] =
4339			    PHY_READ(mac, save_phy_regs_11g[i]);
4340		}
4341
4342		PHY_SETBITS(mac, 0x814, 0x3);
4343		PHY_CLRBITS(mac, 0x815, 0x3);
4344		PHY_CLRBITS(mac, 0x429, 0x8000);
4345		PHY_CLRBITS(mac, 0x802, 0x3);
4346
4347		phyr_80f = PHY_READ(mac, 0x80f);
4348		phyr_810 = PHY_READ(mac, 0x810);
4349
4350		if (phy->phy_rev >= 3)
4351			PHY_WRITE(mac, 0x80f, 0xc020);
4352		else
4353			PHY_WRITE(mac, 0x80f, 0x8020);
4354		PHY_WRITE(mac, 0x810, 0);
4355
4356		phy812_val = bwi_phy812_value(mac, 0x011);
4357		PHY_WRITE(mac, 0x812, phy812_val);
4358		if (phy->phy_rev < 7 ||
4359		    (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
4360			PHY_WRITE(mac, 0x811, 0x1b3);
4361		else
4362			PHY_WRITE(mac, 0x811, 0x9b3);
4363	}
4364	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4365
4366	phyr_35 = PHY_READ(mac, 0x35);
4367	PHY_CLRBITS(mac, 0x35, 0x80);
4368
4369	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4370	rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4371
4372	if (phy->phy_version == 0) {
4373		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
4374	} else {
4375		if (phy->phy_version >= 2)
4376			PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
4377		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
4378	}
4379
4380	calib = bwi_rf_calibval(mac);
4381
4382	if (phy->phy_mode == IEEE80211_MODE_11B)
4383		RF_WRITE(mac, 0x78, 0x26);
4384
4385	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4386		phy812_val = bwi_phy812_value(mac, 0x011);
4387		PHY_WRITE(mac, 0x812, phy812_val);
4388	}
4389
4390	PHY_WRITE(mac, 0x15, 0xbfaf);
4391	PHY_WRITE(mac, 0x2b, 0x1403);
4392
4393	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4394		phy812_val = bwi_phy812_value(mac, 0x001);
4395		PHY_WRITE(mac, 0x812, phy812_val);
4396	}
4397
4398	PHY_WRITE(mac, 0x15, 0xbfa0);
4399
4400	RF_SETBITS(mac, 0x51, 0x4);
4401	if (rf->rf_rev == 8)
4402		RF_WRITE(mac, 0x43, 0x1f);
4403	else {
4404		RF_WRITE(mac, 0x52, 0);
4405		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
4406	}
4407
4408	test_lim = 0;
4409	PHY_WRITE(mac, 0x58, 0);
4410	for (i = 0; i < 16; ++i) {
4411		PHY_WRITE(mac, 0x5a, 0x480);
4412		PHY_WRITE(mac, 0x59, 0xc810);
4413
4414		PHY_WRITE(mac, 0x58, 0xd);
4415		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4416			phy812_val = bwi_phy812_value(mac, 0x101);
4417			PHY_WRITE(mac, 0x812, phy812_val);
4418		}
4419		PHY_WRITE(mac, 0x15, 0xafb0);
4420		DELAY(10);
4421
4422		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4423			phy812_val = bwi_phy812_value(mac, 0x101);
4424			PHY_WRITE(mac, 0x812, phy812_val);
4425		}
4426		PHY_WRITE(mac, 0x15, 0xefb0);
4427		DELAY(10);
4428
4429		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4430			phy812_val = bwi_phy812_value(mac, 0x100);
4431			PHY_WRITE(mac, 0x812, phy812_val);
4432		}
4433		PHY_WRITE(mac, 0x15, 0xfff0);
4434		DELAY(20);
4435
4436		test_lim += PHY_READ(mac, 0x2d);
4437
4438		PHY_WRITE(mac, 0x58, 0);
4439		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4440			phy812_val = bwi_phy812_value(mac, 0x101);
4441			PHY_WRITE(mac, 0x812, phy812_val);
4442		}
4443		PHY_WRITE(mac, 0x15, 0xafb0);
4444	}
4445	++test_lim;
4446	test_lim >>= 9;
4447
4448	DELAY(10);
4449
4450	test = 0;
4451	PHY_WRITE(mac, 0x58, 0);
4452	for (i = 0; i < 16; ++i) {
4453		int j;
4454
4455		rfr_78 = (bwi_bitswap4(i) << 1) | 0x20;
4456		RF_WRITE(mac, 0x78, rfr_78);
4457		DELAY(10);
4458
4459		/* NB: This block is slight different than the above one */
4460		for (j = 0; j < 16; ++j) {
4461			PHY_WRITE(mac, 0x5a, 0xd80);
4462			PHY_WRITE(mac, 0x59, 0xc810);
4463
4464			PHY_WRITE(mac, 0x58, 0xd);
4465			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4466			    phy->phy_rev >= 2) {
4467				phy812_val = bwi_phy812_value(mac, 0x101);
4468				PHY_WRITE(mac, 0x812, phy812_val);
4469			}
4470			PHY_WRITE(mac, 0x15, 0xafb0);
4471			DELAY(10);
4472
4473			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4474			    phy->phy_rev >= 2) {
4475				phy812_val = bwi_phy812_value(mac, 0x101);
4476				PHY_WRITE(mac, 0x812, phy812_val);
4477			}
4478			PHY_WRITE(mac, 0x15, 0xefb0);
4479			DELAY(10);
4480
4481			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4482			    phy->phy_rev >= 2) {
4483				phy812_val = bwi_phy812_value(mac, 0x100);
4484				PHY_WRITE(mac, 0x812, phy812_val);
4485			}
4486			PHY_WRITE(mac, 0x15, 0xfff0);
4487			DELAY(10);
4488
4489			test += PHY_READ(mac, 0x2d);
4490
4491			PHY_WRITE(mac, 0x58, 0);
4492			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4493			    phy->phy_rev >= 2) {
4494				phy812_val = bwi_phy812_value(mac, 0x101);
4495				PHY_WRITE(mac, 0x812, phy812_val);
4496			}
4497			PHY_WRITE(mac, 0x15, 0xafb0);
4498		}
4499
4500		++test;
4501		test >>= 8;
4502
4503		if (test > test_lim)
4504			break;
4505	}
4506	if (i > 15)
4507		rf->rf_calib = rfr_78;
4508	else
4509		rf->rf_calib = calib;
4510	if (rf->rf_calib != 0xffff) {
4511		DPRINTF(1, "%s: RF calibration value: 0x%04x\n",
4512		    sc->sc_dev.dv_xname, rf->rf_calib);
4513		rf->rf_flags |= BWI_RF_F_INITED;
4514	}
4515
4516	/*
4517	 * Restore trashes registers
4518	 */
4519	PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
4520
4521	for (i = 0; i < SAVE_RF_MAX; ++i) {
4522		int pos = (i + 1) % SAVE_RF_MAX;
4523
4524		RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
4525	}
4526	for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
4527		PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
4528
4529	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
4530	if (phy->phy_version != 0)
4531		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
4532
4533	PHY_WRITE(mac, 0x35, phyr_35);
4534	bwi_rf_workaround(mac, rf->rf_curchan);
4535
4536	if (phy->phy_mode == IEEE80211_MODE_11B) {
4537		PHY_WRITE(mac, 0x30, phyr_30);
4538		CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
4539	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4540		/* XXX Spec only says when PHY is linked (gmode) */
4541		CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4542
4543		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4544			PHY_WRITE(mac, save_phy_regs_11g[i],
4545				  save_phy_11g[i]);
4546		}
4547
4548		PHY_WRITE(mac, 0x80f, phyr_80f);
4549		PHY_WRITE(mac, 0x810, phyr_810);
4550	}
4551
4552#undef SAVE_PHY_11G_MAX
4553#undef SAVE_PHY_COMM_MAX
4554#undef SAVE_RF_MAX
4555}
4556
4557uint16_t
4558bwi_rf_calibval(struct bwi_mac *mac)
4559{
4560	uint16_t val, calib;
4561	int idx;
4562
4563	/* http://bcm-specs.sipsolutions.net/RCCTable */
4564	static const uint16_t rf_calibvals[] = {
4565		0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
4566		0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
4567	};
4568
4569	val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
4570	idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
4571	KASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
4572
4573	calib = rf_calibvals[idx] << 1;
4574	if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
4575		calib |= 0x1;
4576	calib |= 0x20;
4577
4578	return (calib);
4579}
4580
4581int32_t
4582_bwi_adjust_devide(int32_t num, int32_t den)
4583{
4584	if (num < 0)
4585		return ((num / den));
4586	else
4587		return ((num + den / 2) / den);
4588}
4589
4590/*
4591 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
4592 * "calculating table entries"
4593 */
4594int
4595bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
4596{
4597	int32_t m1, m2, f, dbm;
4598	int i;
4599
4600	m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
4601	m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
4602
4603#define ITER_MAX	16
4604	f = 256;
4605	for (i = 0; i < ITER_MAX; ++i) {
4606		int32_t q, d;
4607
4608		q = _bwi_adjust_devide(
4609		    f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
4610		d = abs(q - f);
4611		f = q;
4612
4613		if (d < 2)
4614			break;
4615	}
4616	if (i == ITER_MAX)
4617		return (EINVAL);
4618#undef ITER_MAX
4619
4620	dbm = _bwi_adjust_devide(m1 * f, 8192);
4621	if (dbm < -127)
4622		dbm = -127;
4623	else if (dbm > 128)
4624		dbm = 128;
4625
4626	*txpwr = dbm;
4627
4628	return (0);
4629}
4630
4631int
4632bwi_rf_map_txpower(struct bwi_mac *mac)
4633{
4634	struct bwi_softc *sc = mac->mac_sc;
4635	struct bwi_rf *rf = &mac->mac_rf;
4636	struct bwi_phy *phy = &mac->mac_phy;
4637	uint16_t sprom_ofs, val, mask;
4638	int16_t pa_params[3];
4639	int error = 0, i, ant_gain, reg_txpower_max;
4640
4641	/*
4642	 * Find out max TX power
4643	 */
4644	val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
4645	if (phy->phy_mode == IEEE80211_MODE_11A) {
4646		rf->rf_txpower_max = __SHIFTOUT(val,
4647		    BWI_SPROM_MAX_TXPWR_MASK_11A);
4648	} else {
4649		rf->rf_txpower_max = __SHIFTOUT(val,
4650		    BWI_SPROM_MAX_TXPWR_MASK_11BG);
4651
4652		if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
4653		    phy->phy_mode == IEEE80211_MODE_11G)
4654			rf->rf_txpower_max -= 3;
4655	}
4656	if (rf->rf_txpower_max <= 0) {
4657		printf("%s: invalid max txpower in sprom\n",
4658		    sc->sc_dev.dv_xname);
4659		rf->rf_txpower_max = 74;
4660	}
4661	DPRINTF(1, "%s: max txpower from sprom: %d dBm\n",
4662	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4663
4664	/*
4665	 * Find out region/domain max TX power, which is adjusted
4666	 * by antenna gain and 1.5 dBm fluctuation as mentioned
4667	 * in v3 spec.
4668	 */
4669	val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
4670	if (phy->phy_mode == IEEE80211_MODE_11A)
4671		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
4672	else
4673		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
4674	if (ant_gain == 0xff) {
4675		/* XXX why this always invalid? */
4676		DPRINTF(1, "%s: invalid antenna gain in sprom\n",
4677		    sc->sc_dev.dv_xname);
4678		ant_gain = 2;
4679	}
4680	ant_gain *= 4;
4681	DPRINTF(1, "%s: ant gain %d dBm\n", sc->sc_dev.dv_xname, ant_gain);
4682
4683	reg_txpower_max = 90 - ant_gain - 6;	/* XXX magic number */
4684	DPRINTF(1, "%s: region/domain max txpower %d dBm\n",
4685	    sc->sc_dev.dv_xname, reg_txpower_max);
4686
4687	/*
4688	 * Force max TX power within region/domain TX power limit
4689	 */
4690	if (rf->rf_txpower_max > reg_txpower_max)
4691		rf->rf_txpower_max = reg_txpower_max;
4692	DPRINTF(1, "%s: max txpower %d dBm\n",
4693	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4694
4695	/*
4696	 * Create TSSI to TX power mapping
4697	 */
4698
4699	if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
4700	    rf->rf_type != BWI_RF_T_BCM2050) {
4701		rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4702		bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0,
4703		      sizeof(rf->rf_txpower_map0));
4704		goto back;
4705	}
4706
4707#define IS_VALID_PA_PARAM(p)	((p) != 0 && (p) != -1)
4708	/*
4709	 * Extract PA parameters
4710	 */
4711	if (phy->phy_mode == IEEE80211_MODE_11A)
4712		sprom_ofs = BWI_SPROM_PA_PARAM_11A;
4713	else
4714		sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
4715	for (i = 0; i < nitems(pa_params); ++i)
4716		pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
4717
4718	for (i = 0; i < nitems(pa_params); ++i) {
4719		/*
4720		 * If one of the PA parameters from SPROM is not valid,
4721		 * fall back to the default values, if there are any.
4722		 */
4723		if (!IS_VALID_PA_PARAM(pa_params[i])) {
4724			const int8_t *txpower_map;
4725
4726			if (phy->phy_mode == IEEE80211_MODE_11A) {
4727				printf("%s: no tssi2dbm table for 11a PHY\n",
4728				    sc->sc_dev.dv_xname);
4729				return (ENXIO);
4730			}
4731
4732			if (phy->phy_mode == IEEE80211_MODE_11G) {
4733				DPRINTF(1, "%s: use default 11g TSSI map\n",
4734				    sc->sc_dev.dv_xname);
4735				txpower_map = bwi_txpower_map_11g;
4736			} else {
4737				txpower_map = bwi_txpower_map_11b;
4738			}
4739
4740			rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4741			bcopy(txpower_map, rf->rf_txpower_map0,
4742			      sizeof(rf->rf_txpower_map0));
4743			goto back;
4744		}
4745	}
4746
4747	/*
4748	 * All of the PA parameters from SPROM are valid.
4749	 */
4750
4751	/*
4752	 * Extract idle TSSI from SPROM.
4753	 */
4754	val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
4755	DPRINTF(1, "%s: sprom idle tssi: 0x%04x\n", sc->sc_dev.dv_xname, val);
4756
4757	if (phy->phy_mode == IEEE80211_MODE_11A)
4758		mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
4759	else
4760		mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
4761
4762	rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
4763	if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
4764		rf->rf_idle_tssi0 = 62;
4765
4766#undef IS_VALID_PA_PARAM
4767
4768	/*
4769	 * Calculate TX power map, which is indexed by TSSI
4770	 */
4771	DPRINTF(1, "%s: TSSI-TX power map:\n", sc->sc_dev.dv_xname);
4772	for (i = 0; i < BWI_TSSI_MAX; ++i) {
4773		error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
4774					    pa_params);
4775		if (error) {
4776			printf("%s: bwi_rf_calc_txpower failed\n",
4777			    sc->sc_dev.dv_xname);
4778			break;
4779		}
4780		if (i != 0 && i % 8 == 0)
4781			DPRINTF(1, "\n");
4782		DPRINTF(1, "%d ", rf->rf_txpower_map0[i]);
4783	}
4784	DPRINTF(1, "\n");
4785back:
4786	DPRINTF(1, "%s: idle tssi0: %d\n",
4787	    sc->sc_dev.dv_xname, rf->rf_idle_tssi0);
4788
4789	return (error);
4790}
4791
4792void
4793bwi_rf_lo_update_11g(struct bwi_mac *mac)
4794{
4795	struct bwi_softc *sc = mac->mac_sc;
4796	struct ifnet *ifp = &sc->sc_ic.ic_if;
4797	struct bwi_rf *rf = &mac->mac_rf;
4798	struct bwi_phy *phy = &mac->mac_phy;
4799	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
4800	struct rf_saveregs regs;
4801	uint16_t ant_div, chan_ex;
4802	uint8_t devi_ctrl;
4803	uint orig_chan;
4804
4805	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
4806
4807	/*
4808	 * Save RF/PHY registers for later restoration
4809	 */
4810	orig_chan = rf->rf_curchan;
4811	bzero(&regs, sizeof(regs));
4812
4813	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4814		SAVE_PHY_REG(mac, &regs, 429);
4815		SAVE_PHY_REG(mac, &regs, 802);
4816
4817		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4818		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4819	}
4820
4821	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
4822	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
4823	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4824
4825	SAVE_PHY_REG(mac, &regs, 15);
4826	SAVE_PHY_REG(mac, &regs, 2a);
4827	SAVE_PHY_REG(mac, &regs, 35);
4828	SAVE_PHY_REG(mac, &regs, 60);
4829	SAVE_RF_REG(mac, &regs, 43);
4830	SAVE_RF_REG(mac, &regs, 7a);
4831	SAVE_RF_REG(mac, &regs, 52);
4832	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4833		SAVE_PHY_REG(mac, &regs, 811);
4834		SAVE_PHY_REG(mac, &regs, 812);
4835		SAVE_PHY_REG(mac, &regs, 814);
4836		SAVE_PHY_REG(mac, &regs, 815);
4837	}
4838
4839	/* Force to channel 6 */
4840	bwi_rf_set_chan(mac, 6, 0);
4841
4842	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4843		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4844		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4845		bwi_mac_dummy_xmit(mac);
4846	}
4847	RF_WRITE(mac, 0x43, 0x6);
4848
4849	bwi_phy_set_bbp_atten(mac, 2);
4850
4851	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
4852
4853	PHY_WRITE(mac, 0x2e, 0x7f);
4854	PHY_WRITE(mac, 0x80f, 0x78);
4855	PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
4856	RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
4857	PHY_WRITE(mac, 0x2b, 0x203);
4858	PHY_WRITE(mac, 0x2a, 0x8a3);
4859
4860	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4861		PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
4862		PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
4863		PHY_WRITE(mac, 0x811, 0x1b3);
4864		PHY_WRITE(mac, 0x812, 0xb2);
4865	}
4866
4867	if ((ifp->if_flags & IFF_RUNNING) == 0)
4868		tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
4869	PHY_WRITE(mac, 0x80f, 0x8078);
4870
4871	/*
4872	 * Measure all RF LO
4873	 */
4874	devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a);
4875
4876	/*
4877	 * Restore saved RF/PHY registers
4878	 */
4879	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4880		PHY_WRITE(mac, 0x15, 0xe300);
4881		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
4882		DELAY(5);
4883		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
4884		DELAY(2);
4885		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
4886	} else
4887		PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
4888
4889	if ((ifp->if_flags & IFF_RUNNING) == 0)
4890		tpctl = NULL;
4891	bwi_rf_lo_adjust(mac, tpctl);
4892
4893	PHY_WRITE(mac, 0x2e, 0x807f);
4894	if (phy->phy_flags & BWI_PHY_F_LINKED)
4895		PHY_WRITE(mac, 0x2f, 0x202);
4896	else
4897		PHY_WRITE(mac, 0x2f, 0x101);
4898
4899	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
4900
4901	RESTORE_PHY_REG(mac, &regs, 15);
4902	RESTORE_PHY_REG(mac, &regs, 2a);
4903	RESTORE_PHY_REG(mac, &regs, 35);
4904	RESTORE_PHY_REG(mac, &regs, 60);
4905
4906	RESTORE_RF_REG(mac, &regs, 43);
4907	RESTORE_RF_REG(mac, &regs, 7a);
4908
4909	regs.rf_52 &= 0xf0;
4910	regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
4911	RF_WRITE(mac, 0x52, regs.rf_52);
4912
4913	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
4914
4915	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4916		RESTORE_PHY_REG(mac, &regs, 811);
4917		RESTORE_PHY_REG(mac, &regs, 812);
4918		RESTORE_PHY_REG(mac, &regs, 814);
4919		RESTORE_PHY_REG(mac, &regs, 815);
4920		RESTORE_PHY_REG(mac, &regs, 429);
4921		RESTORE_PHY_REG(mac, &regs, 802);
4922	}
4923
4924	bwi_rf_set_chan(mac, orig_chan, 1);
4925}
4926
4927uint32_t
4928bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
4929{
4930	struct bwi_phy *phy = &mac->mac_phy;
4931	uint32_t devi = 0;
4932	int i;
4933
4934	if (phy->phy_flags & BWI_PHY_F_LINKED)
4935		ctrl <<= 8;
4936
4937	for (i = 0; i < 8; ++i) {
4938		if (phy->phy_flags & BWI_PHY_F_LINKED) {
4939			PHY_WRITE(mac, 0x15, 0xe300);
4940			PHY_WRITE(mac, 0x812, ctrl | 0xb0);
4941			DELAY(5);
4942			PHY_WRITE(mac, 0x812, ctrl | 0xb2);
4943			DELAY(2);
4944			PHY_WRITE(mac, 0x812, ctrl | 0xb3);
4945			DELAY(4);
4946			PHY_WRITE(mac, 0x15, 0xf300);
4947		} else {
4948			PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
4949			DELAY(2);
4950			PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
4951			DELAY(4);
4952			PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
4953		}
4954		DELAY(8);
4955		devi += PHY_READ(mac, 0x2d);
4956	}
4957
4958	return (devi);
4959}
4960
4961uint16_t
4962bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
4963{
4964	uint32_t devi_min;
4965	uint16_t tp_ctrl2 = 0;
4966	int i;
4967
4968	RF_WRITE(mac, 0x52, 0);
4969	DELAY(10);
4970	devi_min = bwi_rf_lo_devi_measure(mac, 0);
4971
4972	for (i = 0; i < 16; ++i) {
4973		uint32_t devi;
4974
4975		RF_WRITE(mac, 0x52, i);
4976		DELAY(10);
4977		devi = bwi_rf_lo_devi_measure(mac, 0);
4978
4979		if (devi < devi_min) {
4980			devi_min = devi;
4981			tp_ctrl2 = i;
4982		}
4983	}
4984
4985	return (tp_ctrl2);
4986}
4987
4988uint8_t
4989_bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
4990{
4991#define RF_ATTEN_LISTSZ	14
4992#define BBP_ATTEN_MAX	4	/* half */
4993	struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if;
4994	struct bwi_rf_lo lo_save, *lo;
4995	uint8_t devi_ctrl = 0;
4996	int idx, adj_rf7a = 0;
4997
4998	static const int rf_atten_list[RF_ATTEN_LISTSZ] =
4999	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
5000	static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
5001            { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
5002	static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
5003	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
5004
5005	bzero(&lo_save, sizeof(lo_save));
5006	for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
5007		int init_rf_atten = rf_atten_init_list[idx];
5008		int rf_atten = rf_atten_list[idx];
5009		int bbp_atten;
5010
5011		for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
5012			uint16_t tp_ctrl2, rf7a;
5013
5014			if ((ifp->if_flags & IFF_RUNNING) == 0) {
5015				if (idx == 0) {
5016					bzero(&lo_save, sizeof(lo_save));
5017				} else if (init_rf_atten < 0) {
5018					lo = bwi_get_rf_lo(mac,
5019					    rf_atten, 2 * bbp_atten);
5020					bcopy(lo, &lo_save, sizeof(lo_save));
5021				} else {
5022					lo = bwi_get_rf_lo(mac,
5023					    init_rf_atten, 0);
5024					bcopy(lo, &lo_save, sizeof(lo_save));
5025				}
5026
5027				devi_ctrl = 0;
5028				adj_rf7a = 0;
5029
5030				/*
5031				 * XXX
5032				 * Linux driver overflows 'val'
5033				 */
5034				if (init_rf_atten >= 0) {
5035					int val;
5036
5037					val = rf_atten * 2 + bbp_atten;
5038					if (val > 14) {
5039						adj_rf7a = 1;
5040						if (val > 17)
5041							devi_ctrl = 1;
5042						if (val > 19)
5043							devi_ctrl = 2;
5044					}
5045				}
5046			} else {
5047				lo = bwi_get_rf_lo(mac,
5048					rf_atten, 2 * bbp_atten);
5049				if (!bwi_rf_lo_isused(mac, lo))
5050					continue;
5051				bcopy(lo, &lo_save, sizeof(lo_save));
5052
5053				devi_ctrl = 3;
5054				adj_rf7a = 0;
5055			}
5056
5057			RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
5058
5059			tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
5060			if (init_rf_atten < 0)
5061				tp_ctrl2 |= (3 << 4);
5062			RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
5063
5064			DELAY(10);
5065
5066			bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
5067
5068			rf7a = orig_rf7a & 0xfff0;
5069			if (adj_rf7a)
5070				rf7a |= 0x8;
5071			RF_WRITE(mac, 0x7a, rf7a);
5072
5073			lo = bwi_get_rf_lo(mac,
5074				rf_lo_measure_order[idx], bbp_atten * 2);
5075			bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl);
5076		}
5077	}
5078
5079	return (devi_ctrl);
5080
5081#undef RF_ATTEN_LISTSZ
5082#undef BBP_ATTEN_MAX
5083}
5084
5085void
5086bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
5087    struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
5088{
5089#define LO_ADJUST_MIN	1
5090#define LO_ADJUST_MAX	8
5091#define LO_ADJUST(hi, lo)	{ .ctrl_hi = hi, .ctrl_lo = lo }
5092	static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
5093		LO_ADJUST(1,	1),
5094		LO_ADJUST(1,	0),
5095		LO_ADJUST(1,	-1),
5096		LO_ADJUST(0,	-1),
5097		LO_ADJUST(-1,	-1),
5098		LO_ADJUST(-1,	0),
5099		LO_ADJUST(-1,	1),
5100		LO_ADJUST(0,	1)
5101	};
5102#undef LO_ADJUST
5103
5104	struct bwi_rf_lo lo_min;
5105	uint32_t devi_min;
5106	int found, loop_count, adjust_state;
5107
5108	bcopy(src_lo, &lo_min, sizeof(lo_min));
5109	RF_LO_WRITE(mac, &lo_min);
5110	devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
5111
5112	loop_count = 12;	/* XXX */
5113	adjust_state = 0;
5114	do {
5115		struct bwi_rf_lo lo_base;
5116		int i, fin;
5117
5118		found = 0;
5119		if (adjust_state == 0) {
5120			i = LO_ADJUST_MIN;
5121			fin = LO_ADJUST_MAX;
5122		} else if (adjust_state % 2 == 0) {
5123			i = adjust_state - 1;
5124			fin = adjust_state + 1;
5125		} else {
5126			i = adjust_state - 2;
5127			fin = adjust_state + 2;
5128		}
5129
5130		if (i < LO_ADJUST_MIN)
5131			i += LO_ADJUST_MAX;
5132		KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
5133
5134		if (fin > LO_ADJUST_MAX)
5135			fin -= LO_ADJUST_MAX;
5136		KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
5137
5138		bcopy(&lo_min, &lo_base, sizeof(lo_base));
5139		for (;;) {
5140			struct bwi_rf_lo lo;
5141
5142			lo.ctrl_hi = lo_base.ctrl_hi +
5143				rf_lo_adjust[i - 1].ctrl_hi;
5144			lo.ctrl_lo = lo_base.ctrl_lo +
5145				rf_lo_adjust[i - 1].ctrl_lo;
5146
5147			if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
5148				uint32_t devi;
5149
5150				RF_LO_WRITE(mac, &lo);
5151				devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
5152				if (devi < devi_min) {
5153					devi_min = devi;
5154					adjust_state = i;
5155					found = 1;
5156					bcopy(&lo, &lo_min, sizeof(lo_min));
5157				}
5158			}
5159			if (i == fin)
5160				break;
5161			if (i == LO_ADJUST_MAX)
5162				i = LO_ADJUST_MIN;
5163			else
5164				++i;
5165		}
5166	} while (loop_count-- && found);
5167
5168	bcopy(&lo_min, dst_lo, sizeof(*dst_lo));
5169
5170#undef LO_ADJUST_MIN
5171#undef LO_ADJUST_MAX
5172}
5173
5174void
5175bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
5176{
5177#define SAVE_RF_MAX	3
5178#define SAVE_PHY_MAX	8
5179	struct bwi_softc *sc = mac->mac_sc;
5180	struct bwi_rf *rf = &mac->mac_rf;
5181	struct bwi_phy *phy = &mac->mac_phy;
5182	uint16_t save_rf[SAVE_RF_MAX];
5183	uint16_t save_phy[SAVE_PHY_MAX];
5184	uint16_t ant_div, bbp_atten, chan_ex;
5185	int16_t nrssi[2];
5186	int i;
5187
5188	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5189	    { 0x7a, 0x52, 0x43 };
5190	static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
5191	    { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
5192
5193	/*
5194	 * Save RF/PHY registers for later restoration
5195	 */
5196	for (i = 0; i < SAVE_RF_MAX; ++i)
5197		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5198	for (i = 0; i < SAVE_PHY_MAX; ++i)
5199		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
5200
5201	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5202	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
5203	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5204
5205	/*
5206	 * Calculate nrssi0
5207	 */
5208	if (phy->phy_rev >= 5)
5209		RF_CLRBITS(mac, 0x7a, 0xff80);
5210	else
5211		RF_CLRBITS(mac, 0x7a, 0xfff0);
5212	PHY_WRITE(mac, 0x30, 0xff);
5213
5214	CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
5215
5216	PHY_WRITE(mac, 0x26, 0);
5217	PHY_SETBITS(mac, 0x15, 0x20);
5218	PHY_WRITE(mac, 0x2a, 0x8a3);
5219	RF_SETBITS(mac, 0x7a, 0x80);
5220
5221	nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
5222
5223	/*
5224	 * Calculate nrssi1
5225	 */
5226	RF_CLRBITS(mac, 0x7a, 0xff80);
5227	if (phy->phy_version >= 2)
5228		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
5229	else if (phy->phy_version == 0)
5230		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
5231	else
5232		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
5233
5234	PHY_WRITE(mac, 0x20, 0x3f3f);
5235	PHY_WRITE(mac, 0x15, 0xf330);
5236
5237	RF_WRITE(mac, 0x5a, 0x60);
5238	RF_CLRBITS(mac, 0x43, 0xff0f);
5239
5240	PHY_WRITE(mac, 0x5a, 0x480);
5241	PHY_WRITE(mac, 0x59, 0x810);
5242	PHY_WRITE(mac, 0x58, 0xd);
5243
5244	DELAY(20);
5245
5246	nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
5247
5248	/*
5249	 * Restore saved RF/PHY registers
5250	 */
5251	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
5252	RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
5253
5254	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5255
5256	for (i = 1; i < 4; ++i)
5257		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5258
5259	bwi_rf_workaround(mac, rf->rf_curchan);
5260
5261	if (phy->phy_version != 0)
5262		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5263
5264	for (; i < SAVE_PHY_MAX; ++i)
5265		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5266
5267	for (i = 1; i < SAVE_RF_MAX; ++i)
5268		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5269
5270	/*
5271	 * Install calculated narrow RSSI values
5272	 */
5273	if (nrssi[0] == nrssi[1])
5274		rf->rf_nrssi_slope = 0x10000;
5275	else
5276		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5277	if (nrssi[0] <= -4) {
5278		rf->rf_nrssi[0] = nrssi[0];
5279		rf->rf_nrssi[1] = nrssi[1];
5280	}
5281
5282#undef SAVE_RF_MAX
5283#undef SAVE_PHY_MAX
5284}
5285
5286void
5287bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
5288{
5289#define SAVE_RF_MAX		2
5290#define SAVE_PHY_COMM_MAX	10
5291#define SAVE_PHY6_MAX		8
5292	struct bwi_phy *phy = &mac->mac_phy;
5293	uint16_t save_rf[SAVE_RF_MAX];
5294	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5295	uint16_t save_phy6[SAVE_PHY6_MAX];
5296	uint16_t rf7b = 0xffff;
5297	int16_t nrssi;
5298	int i, phy6_idx = 0;
5299
5300	static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 };
5301	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
5302		0x0001, 0x0811, 0x0812, 0x0814,
5303		0x0815, 0x005a, 0x0059, 0x0058,
5304		0x000a, 0x0003
5305	};
5306	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
5307		0x002e, 0x002f, 0x080f, 0x0810,
5308		0x0801, 0x0060, 0x0014, 0x0478
5309	};
5310
5311	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5312		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5313	for (i = 0; i < SAVE_RF_MAX; ++i)
5314		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5315
5316	PHY_CLRBITS(mac, 0x429, 0x8000);
5317	PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
5318	PHY_SETBITS(mac, 0x811, 0xc);
5319	PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
5320	PHY_CLRBITS(mac, 0x802, 0x3);
5321
5322	if (phy->phy_rev >= 6) {
5323		for (i = 0; i < SAVE_PHY6_MAX; ++i)
5324			save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
5325
5326		PHY_WRITE(mac, 0x2e, 0);
5327		PHY_WRITE(mac, 0x2f, 0);
5328		PHY_WRITE(mac, 0x80f, 0);
5329		PHY_WRITE(mac, 0x810, 0);
5330		PHY_SETBITS(mac, 0x478, 0x100);
5331		PHY_SETBITS(mac, 0x801, 0x40);
5332		PHY_SETBITS(mac, 0x60, 0x40);
5333		PHY_SETBITS(mac, 0x14, 0x200);
5334	}
5335
5336	RF_SETBITS(mac, 0x7a, 0x70);
5337	RF_SETBITS(mac, 0x7a, 0x80);
5338
5339	DELAY(30);
5340
5341	nrssi = bwi_nrssi_11g(mac);
5342	if (nrssi == 31) {
5343		for (i = 7; i >= 4; --i) {
5344			RF_WRITE(mac, 0x7b, i);
5345			DELAY(20);
5346			nrssi = bwi_nrssi_11g(mac);
5347			if (nrssi < 31 && rf7b == 0xffff)
5348				rf7b = i;
5349		}
5350		if (rf7b == 0xffff)
5351			rf7b = 4;
5352	} else {
5353		struct bwi_gains gains;
5354
5355		RF_CLRBITS(mac, 0x7a, 0xff80);
5356
5357		PHY_SETBITS(mac, 0x814, 0x1);
5358		PHY_CLRBITS(mac, 0x815, 0x1);
5359		PHY_SETBITS(mac, 0x811, 0xc);
5360		PHY_SETBITS(mac, 0x812, 0xc);
5361		PHY_SETBITS(mac, 0x811, 0x30);
5362		PHY_SETBITS(mac, 0x812, 0x30);
5363		PHY_WRITE(mac, 0x5a, 0x480);
5364		PHY_WRITE(mac, 0x59, 0x810);
5365		PHY_WRITE(mac, 0x58, 0xd);
5366		if (phy->phy_version == 0)
5367			PHY_WRITE(mac, 0x3, 0x122);
5368		else
5369			PHY_SETBITS(mac, 0xa, 0x2000);
5370		PHY_SETBITS(mac, 0x814, 0x4);
5371		PHY_CLRBITS(mac, 0x815, 0x4);
5372		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5373		RF_SETBITS(mac, 0x7a, 0xf);
5374
5375		bzero(&gains, sizeof(gains));
5376		gains.tbl_gain1 = 3;
5377		gains.tbl_gain2 = 0;
5378		gains.phy_gain = 1;
5379		bwi_set_gains(mac, &gains);
5380
5381		RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
5382		DELAY(30);
5383
5384		nrssi = bwi_nrssi_11g(mac);
5385		if (nrssi == -32) {
5386			for (i = 0; i < 4; ++i) {
5387				RF_WRITE(mac, 0x7b, i);
5388				DELAY(20);
5389				nrssi = bwi_nrssi_11g(mac);
5390				if (nrssi > -31 && rf7b == 0xffff)
5391					rf7b = i;
5392			}
5393			if (rf7b == 0xffff)
5394				rf7b = 3;
5395		} else {
5396			rf7b = 0;
5397		}
5398	}
5399	RF_WRITE(mac, 0x7b, rf7b);
5400
5401	/*
5402	 * Restore saved RF/PHY registers
5403	 */
5404	if (phy->phy_rev >= 6) {
5405		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
5406			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5407			    save_phy6[phy6_idx]);
5408		}
5409	}
5410
5411	/* Saved PHY registers 0, 1, 2 are handled later */
5412	for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
5413		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5414
5415	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
5416		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5417
5418	PHY_SETBITS(mac, 0x802, 0x3);
5419	PHY_SETBITS(mac, 0x429, 0x8000);
5420
5421	bwi_set_gains(mac, NULL);
5422
5423	if (phy->phy_rev >= 6) {
5424		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
5425			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5426			    save_phy6[phy6_idx]);
5427		}
5428	}
5429
5430	PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
5431	PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
5432	PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
5433
5434#undef SAVE_RF_MAX
5435#undef SAVE_PHY_COMM_MAX
5436#undef SAVE_PHY6_MAX
5437}
5438
5439void
5440bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
5441{
5442#define SAVE_RF_MAX		3
5443#define SAVE_PHY_COMM_MAX	4
5444#define SAVE_PHY3_MAX		8
5445	struct bwi_softc *sc = mac->mac_sc;
5446	struct bwi_phy *phy = &mac->mac_phy;
5447	struct bwi_rf *rf = &mac->mac_rf;
5448	uint16_t save_rf[SAVE_RF_MAX];
5449	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5450	uint16_t save_phy3[SAVE_PHY3_MAX];
5451	uint16_t ant_div, bbp_atten, chan_ex;
5452	struct bwi_gains gains;
5453	int16_t nrssi[2];
5454	int i, phy3_idx = 0;
5455
5456	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5457	    { 0x7a, 0x52, 0x43 };
5458	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
5459	    { 0x15, 0x5a, 0x59, 0x58 };
5460	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
5461		0x002e, 0x002f, 0x080f, 0x0810,
5462		0x0801, 0x0060, 0x0014, 0x0478
5463	};
5464
5465	if (rf->rf_rev >= 9)
5466		return;
5467	else if (rf->rf_rev == 8)
5468		bwi_rf_set_nrssi_ofs_11g(mac);
5469
5470	PHY_CLRBITS(mac, 0x429, 0x8000);
5471	PHY_CLRBITS(mac, 0x802, 0x3);
5472
5473	/*
5474	 * Save RF/PHY registers for later restoration
5475	 */
5476	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5477	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
5478
5479	for (i = 0; i < SAVE_RF_MAX; ++i)
5480		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5481	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5482		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5483
5484	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
5485	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5486
5487	if (phy->phy_rev >= 3) {
5488		for (i = 0; i < SAVE_PHY3_MAX; ++i)
5489			save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
5490
5491		PHY_WRITE(mac, 0x2e, 0);
5492		PHY_WRITE(mac, 0x810, 0);
5493
5494		if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
5495		    phy->phy_rev == 7) {
5496			PHY_SETBITS(mac, 0x478, 0x100);
5497			PHY_SETBITS(mac, 0x810, 0x40);
5498		} else if (phy->phy_rev == 3 || phy->phy_rev == 5)
5499			PHY_CLRBITS(mac, 0x810, 0x40);
5500
5501		PHY_SETBITS(mac, 0x60, 0x40);
5502		PHY_SETBITS(mac, 0x14, 0x200);
5503	}
5504
5505	/*
5506	 * Calculate nrssi0
5507	 */
5508	RF_SETBITS(mac, 0x7a, 0x70);
5509
5510	bzero(&gains, sizeof(gains));
5511	gains.tbl_gain1 = 0;
5512	gains.tbl_gain2 = 8;
5513	gains.phy_gain = 0;
5514	bwi_set_gains(mac, &gains);
5515
5516	RF_CLRBITS(mac, 0x7a, 0xff08);
5517	if (phy->phy_rev >= 2) {
5518		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
5519		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
5520	}
5521
5522	RF_SETBITS(mac, 0x7a, 0x80);
5523	DELAY(20);
5524	nrssi[0] = bwi_nrssi_11g(mac);
5525
5526	/*
5527	 * Calculate nrssi1
5528	 */
5529	RF_CLRBITS(mac, 0x7a, 0xff80);
5530	if (phy->phy_version >= 2)
5531		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5532	CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
5533
5534	RF_SETBITS(mac, 0x7a, 0xf);
5535	PHY_WRITE(mac, 0x15, 0xf330);
5536	if (phy->phy_rev >= 2) {
5537		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
5538		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
5539	}
5540
5541	bzero(&gains, sizeof(gains));
5542	gains.tbl_gain1 = 3;
5543	gains.tbl_gain2 = 0;
5544	gains.phy_gain = 1;
5545	bwi_set_gains(mac, &gains);
5546
5547	if (rf->rf_rev == 8) {
5548		RF_WRITE(mac, 0x43, 0x1f);
5549	} else {
5550		RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
5551		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
5552	}
5553	PHY_WRITE(mac, 0x5a, 0x480);
5554	PHY_WRITE(mac, 0x59, 0x810);
5555	PHY_WRITE(mac, 0x58, 0xd);
5556	DELAY(20);
5557
5558	nrssi[1] = bwi_nrssi_11g(mac);
5559
5560	/*
5561	 * Install calculated narrow RSSI values
5562	 */
5563	if (nrssi[1] == nrssi[0])
5564		rf->rf_nrssi_slope = 0x10000;
5565	else
5566		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5567	if (nrssi[0] >= -4) {
5568		rf->rf_nrssi[0] = nrssi[1];
5569		rf->rf_nrssi[1] = nrssi[0];
5570	}
5571
5572	/*
5573	 * Restore saved RF/PHY registers
5574	 */
5575	if (phy->phy_rev >= 3) {
5576		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
5577			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5578				  save_phy3[phy3_idx]);
5579		}
5580	}
5581	if (phy->phy_rev >= 2) {
5582		PHY_CLRBITS(mac, 0x812, 0x30);
5583		PHY_CLRBITS(mac, 0x811, 0x30);
5584	}
5585
5586	for (i = 0; i < SAVE_RF_MAX; ++i)
5587		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5588
5589	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5590	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
5591	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5592
5593	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5594		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5595
5596	bwi_rf_workaround(mac, rf->rf_curchan);
5597	PHY_SETBITS(mac, 0x802, 0x3);
5598	bwi_set_gains(mac, NULL);
5599	PHY_SETBITS(mac, 0x429, 0x8000);
5600
5601	if (phy->phy_rev >= 3) {
5602		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
5603			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5604			    save_phy3[phy3_idx]);
5605		}
5606	}
5607
5608	bwi_rf_init_sw_nrssi_table(mac);
5609	bwi_rf_set_nrssi_thr_11g(mac);
5610
5611#undef SAVE_RF_MAX
5612#undef SAVE_PHY_COMM_MAX
5613#undef SAVE_PHY3_MAX
5614}
5615
5616void
5617bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
5618{
5619	struct bwi_rf *rf = &mac->mac_rf;
5620	int d, i;
5621
5622	d = 0x1f - rf->rf_nrssi[0];
5623	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5624		int val;
5625
5626		val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
5627		if (val < 0)
5628			val = 0;
5629		else if (val > 0x3f)
5630			val = 0x3f;
5631
5632		rf->rf_nrssi_table[i] = val;
5633	}
5634}
5635
5636void
5637bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
5638{
5639	int i;
5640
5641	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5642		int16_t val;
5643
5644		val = bwi_nrssi_read(mac, i);
5645
5646		val -= adjust;
5647		if (val < -32)
5648			val = -32;
5649		else if (val > 31)
5650			val = 31;
5651
5652		bwi_nrssi_write(mac, i, val);
5653	}
5654}
5655
5656void
5657bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
5658{
5659	struct bwi_rf *rf = &mac->mac_rf;
5660	int32_t thr;
5661
5662	if (rf->rf_type != BWI_RF_T_BCM2050 ||
5663	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
5664		return;
5665
5666	/*
5667	 * Calculate nrssi threshold
5668	 */
5669	if (rf->rf_rev >= 6) {
5670		thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
5671		thr += 20 * (rf->rf_nrssi[0] + 1);
5672		thr /= 40;
5673	} else {
5674		thr = rf->rf_nrssi[1] - 5;
5675	}
5676	if (thr < 0)
5677		thr = 0;
5678	else if (thr > 0x3e)
5679		thr = 0x3e;
5680
5681	PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B);	/* dummy read */
5682	PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
5683
5684	if (rf->rf_rev >= 6) {
5685		PHY_WRITE(mac, 0x87, 0xe0d);
5686		PHY_WRITE(mac, 0x86, 0xc0b);
5687		PHY_WRITE(mac, 0x85, 0xa09);
5688		PHY_WRITE(mac, 0x84, 0x808);
5689		PHY_WRITE(mac, 0x83, 0x808);
5690		PHY_WRITE(mac, 0x82, 0x604);
5691		PHY_WRITE(mac, 0x81, 0x302);
5692		PHY_WRITE(mac, 0x80, 0x100);
5693	}
5694}
5695
5696int32_t
5697_nrssi_threshold(const struct bwi_rf *rf, int32_t val)
5698{
5699	val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
5700	val += (rf->rf_nrssi[0] << 6);
5701	if (val < 32)
5702		val += 31;
5703	else
5704		val += 32;
5705	val >>= 6;
5706	if (val < -31)
5707		val = -31;
5708	else if (val > 31)
5709		val = 31;
5710
5711	return (val);
5712}
5713
5714void
5715bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
5716{
5717	int32_t thr1, thr2;
5718	uint16_t thr;
5719
5720	/*
5721	 * Find the two nrssi thresholds
5722	 */
5723	if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
5724	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
5725	    	int16_t nrssi;
5726
5727		nrssi = bwi_nrssi_read(mac, 0x20);
5728		if (nrssi >= 32)
5729			nrssi -= 64;
5730
5731		if (nrssi < 3) {
5732			thr1 = 0x2b;
5733			thr2 = 0x27;
5734		} else {
5735			thr1 = 0x2d;
5736			thr2 = 0x2b;
5737		}
5738	} else {
5739		/* TODO Interfere mode */
5740		thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
5741		thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
5742	}
5743
5744#define NRSSI_THR1_MASK		0x003f
5745#define NRSSI_THR2_MASK		0x0fc0
5746	thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
5747	    __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
5748	PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
5749#undef NRSSI_THR1_MASK
5750#undef NRSSI_THR2_MASK
5751}
5752
5753void
5754bwi_rf_clear_tssi(struct bwi_mac *mac)
5755{
5756	/* XXX use function pointer */
5757	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
5758		/* TODO: 11A */
5759	} else {
5760		uint16_t val;
5761		int i;
5762
5763		val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
5764		    __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
5765
5766		for (i = 0; i < 2; ++i) {
5767			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5768			    BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
5769		}
5770
5771		for (i = 0; i < 2; ++i) {
5772			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5773			    BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
5774		}
5775	}
5776}
5777
5778void
5779bwi_rf_clear_state(struct bwi_rf *rf)
5780{
5781	int i;
5782
5783	rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
5784	bzero(rf->rf_lo, sizeof(rf->rf_lo));
5785	bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used));
5786
5787	rf->rf_nrssi_slope = 0;
5788	rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
5789	rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
5790
5791	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
5792		rf->rf_nrssi_table[i] = i;
5793
5794	rf->rf_lo_gain = 0;
5795	rf->rf_rx_gain = 0;
5796
5797	bcopy(rf->rf_txpower_map0, rf->rf_txpower_map,
5798	      sizeof(rf->rf_txpower_map));
5799	rf->rf_idle_tssi = rf->rf_idle_tssi0;
5800}
5801
5802void
5803bwi_rf_on_11a(struct bwi_mac *mac)
5804{
5805	/* TODO: 11A */
5806}
5807
5808void
5809bwi_rf_on_11bg(struct bwi_mac *mac)
5810{
5811	struct bwi_phy *phy = &mac->mac_phy;
5812
5813	PHY_WRITE(mac, 0x15, 0x8000);
5814	PHY_WRITE(mac, 0x15, 0xcc00);
5815	if (phy->phy_flags & BWI_PHY_F_LINKED)
5816		PHY_WRITE(mac, 0x15, 0xc0);
5817	else
5818		PHY_WRITE(mac, 0x15, 0);
5819
5820	bwi_rf_set_chan(mac, 6 /* XXX */, 1);
5821}
5822
5823void
5824bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
5825{
5826	struct bwi_softc *sc = mac->mac_sc;
5827	struct bwi_phy *phy = &mac->mac_phy;
5828	uint16_t val;
5829
5830	KASSERT(ant_mode == BWI_ANT_MODE_0 ||
5831	    ant_mode == BWI_ANT_MODE_1 ||
5832	    ant_mode == BWI_ANT_MODE_AUTO);
5833
5834	HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5835
5836	if (phy->phy_mode == IEEE80211_MODE_11B) {
5837		/* NOTE: v4/v3 conflicts, take v3 */
5838		if (mac->mac_rev == 2)
5839			val = BWI_ANT_MODE_AUTO;
5840		else
5841			val = ant_mode;
5842		val <<= 7;
5843		PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
5844	} else {	/* 11a/g */
5845		/* XXX reg/value naming */
5846		val = ant_mode << 7;
5847		PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
5848
5849		if (ant_mode == BWI_ANT_MODE_AUTO)
5850			PHY_CLRBITS(mac, 0x42b, 0x100);
5851
5852		if (phy->phy_mode == IEEE80211_MODE_11A) {
5853			/* TODO: 11A */
5854		} else {	/* 11g */
5855			if (ant_mode == BWI_ANT_MODE_AUTO)
5856				PHY_SETBITS(mac, 0x48c, 0x2000);
5857			else
5858				PHY_CLRBITS(mac, 0x48c, 0x2000);
5859
5860			if (phy->phy_rev >= 2) {
5861				PHY_SETBITS(mac, 0x461, 0x10);
5862				PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
5863				if (phy->phy_rev == 2) {
5864					PHY_WRITE(mac, 0x427, 0x8);
5865				} else {
5866					PHY_FILT_SETBITS(mac, 0x427,
5867							 0xff00, 0x8);
5868				}
5869
5870				if (phy->phy_rev >= 6)
5871					PHY_WRITE(mac, 0x49b, 0xdc);
5872			}
5873		}
5874	}
5875
5876	/* XXX v4 set AUTO_ANTDIV unconditionally */
5877	if (ant_mode == BWI_ANT_MODE_AUTO)
5878		HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5879
5880	val = ant_mode << 8;
5881	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
5882	    0xfc3f, val);
5883	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
5884	    0xfc3f, val);
5885	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
5886	    0xfc3f, val);
5887
5888	/* XXX what's these */
5889	if (phy->phy_mode == IEEE80211_MODE_11B)
5890		CSR_SETBITS_2(sc, 0x5e, 0x4);
5891
5892	CSR_WRITE_4(sc, 0x100, 0x1000000);
5893	if (mac->mac_rev < 5)
5894		CSR_WRITE_4(sc, 0x10c, 0x1000000);
5895
5896	mac->mac_rf.rf_ant_mode = ant_mode;
5897}
5898
5899int
5900bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
5901{
5902	int i;
5903
5904	for (i = 0; i < 4; ) {
5905		uint16_t val;
5906
5907		val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
5908		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
5909		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
5910	}
5911
5912	for (i = 0; i < 4; ++i) {
5913		if (tssi[i] == BWI_INVALID_TSSI)
5914			return (EINVAL);
5915	}
5916
5917	return (0);
5918}
5919
5920int
5921bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
5922{
5923	struct bwi_rf *rf = &mac->mac_rf;
5924	int pwr_idx;
5925
5926	pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
5927#if 0
5928	if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
5929		return EINVAL;
5930#else
5931	if (pwr_idx < 0)
5932		pwr_idx = 0;
5933	else if (pwr_idx >= BWI_TSSI_MAX)
5934		pwr_idx = BWI_TSSI_MAX - 1;
5935#endif
5936	*txpwr = rf->rf_txpower_map[pwr_idx];
5937
5938	return (0);
5939}
5940
5941int
5942bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
5943{
5944	uint16_t flags1, flags3;
5945	int rssi, lna_gain;
5946
5947	rssi = hdr->rxh_rssi;
5948	flags1 = letoh16(hdr->rxh_flags1);
5949	flags3 = letoh16(hdr->rxh_flags3);
5950
5951#define NEW_BCM2050_RSSI
5952#ifdef NEW_BCM2050_RSSI
5953	if (flags1 & BWI_RXH_F1_OFDM) {
5954		if (rssi > 127)
5955			rssi -= 256;
5956		if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
5957			rssi += 17;
5958		else
5959			rssi -= 4;
5960		return (rssi);
5961	}
5962
5963	if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
5964		struct bwi_rf *rf = &mac->mac_rf;
5965
5966		if (rssi >= BWI_NRSSI_TBLSZ)
5967			rssi = BWI_NRSSI_TBLSZ - 1;
5968
5969		rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
5970		rssi -= 67;
5971	} else {
5972		rssi = ((31 - rssi) * -149) / 128;
5973		rssi -= 68;
5974	}
5975
5976	if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
5977		return (rssi);
5978
5979	if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
5980		rssi += 20;
5981
5982	lna_gain = __SHIFTOUT(letoh16(hdr->rxh_phyinfo),
5983	    BWI_RXH_PHYINFO_LNAGAIN);
5984	DPRINTF(3, "lna_gain %d, phyinfo 0x%04x\n",
5985	    lna_gain, letoh16(hdr->rxh_phyinfo));
5986	switch (lna_gain) {
5987	case 0:
5988		rssi += 27;
5989		break;
5990	case 1:
5991		rssi += 6;
5992		break;
5993	case 2:
5994		rssi += 12;
5995		break;
5996	case 3:
5997		/*
5998		 * XXX
5999		 * According to v3 spec, we should do _nothing_ here,
6000		 * but it seems that the result RSSI will be too low
6001		 * (relative to what ath(4) says).  Raise it a little
6002		 * bit.
6003		 */
6004		rssi += 5;
6005		break;
6006	default:
6007		panic("impossible lna gain %d", lna_gain);
6008	}
6009#else	/* !NEW_BCM2050_RSSI */
6010	lna_gain = 0; /* shut up gcc warning */
6011
6012	if (flags1 & BWI_RXH_F1_OFDM) {
6013		if (rssi > 127)
6014			rssi -= 256;
6015		rssi = (rssi * 73) / 64;
6016
6017		if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6018			rssi += 25;
6019		else
6020			rssi -= 3;
6021		return (rssi);
6022	}
6023
6024	if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
6025		struct bwi_rf *rf = &mac->mac_rf;
6026
6027		if (rssi >= BWI_NRSSI_TBLSZ)
6028			rssi = BWI_NRSSI_TBLSZ - 1;
6029
6030		rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
6031		rssi -= 57;
6032	} else {
6033		rssi = ((31 - rssi) * -149) / 128;
6034		rssi -= 68;
6035	}
6036
6037	if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
6038		return (rssi);
6039
6040	if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6041		rssi += 25;
6042#endif	/* NEW_BCM2050_RSSI */
6043	return (rssi);
6044}
6045
6046int
6047bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6048{
6049	uint16_t flags1;
6050	int rssi;
6051
6052	rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
6053
6054	flags1 = letoh16(hdr->rxh_flags1);
6055	if (flags1 & BWI_RXH_F1_BCM2053_RSSI)
6056		rssi -= 109;
6057	else
6058		rssi -= 83;
6059
6060	return (rssi);
6061}
6062
6063int
6064bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6065{
6066	int rssi;
6067
6068	rssi = hdr->rxh_rssi;
6069	if (rssi > 127)
6070		rssi -= 256;
6071
6072	return (rssi);
6073}
6074
6075uint16_t
6076bwi_rf_lo_measure_11b(struct bwi_mac *mac)
6077{
6078	uint16_t val;
6079	int i;
6080
6081	val = 0;
6082	for (i = 0; i < 10; ++i) {
6083		PHY_WRITE(mac, 0x15, 0xafa0);
6084		DELAY(1);
6085		PHY_WRITE(mac, 0x15, 0xefa0);
6086		DELAY(10);
6087		PHY_WRITE(mac, 0x15, 0xffa0);
6088		DELAY(40);
6089
6090		val += PHY_READ(mac, 0x2c);
6091	}
6092
6093	return (val);
6094}
6095
6096void
6097bwi_rf_lo_update_11b(struct bwi_mac *mac)
6098{
6099	struct bwi_softc *sc = mac->mac_sc;
6100	struct bwi_rf *rf = &mac->mac_rf;
6101	struct rf_saveregs regs;
6102	uint16_t rf_val, phy_val, min_val, val;
6103	uint16_t rf52, bphy_ctrl;
6104	int i;
6105
6106	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6107
6108	bzero(&regs, sizeof(regs));
6109	bphy_ctrl = 0;
6110
6111	/*
6112	 * Save RF/PHY registers for later restoration
6113	 */
6114	SAVE_PHY_REG(mac, &regs, 15);
6115	rf52 = RF_READ(mac, 0x52) & 0xfff0;
6116	if (rf->rf_type == BWI_RF_T_BCM2050) {
6117		SAVE_PHY_REG(mac, &regs, 0a);
6118		SAVE_PHY_REG(mac, &regs, 2a);
6119		SAVE_PHY_REG(mac, &regs, 35);
6120		SAVE_PHY_REG(mac, &regs, 03);
6121		SAVE_PHY_REG(mac, &regs, 01);
6122		SAVE_PHY_REG(mac, &regs, 30);
6123
6124		SAVE_RF_REG(mac, &regs, 43);
6125		SAVE_RF_REG(mac, &regs, 7a);
6126
6127		bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
6128
6129		SAVE_RF_REG(mac, &regs, 52);
6130		regs.rf_52 &= 0xf0;
6131
6132		PHY_WRITE(mac, 0x30, 0xff);
6133		CSR_WRITE_2(sc, BWI_PHY_CTRL, 0x3f3f);
6134		PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
6135		RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
6136	}
6137
6138	PHY_WRITE(mac, 0x15, 0xb000);
6139
6140	if (rf->rf_type == BWI_RF_T_BCM2050) {
6141		PHY_WRITE(mac, 0x2b, 0x203);
6142 		PHY_WRITE(mac, 0x2a, 0x8a3);
6143 	} else {
6144		PHY_WRITE(mac, 0x2b, 0x1402);
6145	}
6146
6147	/*
6148	 * Setup RF signal
6149	 */
6150	rf_val = 0;
6151	min_val = 65535;
6152
6153	for (i = 0; i < 4; ++i) {
6154		RF_WRITE(mac, 0x52, rf52 | i);
6155		bwi_rf_lo_measure_11b(mac);	/* Ignore return value */
6156	}
6157	for (i = 0; i < 10; ++i) {
6158 		RF_WRITE(mac, 0x52, rf52 | i);
6159
6160  		val = bwi_rf_lo_measure_11b(mac) / 10;
6161		if (val < min_val) {
6162			min_val = val;
6163			rf_val = i;
6164		}
6165	}
6166	RF_WRITE(mac, 0x52, rf52 | rf_val);
6167
6168	/*
6169	 * Setup PHY signal
6170	*/
6171	phy_val = 0;
6172	min_val = 65535;
6173
6174	for (i = -4; i < 5; i += 2) {
6175		int j;
6176
6177		for (j = -4; j < 5; j += 2) {
6178			uint16_t phy2f;
6179
6180			phy2f = (0x100 * i) + j;
6181			if (j < 0)
6182				phy2f += 0x100;
6183			PHY_WRITE(mac, 0x2f, phy2f);
6184
6185			val = bwi_rf_lo_measure_11b(mac) / 10;
6186			if (val < min_val) {
6187				min_val = val;
6188				phy_val = phy2f;
6189			}
6190		}
6191	}
6192	PHY_WRITE(mac, 0x2f, phy_val + 0x101);
6193
6194	/*
6195	 * Restore saved RF/PHY registers
6196	 */
6197	if (rf->rf_type == BWI_RF_T_BCM2050) {
6198		RESTORE_PHY_REG(mac, &regs, 0a);
6199		RESTORE_PHY_REG(mac, &regs, 2a);
6200		RESTORE_PHY_REG(mac, &regs, 35);
6201		RESTORE_PHY_REG(mac, &regs, 03);
6202		RESTORE_PHY_REG(mac, &regs, 01);
6203		RESTORE_PHY_REG(mac, &regs, 30);
6204
6205		RESTORE_RF_REG(mac, &regs, 43);
6206		RESTORE_RF_REG(mac, &regs, 7a);
6207
6208		RF_FILT_SETBITS(mac, 0x52, 0xf, regs.rf_52);
6209
6210		CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
6211	}
6212	RESTORE_PHY_REG(mac, &regs, 15);
6213
6214	bwi_rf_workaround(mac, rf->rf_curchan);
6215}
6216
6217/* INTERFACE */
6218
6219uint16_t
6220bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
6221{
6222	return (CSR_READ_2(sc, ofs + BWI_SPROM_START));
6223}
6224
6225void
6226bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
6227    int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx)
6228{
6229	struct bwi_desc32 *desc = &desc_array[desc_idx];
6230	uint32_t ctrl, addr, addr_hi, addr_lo;
6231
6232	if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT && paddr >= 0x40000000)
6233		panic("bad paddr 0x%lx\n", (long)paddr);
6234
6235	addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK);
6236	addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK);
6237
6238	addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) |
6239	    __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK);
6240
6241	ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) |
6242	     __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK);
6243	if (desc_idx == ndesc - 1)
6244		ctrl |= BWI_DESC32_C_EOR;
6245	if (tx) {
6246		/* XXX */
6247		ctrl |= BWI_DESC32_C_FRAME_START |
6248		    BWI_DESC32_C_FRAME_END |
6249		    BWI_DESC32_C_INTR;
6250	}
6251
6252	desc->addr = htole32(addr);
6253	desc->ctrl = htole32(ctrl);
6254}
6255
6256void
6257bwi_power_on(struct bwi_softc *sc, int with_pll)
6258{
6259	uint32_t gpio_in, gpio_out, gpio_en, status;
6260
6261	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6262
6263	gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN);
6264	if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
6265		goto back;
6266
6267	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6268	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6269
6270	gpio_out |= BWI_PCIM_GPIO_PWR_ON;
6271	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6272	if (with_pll) {
6273		/* Turn off PLL first */
6274		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6275		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6276	}
6277
6278	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6279	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6280	DELAY(1000);
6281
6282	if (with_pll) {
6283		/* Turn on PLL */
6284		gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
6285		(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6286		DELAY(5000);
6287	}
6288
6289back:
6290	/* Clear "Signaled Target Abort" */
6291	status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG);
6292	status &= ~PCI_STATUS_TARGET_TARGET_ABORT;
6293	(sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status);
6294}
6295
6296int
6297bwi_power_off(struct bwi_softc *sc, int with_pll)
6298{
6299	uint32_t gpio_out, gpio_en;
6300
6301	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6302
6303	(sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */
6304	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6305	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6306
6307	gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
6308	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6309	if (with_pll) {
6310		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6311		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6312	}
6313
6314	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6315	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6316
6317	return (0);
6318}
6319
6320int
6321bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
6322    struct bwi_regwin **old_rw)
6323{
6324	int error;
6325
6326	if (old_rw != NULL)
6327		*old_rw = NULL;
6328
6329	if (!BWI_REGWIN_EXIST(rw))
6330		return (EINVAL);
6331
6332	if (sc->sc_cur_regwin != rw) {
6333		error = bwi_regwin_select(sc, rw->rw_id);
6334		if (error) {
6335			printf("%s: can't select regwin %d\n",
6336			    sc->sc_dev.dv_xname, rw->rw_id);
6337			return (error);
6338		}
6339	}
6340
6341	if (old_rw != NULL)
6342		*old_rw = sc->sc_cur_regwin;
6343	sc->sc_cur_regwin = rw;
6344
6345	return (0);
6346}
6347
6348int
6349bwi_regwin_select(struct bwi_softc *sc, int id)
6350{
6351	uint32_t win = BWI_PCIM_REGWIN(id);
6352	int i;
6353
6354#define RETRY_MAX	50
6355	for (i = 0; i < RETRY_MAX; ++i) {
6356		(sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win);
6357		if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win)
6358			return (0);
6359		DELAY(10);
6360	}
6361#undef RETRY_MAX
6362
6363	return (ENXIO);
6364}
6365
6366void
6367bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
6368{
6369	uint32_t val;
6370
6371	val = CSR_READ_4(sc, BWI_ID_HI);
6372	*type = BWI_ID_HI_REGWIN_TYPE(val);
6373	*rev = BWI_ID_HI_REGWIN_REV(val);
6374
6375	DPRINTF(1, "%s: regwin: type 0x%03x, rev %d, vendor 0x%04x\n",
6376	    sc->sc_dev.dv_xname,
6377	    *type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
6378}
6379
6380void
6381bwi_led_attach(struct bwi_softc *sc)
6382{
6383	const uint8_t *led_act = NULL;
6384	uint16_t gpio, val[BWI_LED_MAX];
6385	int i;
6386
6387	for (i = 0; i < nitems(bwi_vendor_led_act); ++i) {
6388		if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
6389			led_act = bwi_vendor_led_act[i].led_act;
6390				break;
6391		}
6392	}
6393	if (led_act == NULL)
6394		led_act = bwi_default_led_act;
6395
6396	gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
6397	val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
6398	val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
6399
6400	gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23);
6401	val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2);
6402	val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3);
6403
6404	for (i = 0; i < BWI_LED_MAX; ++i) {
6405		struct bwi_led *led = &sc->sc_leds[i];
6406
6407		if (val[i] == 0xff) {
6408			led->l_act = led_act[i];
6409		} else {
6410			if (val[i] & BWI_LED_ACT_LOW)
6411				led->l_flags |= BWI_LED_F_ACTLOW;
6412			led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
6413		}
6414		led->l_mask = (1 << i);
6415
6416		if (led->l_act == BWI_LED_ACT_BLINK_SLOW ||
6417		    led->l_act == BWI_LED_ACT_BLINK_POLL ||
6418		    led->l_act == BWI_LED_ACT_BLINK) {
6419		    led->l_flags |= BWI_LED_F_BLINK;
6420			if (led->l_act == BWI_LED_ACT_BLINK_POLL)
6421				led->l_flags |= BWI_LED_F_POLLABLE;
6422			else if (led->l_act == BWI_LED_ACT_BLINK_SLOW)
6423				led->l_flags |= BWI_LED_F_SLOW;
6424
6425			if (sc->sc_blink_led == NULL) {
6426				sc->sc_blink_led = led;
6427				if (led->l_flags & BWI_LED_F_SLOW)
6428					BWI_LED_SLOWDOWN(sc->sc_led_idle);
6429			}
6430		}
6431
6432		DPRINTF(1, "%s: %dth led, act %d, lowact %d\n",
6433		    sc->sc_dev.dv_xname, i, led->l_act,
6434		    led->l_flags & BWI_LED_F_ACTLOW);
6435	}
6436	timeout_set(&sc->sc_led_blink_next_ch, bwi_led_blink_next, sc);
6437	timeout_set(&sc->sc_led_blink_end_ch, bwi_led_blink_end, sc);
6438}
6439
6440uint16_t
6441bwi_led_onoff(struct bwi_led *led, uint16_t val, int on)
6442{
6443	if (led->l_flags & BWI_LED_F_ACTLOW)
6444		on = !on;
6445	if (on)
6446		val |= led->l_mask;
6447	else
6448		val &= ~led->l_mask;
6449
6450	return (val);
6451}
6452
6453void
6454bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
6455{
6456	struct ieee80211com *ic = &sc->sc_ic;
6457	uint16_t val;
6458	int i;
6459
6460	if (nstate == IEEE80211_S_INIT) {
6461		timeout_del(&sc->sc_led_blink_next_ch);
6462		timeout_del(&sc->sc_led_blink_end_ch);
6463		sc->sc_led_blinking = 0;
6464	}
6465
6466	if ((ic->ic_if.if_flags & IFF_RUNNING) == 0)
6467		return;
6468
6469	val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6470	for (i = 0; i < BWI_LED_MAX; ++i) {
6471		struct bwi_led *led = &sc->sc_leds[i];
6472		int on;
6473
6474		if (led->l_act == BWI_LED_ACT_UNKN ||
6475		    led->l_act == BWI_LED_ACT_NULL)
6476			continue;
6477
6478		if ((led->l_flags & BWI_LED_F_BLINK) &&
6479			nstate != IEEE80211_S_INIT)
6480			continue;
6481
6482		switch (led->l_act) {
6483		case BWI_LED_ACT_ON:	/* Always on */
6484			on = 1;
6485			break;
6486		case BWI_LED_ACT_OFF:	/* Always off */
6487		case BWI_LED_ACT_5GHZ:	/* TODO: 11A */
6488			on = 0;
6489			break;
6490		default:
6491			on = 1;
6492			switch (nstate) {
6493			case IEEE80211_S_INIT:
6494				on = 0;
6495				break;
6496			case IEEE80211_S_RUN:
6497				if (led->l_act == BWI_LED_ACT_11G &&
6498				    ic->ic_curmode != IEEE80211_MODE_11G)
6499					on = 0;
6500				break;
6501			default:
6502				if (led->l_act == BWI_LED_ACT_ASSOC)
6503					on = 0;
6504				break;
6505			}
6506			break;
6507		}
6508
6509		val = bwi_led_onoff(led, val, on);
6510	}
6511	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6512}
6513
6514void
6515bwi_led_event(struct bwi_softc *sc, int event)
6516{
6517	struct bwi_led *led = sc->sc_blink_led;
6518	int rate;
6519
6520	if (event == BWI_LED_EVENT_POLL) {
6521		if ((led->l_flags & BWI_LED_F_POLLABLE) == 0)
6522			return;
6523		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
6524			return;
6525	}
6526
6527	sc->sc_led_ticks = ticks;
6528	if (sc->sc_led_blinking)
6529		return;
6530
6531	switch (event) {
6532	case BWI_LED_EVENT_RX:
6533		rate = sc->sc_rx_rate;
6534		break;
6535	case BWI_LED_EVENT_TX:
6536		rate = sc->sc_tx_rate;
6537		break;
6538	case BWI_LED_EVENT_POLL:
6539		rate = 0;
6540		break;
6541	default:
6542		panic("unknown LED event %d", event);
6543		break;
6544	}
6545	bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
6546	    bwi_led_duration[rate].off_dur);
6547}
6548
6549void
6550bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
6551{
6552	struct bwi_led *led = sc->sc_blink_led;
6553	uint16_t val;
6554
6555	val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6556	val = bwi_led_onoff(led, val, 1);
6557	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6558
6559	if (led->l_flags & BWI_LED_F_SLOW) {
6560		BWI_LED_SLOWDOWN(on_dur);
6561		BWI_LED_SLOWDOWN(off_dur);
6562	}
6563
6564	sc->sc_led_blinking = 1;
6565	sc->sc_led_blink_offdur = off_dur;
6566
6567	timeout_add(&sc->sc_led_blink_next_ch, on_dur);
6568}
6569
6570void
6571bwi_led_blink_next(void *xsc)
6572{
6573	struct bwi_softc *sc = xsc;
6574	uint16_t val;
6575
6576	val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6577	val = bwi_led_onoff(sc->sc_blink_led, val, 0);
6578	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6579
6580	timeout_add(&sc->sc_led_blink_end_ch, sc->sc_led_blink_offdur);
6581}
6582
6583void
6584bwi_led_blink_end(void *xsc)
6585{
6586	struct bwi_softc *sc = xsc;
6587
6588	sc->sc_led_blinking = 0;
6589}
6590
6591int
6592bwi_bbp_attach(struct bwi_softc *sc)
6593{
6594	uint16_t bbp_id, rw_type;
6595	uint8_t rw_rev;
6596	uint32_t info;
6597	int error, nregwin, i;
6598
6599	/*
6600	 * Get 0th regwin information
6601	 * NOTE: 0th regwin should exist
6602	 */
6603	error = bwi_regwin_select(sc, 0);
6604	if (error) {
6605		printf("%s: can't select regwin 0\n", sc->sc_dev.dv_xname);
6606		return (error);
6607	}
6608	bwi_regwin_info(sc, &rw_type, &rw_rev);
6609
6610	/*
6611	 * Find out BBP id
6612	 */
6613	bbp_id = 0;
6614	info = 0;
6615	if (rw_type == BWI_REGWIN_T_COM) {
6616		info = CSR_READ_4(sc, BWI_INFO);
6617		bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
6618
6619		BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
6620
6621		sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
6622	} else {
6623		uint16_t did = sc->sc_pci_did;
6624		uint8_t revid = sc->sc_pci_revid;
6625
6626		for (i = 0; i < nitems(bwi_bbpid_map); ++i) {
6627			if (did >= bwi_bbpid_map[i].did_min &&
6628			    did <= bwi_bbpid_map[i].did_max) {
6629				bbp_id = bwi_bbpid_map[i].bbp_id;
6630				break;
6631			}
6632		}
6633		if (bbp_id == 0) {
6634			printf("%s: no BBP id for device id 0x%04x\n",
6635			    sc->sc_dev.dv_xname, did);
6636			return (ENXIO);
6637		}
6638
6639		info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) |
6640		    __SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
6641	}
6642
6643	/*
6644	 * Find out number of regwins
6645	 */
6646	nregwin = 0;
6647	if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
6648		nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
6649	} else {
6650		for (i = 0; i < nitems(bwi_regwin_count); ++i) {
6651			if (bwi_regwin_count[i].bbp_id == bbp_id) {
6652				nregwin = bwi_regwin_count[i].nregwin;
6653				break;
6654			}
6655		}
6656		if (nregwin == 0) {
6657			printf("%s: no number of win for BBP id 0x%04x\n",
6658			    sc->sc_dev.dv_xname, bbp_id);
6659			return (ENXIO);
6660		}
6661	}
6662
6663	/* Record BBP id/rev for later using */
6664	sc->sc_bbp_id = bbp_id;
6665	sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
6666	sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
6667	DPRINTF(1, "%s: BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
6668	    sc->sc_dev.dv_xname, sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
6669	DPRINTF(1, "%s: nregwin %d, cap 0x%08x\n",
6670	    sc->sc_dev.dv_xname, nregwin, sc->sc_cap);
6671
6672	/*
6673	 * Create rest of the regwins
6674	 */
6675
6676	/* Don't re-create common regwin, if it is already created */
6677	i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
6678
6679	for (; i < nregwin; ++i) {
6680		/*
6681		 * Get regwin information
6682		 */
6683		error = bwi_regwin_select(sc, i);
6684		if (error) {
6685			printf("%s: can't select regwin %d\n",
6686			    sc->sc_dev.dv_xname, i);
6687			return (error);
6688		}
6689		bwi_regwin_info(sc, &rw_type, &rw_rev);
6690
6691		/*
6692		 * Try attach:
6693		 * 1) Bus (PCI/PCIE) regwin
6694		 * 2) MAC regwin
6695		 * Ignore rest types of regwin
6696		 */
6697		if (rw_type == BWI_REGWIN_T_BUSPCI ||
6698		    rw_type == BWI_REGWIN_T_BUSPCIE) {
6699			if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6700				printf("%s: bus regwin already exists\n",
6701				    sc->sc_dev.dv_xname);
6702			} else {
6703				BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
6704				    rw_type, rw_rev);
6705			}
6706		} else if (rw_type == BWI_REGWIN_T_MAC) {
6707			/* XXX ignore return value */
6708			bwi_mac_attach(sc, i, rw_rev);
6709		}
6710	}
6711
6712	/* At least one MAC shold exist */
6713	if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
6714		printf("%s: no MAC was found\n", sc->sc_dev.dv_xname);
6715		return (ENXIO);
6716	}
6717	KASSERT(sc->sc_nmac > 0);
6718
6719	/* Bus regwin must exist */
6720	if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6721		printf("%s: no bus regwin was found\n", sc->sc_dev.dv_xname);
6722		return (ENXIO);
6723	}
6724
6725	/* Start with first MAC */
6726	error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
6727	if (error)
6728		return (error);
6729
6730	return (0);
6731}
6732
6733int
6734bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6735{
6736	struct bwi_regwin *old, *bus;
6737	uint32_t val;
6738	int error;
6739
6740	bus = &sc->sc_bus_regwin;
6741	KASSERT(sc->sc_cur_regwin == &mac->mac_regwin);
6742
6743	/*
6744	 * Tell bus to generate requested interrupts
6745	 */
6746	if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6747		/*
6748		 * NOTE: Read BWI_FLAGS from MAC regwin
6749		 */
6750		val = CSR_READ_4(sc, BWI_FLAGS);
6751
6752		error = bwi_regwin_switch(sc, bus, &old);
6753		if (error)
6754			return (error);
6755
6756		CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
6757	} else {
6758		uint32_t mac_mask;
6759
6760		mac_mask = 1 << mac->mac_id;
6761
6762		error = bwi_regwin_switch(sc, bus, &old);
6763		if (error)
6764			return (error);
6765
6766		val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL);
6767		val |= mac_mask << 8;
6768		(sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val);
6769	}
6770
6771	if (sc->sc_flags & BWI_F_BUS_INITED)
6772		goto back;
6773
6774	if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6775		/*
6776		 * Enable prefetch and burst
6777		 */
6778		CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
6779		    BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
6780
6781		if (bus->rw_rev < 5) {
6782			struct bwi_regwin *com = &sc->sc_com_regwin;
6783
6784			/*
6785			 * Configure timeouts for bus operation
6786			 */
6787
6788			/*
6789			 * Set service timeout and request timeout
6790			 */
6791			CSR_SETBITS_4(sc, BWI_CONF_LO,
6792			    __SHIFTIN(BWI_CONF_LO_SERVTO,
6793			    BWI_CONF_LO_SERVTO_MASK) |
6794			    __SHIFTIN(BWI_CONF_LO_REQTO,
6795			    BWI_CONF_LO_REQTO_MASK));
6796
6797			/*
6798			 * If there is common regwin, we switch to that regwin
6799			 * and switch back to bus regwin once we have done.
6800			 */
6801			if (BWI_REGWIN_EXIST(com)) {
6802				error = bwi_regwin_switch(sc, com, NULL);
6803				if (error)
6804					return (error);
6805			}
6806
6807			/* Let bus know what we have changed */
6808			CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
6809			CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
6810			CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
6811			CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
6812
6813			if (BWI_REGWIN_EXIST(com)) {
6814				error = bwi_regwin_switch(sc, bus, NULL);
6815				if (error)
6816					return (error);
6817			}
6818		} else if (bus->rw_rev >= 11) {
6819			/*
6820			 * Enable memory read multiple
6821			 */
6822			CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
6823		}
6824	} else {
6825		/* TODO: PCIE */
6826	}
6827
6828	sc->sc_flags |= BWI_F_BUS_INITED;
6829back:
6830	return (bwi_regwin_switch(sc, old, NULL));
6831}
6832
6833void
6834bwi_get_card_flags(struct bwi_softc *sc)
6835{
6836	sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
6837	if (sc->sc_card_flags == 0xffff)
6838		sc->sc_card_flags = 0;
6839
6840	if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
6841	    sc->sc_pci_subdid == 0x4e && /* XXX */
6842	    sc->sc_pci_revid > 0x40)
6843		sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
6844
6845	DPRINTF(1, "%s: card flags 0x%04x\n",
6846	    sc->sc_dev.dv_xname, sc->sc_card_flags);
6847}
6848
6849void
6850bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
6851{
6852	int i;
6853
6854	for (i = 0; i < 3; ++i) {
6855		*((uint16_t *)eaddr + i) =
6856		    htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
6857	}
6858}
6859
6860void
6861bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
6862{
6863	struct bwi_regwin *com;
6864	uint32_t val;
6865	uint div;
6866	int src;
6867
6868	bzero(freq, sizeof(*freq));
6869	com = &sc->sc_com_regwin;
6870
6871	KASSERT(BWI_REGWIN_EXIST(com));
6872	KASSERT(sc->sc_cur_regwin == com);
6873	KASSERT(sc->sc_cap & BWI_CAP_CLKMODE);
6874
6875	/*
6876	 * Calculate clock frequency
6877	 */
6878	src = -1;
6879	div = 0;
6880	if (com->rw_rev < 6) {
6881		val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6882		if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
6883			src = BWI_CLKSRC_PCI;
6884			div = 64;
6885		} else {
6886			src = BWI_CLKSRC_CS_OSC;
6887			div = 32;
6888		}
6889	} else if (com->rw_rev < 10) {
6890		val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6891
6892		src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
6893		if (src == BWI_CLKSRC_LP_OSC)
6894			div = 1;
6895		else {
6896			div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
6897
6898			/* Unknown source */
6899			if (src >= BWI_CLKSRC_MAX)
6900				src = BWI_CLKSRC_CS_OSC;
6901		}
6902	} else {
6903		val = CSR_READ_4(sc, BWI_CLOCK_INFO);
6904
6905		src = BWI_CLKSRC_CS_OSC;
6906		div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
6907	}
6908
6909	KASSERT(src >= 0 && src < BWI_CLKSRC_MAX);
6910	KASSERT(div != 0);
6911
6912	DPRINTF(1, "%s: clksrc %s\n",
6913	    sc->sc_dev.dv_xname,
6914	    src == BWI_CLKSRC_PCI ? "PCI" :
6915	    (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
6916
6917	freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
6918	freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
6919
6920	DPRINTF(1, "%s: clkfreq min %u, max %u\n",
6921	    sc->sc_dev.dv_xname, freq->clkfreq_min, freq->clkfreq_max);
6922}
6923
6924int
6925bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
6926{
6927	struct bwi_regwin *old, *com;
6928	uint32_t clk_ctrl, clk_src;
6929	int error, pwr_off = 0;
6930
6931	com = &sc->sc_com_regwin;
6932	if (!BWI_REGWIN_EXIST(com))
6933		return (0);
6934
6935	if (com->rw_rev >= 10 || com->rw_rev < 6)
6936		return (0);
6937
6938	/*
6939	 * For common regwin whose rev is [6, 10), the chip
6940	 * must be capable to change clock mode.
6941	 */
6942	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
6943		return (0);
6944
6945	error = bwi_regwin_switch(sc, com, &old);
6946	if (error)
6947		return (error);
6948
6949	if (clk_mode == BWI_CLOCK_MODE_FAST)
6950		bwi_power_on(sc, 0);	/* Don't turn on PLL */
6951
6952	clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6953	clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
6954
6955	switch (clk_mode) {
6956	case BWI_CLOCK_MODE_FAST:
6957		clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
6958		clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
6959		break;
6960	case BWI_CLOCK_MODE_SLOW:
6961		clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
6962		break;
6963	case BWI_CLOCK_MODE_DYN:
6964		clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
6965		    BWI_CLOCK_CTRL_IGNPLL |
6966		    BWI_CLOCK_CTRL_NODYN);
6967		if (clk_src != BWI_CLKSRC_CS_OSC) {
6968			clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
6969			pwr_off = 1;
6970		}
6971		break;
6972	}
6973	CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
6974
6975	if (pwr_off)
6976		bwi_power_off(sc, 0);	/* Leave PLL as it is */
6977
6978	return (bwi_regwin_switch(sc, old, NULL));
6979}
6980
6981int
6982bwi_set_clock_delay(struct bwi_softc *sc)
6983{
6984	struct bwi_regwin *old, *com;
6985	int error;
6986
6987	com = &sc->sc_com_regwin;
6988	if (!BWI_REGWIN_EXIST(com))
6989		return (0);
6990
6991	error = bwi_regwin_switch(sc, com, &old);
6992	if (error)
6993		return (error);
6994
6995	if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
6996		if (sc->sc_bbp_rev == 0)
6997			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
6998		else if (sc->sc_bbp_rev == 1)
6999			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
7000	}
7001
7002	if (sc->sc_cap & BWI_CAP_CLKMODE) {
7003		if (com->rw_rev >= 10)
7004			CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
7005		else {
7006			struct bwi_clock_freq freq;
7007
7008			bwi_get_clock_freq(sc, &freq);
7009			CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
7010			    howmany(freq.clkfreq_max * 150, 1000000));
7011			CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
7012			    howmany(freq.clkfreq_max * 15, 1000000));
7013		}
7014	}
7015
7016	return (bwi_regwin_switch(sc, old, NULL));
7017}
7018
7019int
7020bwi_init(struct ifnet *ifp)
7021{
7022	struct bwi_softc *sc = ifp->if_softc;
7023
7024	bwi_init_statechg(sc, 1);
7025
7026	return (0);
7027}
7028
7029void
7030bwi_init_statechg(struct bwi_softc *sc, int statechg)
7031{
7032	struct ieee80211com *ic = &sc->sc_ic;
7033	struct ifnet *ifp = &ic->ic_if;
7034	struct bwi_mac *mac;
7035	int error;
7036
7037	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7038
7039	error = bwi_stop(sc, statechg);
7040	if (error) {
7041		DPRINTF(1, "%s: can't stop\n", sc->sc_dev.dv_xname);
7042		return;
7043	}
7044
7045	/* power on cardbus socket */
7046	if (sc->sc_enable != NULL)
7047		(*sc->sc_enable)(sc);
7048
7049	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
7050
7051	/* TODO: 2 MAC */
7052
7053	mac = &sc->sc_mac[0];
7054	error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
7055	if (error)
7056		goto back;
7057
7058	error = bwi_mac_init(mac);
7059	if (error)
7060		goto back;
7061
7062	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
7063
7064	IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
7065
7066	bwi_set_bssid(sc, bwi_zero_addr);	/* Clear BSSID */
7067	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr);
7068
7069	bwi_mac_reset_hwkeys(mac);
7070
7071	if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
7072		int i;
7073
7074#define NRETRY	1000
7075		/*
7076		 * Drain any possible pending TX status
7077		 */
7078		for (i = 0; i < NRETRY; ++i) {
7079			if ((CSR_READ_4(sc, BWI_TXSTATUS_0) &
7080			     BWI_TXSTATUS_0_MORE) == 0)
7081				break;
7082			CSR_READ_4(sc, BWI_TXSTATUS_1);
7083		}
7084		if (i == NRETRY)
7085			printf("%s: can't drain TX status\n",
7086			    sc->sc_dev.dv_xname);
7087#undef NRETRY
7088	}
7089
7090	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
7091		bwi_mac_updateslot(mac, 1);
7092
7093	/* Start MAC */
7094	error = bwi_mac_start(mac);
7095	if (error)
7096		goto back;
7097
7098	/* Enable intrs */
7099	bwi_enable_intrs(sc, BWI_INIT_INTRS);
7100
7101	ifp->if_flags |= IFF_RUNNING;
7102	ifp->if_flags &= ~IFF_OACTIVE;
7103
7104	if (statechg) {
7105		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7106			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
7107		} else {
7108			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
7109		}
7110	} else {
7111		ieee80211_new_state(ic, ic->ic_state, -1);
7112	}
7113
7114back:
7115	if (error)
7116		bwi_stop(sc, 1);
7117	else
7118		bwi_start(ifp);
7119}
7120
7121int
7122bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
7123{
7124	struct bwi_softc *sc = ifp->if_softc;
7125	struct ieee80211com *ic = &sc->sc_ic;
7126	struct ifaddr *ifa;
7127	struct ifreq *ifr;
7128	int s, error = 0;
7129	uint8_t chan;
7130
7131	s = splnet();
7132
7133	switch (cmd) {
7134	case SIOCSIFADDR:
7135		ifa = (struct ifaddr *)data;
7136		ifp->if_flags |= IFF_UP;
7137		if (ifa->ifa_addr->sa_family == AF_INET)
7138			arp_ifinit(&ic->ic_ac, ifa);
7139		/* FALLTHROUGH */
7140	case SIOCSIFFLAGS:
7141		if (ifp->if_flags & IFF_UP) {
7142			if ((ifp->if_flags & IFF_RUNNING) == 0)
7143				bwi_init(ifp);
7144		} else {
7145			if (ifp->if_flags & IFF_RUNNING)
7146				bwi_stop(sc, 1);
7147		}
7148		break;
7149        case SIOCADDMULTI:
7150        case SIOCDELMULTI:
7151		ifr = (struct ifreq *)data;
7152		error = (cmd == SIOCADDMULTI) ?
7153		    ether_addmulti(ifr, &ic->ic_ac) :
7154		    ether_delmulti(ifr, &ic->ic_ac);
7155
7156		if (error == ENETRESET)
7157			error = 0;
7158		break;
7159	case SIOCS80211CHANNEL:
7160		/* allow fast channel switching in monitor mode */
7161		error = ieee80211_ioctl(ifp, cmd, data);
7162		if (error == ENETRESET &&
7163		    ic->ic_opmode == IEEE80211_M_MONITOR) {
7164			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7165			    (IFF_UP | IFF_RUNNING)) {
7166				ic->ic_bss->ni_chan = ic->ic_ibss_chan;
7167				chan = ieee80211_chan2ieee(ic,
7168				    ic->ic_bss->ni_chan);
7169				bwi_set_chan(sc, chan);
7170			}
7171			error = 0;
7172		}
7173		break;
7174	default:
7175		error = ieee80211_ioctl(ifp, cmd, data);
7176		break;
7177	}
7178
7179	if (error == ENETRESET) {
7180		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7181		    (IFF_UP | IFF_RUNNING))
7182			bwi_init(ifp);
7183		error = 0;
7184	}
7185
7186	splx(s);
7187
7188	return (error);
7189}
7190
7191void
7192bwi_start(struct ifnet *ifp)
7193{
7194	struct bwi_softc *sc = ifp->if_softc;
7195	struct ieee80211com *ic = &sc->sc_ic;
7196	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
7197	int trans, idx;
7198
7199	if ((ifp->if_flags & IFF_OACTIVE) || (ifp->if_flags & IFF_RUNNING) == 0)
7200		return;
7201
7202	trans = 0;
7203	idx = tbd->tbd_idx;
7204
7205	while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
7206		struct ieee80211_frame *wh;
7207		struct ieee80211_node *ni;
7208		struct ieee80211_key *k;
7209		struct mbuf *m;
7210		int mgt_pkt = 0;
7211
7212		IF_POLL(&ic->ic_mgtq, m);
7213		if (m != NULL) {
7214			IF_DEQUEUE(&ic->ic_mgtq, m);
7215
7216			ni = m->m_pkthdr.ph_cookie;
7217
7218			mgt_pkt = 1;
7219		} else {
7220			struct ether_header *eh;
7221
7222			if (ic->ic_state != IEEE80211_S_RUN)
7223				break;
7224
7225			IFQ_POLL(&ifp->if_snd, m);
7226			if (m == NULL)
7227				break;
7228
7229			IFQ_DEQUEUE(&ifp->if_snd, m);
7230
7231			if (m->m_len < sizeof(*eh)) {
7232				m = m_pullup(m, sizeof(*eh));
7233				if (m == NULL) {
7234					ifp->if_oerrors++;
7235					continue;
7236				}
7237			}
7238			eh = mtod(m, struct ether_header *);
7239
7240			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
7241			if (ni == NULL) {
7242				m_freem(m);
7243				ifp->if_oerrors++;
7244				continue;
7245			}
7246
7247			/* TODO: PS */
7248#if NBPFILTER > 0
7249			if (ifp->if_bpf != NULL)
7250				bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
7251#endif
7252			m = ieee80211_encap(ifp, m, &ni);
7253			if (m == NULL)
7254				continue;
7255		}
7256#if NBPFILTER > 0
7257		if (ic->ic_rawbpf != NULL)
7258			bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
7259#endif
7260		wh = mtod(m, struct ieee80211_frame *);
7261		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
7262			k = ieee80211_get_txkey(ic, wh, ni);
7263			if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
7264				return;
7265		}
7266		wh = NULL;	/* Catch any invalid use */
7267
7268		if (mgt_pkt) {
7269			ieee80211_release_node(ic, ni);
7270			ni = NULL;
7271		}
7272
7273		if (bwi_encap(sc, idx, m, ni) != 0) {
7274			/* 'm' is freed in bwi_encap() if we reach here */
7275			if (ni != NULL)
7276				ieee80211_release_node(ic, ni);
7277			ifp->if_oerrors++;
7278			continue;
7279		}
7280
7281		trans = 1;
7282		tbd->tbd_used++;
7283		idx = (idx + 1) % BWI_TX_NDESC;
7284
7285		if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
7286			ifp->if_flags |= IFF_OACTIVE;
7287			break;
7288		}
7289	}
7290	tbd->tbd_idx = idx;
7291
7292	if (trans)
7293		sc->sc_tx_timer = 5;
7294	ifp->if_timer = 1;
7295}
7296
7297void
7298bwi_watchdog(struct ifnet *ifp)
7299{
7300	struct bwi_softc *sc = ifp->if_softc;
7301
7302	ifp->if_timer = 0;
7303
7304	if ((ifp->if_flags & IFF_RUNNING) == 0)
7305		return;
7306
7307	if (sc->sc_tx_timer) {
7308		if (--sc->sc_tx_timer == 0) {
7309			printf("%s: watchdog timeout\n",
7310			    sc->sc_dev.dv_xname);
7311			ifp->if_oerrors++;
7312			/* TODO */
7313		} else
7314			ifp->if_timer = 1;
7315	}
7316
7317	ieee80211_watchdog(ifp);
7318}
7319
7320void
7321bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
7322{
7323	timeout_del(&sc->sc_scan_ch);
7324	timeout_del(&sc->sc_calib_ch);
7325
7326	bwi_led_newstate(sc, nstate);
7327
7328	if (nstate == IEEE80211_S_INIT)
7329		sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
7330}
7331
7332int
7333bwi_stop(struct bwi_softc *sc, int state_chg)
7334{
7335	struct ieee80211com *ic = &sc->sc_ic;
7336	struct ifnet *ifp = &ic->ic_if;
7337	struct bwi_mac *mac;
7338	int i, error, pwr_off = 0;
7339
7340	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7341
7342	if (state_chg)
7343		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
7344	else
7345		bwi_newstate_begin(sc, IEEE80211_S_INIT);
7346
7347	if (ifp->if_flags & IFF_RUNNING) {
7348		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7349		mac = (struct bwi_mac *)sc->sc_cur_regwin;
7350
7351		bwi_disable_intrs(sc, BWI_ALL_INTRS);
7352		CSR_READ_4(sc, BWI_MAC_INTR_MASK);
7353		bwi_mac_stop(mac);
7354	}
7355
7356	for (i = 0; i < sc->sc_nmac; ++i) {
7357		struct bwi_regwin *old_rw;
7358
7359		mac = &sc->sc_mac[i];
7360		if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
7361			continue;
7362
7363		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
7364		if (error)
7365			continue;
7366
7367		bwi_mac_shutdown(mac);
7368		pwr_off = 1;
7369
7370		bwi_regwin_switch(sc, old_rw, NULL);
7371	}
7372
7373	if (pwr_off)
7374		bwi_bbp_power_off(sc);
7375
7376	sc->sc_tx_timer = 0;
7377	ifp->if_timer = 0;
7378	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
7379
7380	/* power off cardbus socket */
7381	if (sc->sc_disable)
7382		sc->sc_disable(sc);
7383
7384	return (0);
7385}
7386
7387int
7388bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7389{
7390	struct bwi_softc *sc = ic->ic_if.if_softc;
7391	struct ieee80211_node *ni;
7392	int error;
7393	uint8_t chan;
7394
7395	timeout_del(&sc->sc_amrr_ch);
7396
7397	bwi_newstate_begin(sc, nstate);
7398
7399	if (nstate == IEEE80211_S_INIT)
7400		goto back;
7401
7402	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
7403	error = bwi_set_chan(sc, chan);
7404	if (error) {
7405		printf("%s: can't set channel to %u\n",
7406		    sc->sc_dev.dv_xname,
7407		    ieee80211_chan2ieee(ic, ic->ic_des_chan));
7408		return (error);
7409	}
7410
7411	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7412		/* Nothing to do */
7413	} else if (nstate == IEEE80211_S_RUN) {
7414		struct bwi_mac *mac;
7415
7416		ni = ic->ic_bss;
7417
7418		bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
7419
7420		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7421		mac = (struct bwi_mac *)sc->sc_cur_regwin;
7422
7423		/* Initial TX power calibration */
7424		bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
7425#ifdef notyet
7426		sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
7427#else
7428		sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
7429#endif
7430		if (ic->ic_opmode == IEEE80211_M_STA) {
7431			/* fake a join to init the tx rate */
7432			bwi_newassoc(ic, ni, 1);
7433		}
7434
7435		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7436			/* start automatic rate control timer */
7437			if (ic->ic_fixed_rate == -1)
7438				timeout_add_msec(&sc->sc_amrr_ch, 500);
7439		}
7440	} else
7441		bwi_set_bssid(sc, bwi_zero_addr);
7442
7443back:
7444	error = sc->sc_newstate(ic, nstate, arg);
7445
7446	if (nstate == IEEE80211_S_SCAN) {
7447		timeout_add_msec(&sc->sc_scan_ch, sc->sc_dwell_time);
7448	} else if (nstate == IEEE80211_S_RUN) {
7449		/* XXX 15 seconds */
7450		timeout_add_sec(&sc->sc_calib_ch, 1);
7451	}
7452
7453	return (error);
7454}
7455
7456int
7457bwi_media_change(struct ifnet *ifp)
7458{
7459	int error;
7460
7461	error = ieee80211_media_change(ifp);
7462	if (error != ENETRESET)
7463		return (error);
7464
7465	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
7466		bwi_init(ifp);
7467
7468	return (0);
7469}
7470
7471void
7472bwi_iter_func(void *arg, struct ieee80211_node *ni)
7473{
7474	struct bwi_softc *sc = arg;
7475	struct bwi_node *bn = (struct bwi_node *)ni;
7476
7477	ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
7478}
7479
7480void
7481bwi_amrr_timeout(void *arg)
7482{
7483	struct bwi_softc *sc = arg;
7484	struct ieee80211com *ic = &sc->sc_ic;
7485
7486	if (ic->ic_opmode == IEEE80211_M_STA)
7487		bwi_iter_func(sc, ic->ic_bss);
7488#ifndef IEEE80211_STA_ONLY
7489	else
7490		ieee80211_iterate_nodes(ic, bwi_iter_func, sc);
7491#endif
7492
7493	timeout_add_msec(&sc->sc_amrr_ch, 500);
7494}
7495
7496void
7497bwi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
7498{
7499	struct bwi_softc *sc = ic->ic_if.if_softc;
7500	int i;
7501
7502	DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7503
7504	ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
7505
7506	/* set rate to some reasonable initial value */
7507	for (i = ni->ni_rates.rs_nrates - 1;
7508	    i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
7509	    i--);
7510
7511	ni->ni_txrate = i;
7512}
7513
7514struct ieee80211_node *
7515bwi_node_alloc(struct ieee80211com *ic)
7516{
7517	struct bwi_node *bn;
7518
7519	bn = malloc(sizeof(*bn), M_DEVBUF, M_NOWAIT | M_ZERO);
7520	if (bn == NULL)
7521		return (NULL);
7522
7523	return ((struct ieee80211_node *)bn);
7524}
7525
7526struct uvm_constraint_range bwi_constraint = { 0x0, (0x40000000 - 1) };
7527struct kmem_pa_mode bwi_pa_mode = {
7528	.kp_align = BWI_RING_ALIGN,
7529	.kp_constraint = &bwi_constraint,
7530	.kp_zero = 1
7531};
7532
7533int
7534bwi_dma_alloc(struct bwi_softc *sc)
7535{
7536	int error, i, has_txstats;
7537	bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
7538	uint32_t txrx_ctrl_step = 0;
7539	int s;
7540
7541	has_txstats = 0;
7542	for (i = 0; i < sc->sc_nmac; ++i) {
7543		if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
7544			has_txstats = 1;
7545			break;
7546		}
7547	}
7548
7549	switch (sc->sc_bus_space) {
7550	case BWI_BUS_SPACE_30BIT:
7551		/*
7552		 * 30bit devices must use bounce buffers but
7553		 * otherwise work like 32bit devices.
7554		 */
7555		sc->sc_newbuf = bwi_newbuf30;
7556
7557		/* XXX implement txstats for 30bit? */
7558		has_txstats = 0;
7559
7560		/* FALLTHROUGH */
7561	case BWI_BUS_SPACE_32BIT:
7562		desc_sz = sizeof(struct bwi_desc32);
7563		txrx_ctrl_step = 0x20;
7564
7565		sc->sc_init_tx_ring = bwi_init_tx_ring32;
7566		sc->sc_free_tx_ring = bwi_free_tx_ring32;
7567		sc->sc_init_rx_ring = bwi_init_rx_ring32;
7568		sc->sc_free_rx_ring = bwi_free_rx_ring32;
7569		if (sc->sc_newbuf == NULL)
7570			sc->sc_newbuf = bwi_newbuf;
7571		sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
7572		sc->sc_setup_txdesc = bwi_setup_tx_desc32;
7573		sc->sc_rxeof = bwi_rxeof32;
7574		sc->sc_start_tx = bwi_start_tx32;
7575		if (has_txstats) {
7576			sc->sc_init_txstats = bwi_init_txstats32;
7577			sc->sc_free_txstats = bwi_free_txstats32;
7578			sc->sc_txeof_status = bwi_txeof_status32;
7579		}
7580		break;
7581
7582	case BWI_BUS_SPACE_64BIT:
7583		desc_sz = sizeof(struct bwi_desc64);
7584		txrx_ctrl_step = 0x40;
7585
7586		sc->sc_init_tx_ring = bwi_init_tx_ring64;
7587		sc->sc_free_tx_ring = bwi_free_tx_ring64;
7588		sc->sc_init_rx_ring = bwi_init_rx_ring64;
7589		sc->sc_free_rx_ring = bwi_free_rx_ring64;
7590		sc->sc_newbuf = bwi_newbuf;
7591		sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
7592		sc->sc_setup_txdesc = bwi_setup_tx_desc64;
7593		sc->sc_rxeof = bwi_rxeof64;
7594		sc->sc_start_tx = bwi_start_tx64;
7595		if (has_txstats) {
7596			sc->sc_init_txstats = bwi_init_txstats64;
7597			sc->sc_free_txstats = bwi_free_txstats64;
7598			sc->sc_txeof_status = bwi_txeof_status64;
7599		}
7600		break;
7601	default:
7602		panic("unsupported bus space type %d", sc->sc_bus_space);
7603	}
7604
7605	KASSERT(desc_sz != 0);
7606	KASSERT(txrx_ctrl_step != 0);
7607
7608	tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
7609	rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
7610
7611	s = splvm();
7612
7613#define TXRX_CTRL(idx)	(BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
7614	/*
7615	 * Create TX ring DMA stuffs
7616	 */
7617	for (i = 0; i < BWI_TX_NRING; ++i) {
7618		error = bwi_dma_ring_alloc(sc,
7619		    &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
7620		if (error) {
7621			printf("%s: %dth TX ring DMA alloc failed\n",
7622			    sc->sc_dev.dv_xname, i);
7623			bwi_dma_free(sc);
7624			splx(s);
7625			return (error);
7626		}
7627	}
7628
7629	/*
7630	 * Create RX ring DMA stuffs
7631	 */
7632	error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
7633	    rx_ring_sz, TXRX_CTRL(0));
7634	if (error) {
7635		printf("%s: RX ring DMA alloc failed\n", sc->sc_dev.dv_xname);
7636		bwi_dma_free(sc);
7637		splx(s);
7638		return (error);
7639	}
7640
7641	if (has_txstats) {
7642		error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
7643		if (error) {
7644			printf("%s: TX stats DMA alloc failed\n",
7645			    sc->sc_dev.dv_xname);
7646			bwi_dma_free(sc);
7647			splx(s);
7648			return (error);
7649		}
7650	}
7651#undef TXRX_CTRL
7652
7653	if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT)
7654		error = bwi_dma_mbuf_create30(sc);
7655	else
7656		error = bwi_dma_mbuf_create(sc);
7657	if (error)
7658		bwi_dma_free(sc);
7659
7660	splx(s);
7661
7662	return (error);
7663}
7664
7665void
7666bwi_dma_free(struct bwi_softc *sc)
7667{
7668	struct bwi_ring_data *rd;
7669	int i;
7670
7671	for (i = 0; i < BWI_TX_NRING; ++i) {
7672		rd = &sc->sc_tx_rdata[i];
7673
7674		if (rd->rdata_desc != NULL) {
7675			bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
7676			km_free(rd->rdata_desc, rd->rdata_ring_sz,
7677			    &kv_intrsafe, &bwi_pa_mode);
7678			rd->rdata_desc = NULL;
7679		}
7680	}
7681
7682	rd = &sc->sc_rx_rdata;
7683
7684	if (rd->rdata_desc != NULL) {
7685		bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
7686		km_free(rd->rdata_desc, rd->rdata_ring_sz,
7687		    &kv_intrsafe, &bwi_pa_mode);
7688		rd->rdata_desc = NULL;
7689	}
7690
7691	bwi_dma_txstats_free(sc);
7692
7693	if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
7694		for (i = 0; i < BWI_TX_NRING; ++i) {
7695			if (sc->sc_bounce_tx_data[i] != NULL) {
7696				km_free(sc->sc_bounce_tx_data[i],
7697				    BWI_TX_NDESC * MCLBYTES,
7698				    &kv_intrsafe, &bwi_pa_mode);
7699				sc->sc_bounce_tx_data[i] = NULL;
7700			}
7701		}
7702
7703		if (sc->sc_bounce_rx_data != NULL) {
7704			km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC * MCLBYTES,
7705			    &kv_intrsafe, &bwi_pa_mode);
7706			sc->sc_bounce_rx_data = NULL;
7707		}
7708	}
7709}
7710
7711int
7712bwi_dma_ring_alloc(struct bwi_softc *sc,
7713    struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
7714{
7715	int error;
7716
7717	/* Allocate rings below 1GB so 30bit devices can access them.*/
7718	rd->rdata_desc = (caddr_t)km_alloc(size, &kv_intrsafe, &bwi_pa_mode,
7719	    &kd_nowait);
7720	if (rd->rdata_desc == NULL) {
7721		printf(": could not allocate ring DMA memory\n");
7722		return (ENOMEM);
7723	}
7724
7725	error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
7726	    BUS_DMA_NOWAIT, &rd->rdata_dmap);
7727	if (error) {
7728		printf(": cannot create ring DMA map (error %d)\n", error);
7729		km_free(rd->rdata_desc, size, &kv_intrsafe, &bwi_pa_mode);
7730		rd->rdata_desc = NULL;
7731		return (error);
7732	}
7733
7734	error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
7735	    size, NULL, BUS_DMA_WAITOK);
7736	if (error) {
7737		printf("%s: can't load DMA mem\n", sc->sc_dev.dv_xname);
7738		bus_dmamap_destroy(sc->sc_dmat, rd->rdata_dmap);
7739		km_free(rd->rdata_desc, size, &kv_intrsafe, &bwi_pa_mode);
7740		rd->rdata_desc = NULL;
7741		return (error);
7742	}
7743
7744	rd->rdata_ring_sz = size;
7745	rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
7746	rd->rdata_txrx_ctrl = txrx_ctrl;
7747
7748	return (0);
7749}
7750
7751int
7752bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
7753    bus_size_t desc_sz)
7754{
7755	struct bwi_txstats_data *st;
7756	bus_size_t dma_size;
7757	int error, nsegs;
7758
7759	st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
7760	sc->sc_txstats = st;
7761
7762	/*
7763	 * Create TX stats descriptor DMA stuffs
7764	 */
7765	dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
7766
7767	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7768	    BUS_DMA_NOWAIT, &st->stats_ring_dmap);
7769	if (error) {
7770		printf("%s: can't create txstats ring DMA mem\n",
7771		    sc->sc_dev.dv_xname);
7772		return (error);
7773	}
7774
7775	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
7776	     &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
7777	if (error) {
7778		printf("%s: can't allocate txstats ring DMA mem\n",
7779		    sc->sc_dev.dv_xname);
7780		return (error);
7781	}
7782
7783	error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
7784	    dma_size, (caddr_t *)&st->stats_ring, BUS_DMA_NOWAIT);
7785	if (error) {
7786		printf("%s: can't map txstats ring DMA mem\n",
7787		    sc->sc_dev.dv_xname);
7788		return (error);
7789	}
7790
7791	error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
7792	    st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
7793	if (error) {
7794		printf("%s: can't load txstats ring DMA mem\n",
7795		    sc->sc_dev.dv_xname);
7796		bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
7797		return (error);
7798	}
7799
7800	st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
7801
7802	/*
7803	 * Create TX stats DMA stuffs
7804	 */
7805	dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
7806	    BWI_ALIGN);
7807
7808	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7809	    BUS_DMA_NOWAIT, &st->stats_dmap);
7810	if (error) {
7811		printf("%s: can't create txstats ring DMA mem\n",
7812		    sc->sc_dev.dv_xname);
7813		return (error);
7814	}
7815	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
7816	    &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
7817	if (error) {
7818		printf("%s: can't allocate txstats DMA mem\n",
7819		    sc->sc_dev.dv_xname);
7820		return (error);
7821	}
7822
7823	error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
7824	    dma_size, (caddr_t *)&st->stats, BUS_DMA_NOWAIT);
7825	if (error) {
7826		printf("%s: can't map txstats DMA mem\n", sc->sc_dev.dv_xname);
7827		return (error);
7828	}
7829
7830	error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
7831	    dma_size, NULL, BUS_DMA_WAITOK);
7832	if (error) {
7833		printf("%s: can't load txstats DMA mem\n", sc->sc_dev.dv_xname);
7834		bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
7835		return (error);
7836	}
7837
7838	st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
7839	st->stats_ctrl_base = ctrl_base;
7840
7841	return (0);
7842}
7843
7844void
7845bwi_dma_txstats_free(struct bwi_softc *sc)
7846{
7847	struct bwi_txstats_data *st;
7848
7849	if (sc->sc_txstats == NULL)
7850		return;
7851	st = sc->sc_txstats;
7852
7853	bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
7854	bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
7855
7856	bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
7857	bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
7858
7859	free(st, M_DEVBUF, 0);
7860}
7861
7862int
7863bwi_dma_mbuf_create30(struct bwi_softc *sc)
7864{
7865	int i, j, k, error;
7866
7867	for (i = 0; i < BWI_TX_NRING; ++i) {
7868		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7869
7870		sc->sc_bounce_tx_data[i] = (caddr_t)km_alloc(
7871		    BWI_TX_NDESC * MCLBYTES, &kv_intrsafe,
7872		    &bwi_pa_mode, &kd_waitok);
7873		if (sc->sc_bounce_tx_data[i] == NULL) {
7874			printf(": could not allocate TX mbuf bounce buffer\n");
7875			error = ENOMEM;
7876			break;
7877		}
7878
7879		for (j = 0; j < BWI_TX_NDESC; ++j) {
7880			error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
7881			    1, MCLBYTES, 0, BUS_DMA_NOWAIT,
7882			    &tbd->tbd_buf[j].tb_dmap);
7883			if (error) {
7884				printf(": cannot create TX mbuf DMA map\n");
7885				for (k = 0; k < j; ++k) {
7886					bus_dmamap_destroy(sc->sc_dmat,
7887					    tbd->tbd_buf[k].tb_dmap);
7888				}
7889				break;
7890			}
7891		}
7892	}
7893	if (error) {
7894		bwi_dma_mbuf_destroy(sc, i, 0);
7895		for (j = 0; j < i; ++j)
7896			km_free(sc->sc_bounce_tx_data[j], BWI_TX_NDESC,
7897			    &kv_intrsafe, &bwi_pa_mode);
7898		return (error);
7899	}
7900
7901	for (i = 0; i < BWI_TX_NRING; ++i) {
7902		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7903
7904		for (j = 0; j < BWI_TX_NDESC; ++j) {
7905			struct bwi_txbuf *tb = &tbd->tbd_buf[j];
7906
7907			error = bus_dmamap_load(sc->sc_dmat, tb->tb_dmap,
7908			    sc->sc_bounce_tx_data[i] + (MCLBYTES * j),
7909			    MCLBYTES, NULL, BUS_DMA_NOWAIT);
7910			if (error) {
7911				printf(": cannot create TX mbuf DMA map\n");
7912				for (k = 0; k < j; ++k) {
7913					bus_dmamap_destroy(sc->sc_dmat,
7914					    tbd->tbd_buf[k].tb_dmap);
7915				}
7916				break;
7917			}
7918		}
7919	}
7920	if (error) {
7921		bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 0);
7922		for (i = 0; i < BWI_TX_NRING; ++i)
7923			km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC,
7924			    &kv_intrsafe, &bwi_pa_mode);
7925		return (error);
7926	}
7927
7928	sc->sc_bounce_rx_data = (caddr_t)km_alloc(BWI_RX_NDESC * MCLBYTES,
7929	    &kv_intrsafe, &bwi_pa_mode, &kd_waitok);
7930	if (sc->sc_bounce_rx_data == NULL) {
7931		printf(": could not allocate RX mbuf bounce buffer\n");
7932		bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 0);
7933		for (i = 0; i < BWI_TX_NRING; ++i)
7934			km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC,
7935			    &kv_intrsafe, &bwi_pa_mode);
7936		return (ENOMEM);
7937	}
7938
7939	for (i = 0; i < BWI_RX_NDESC; ++i) {
7940		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
7941		    MCLBYTES, 0, BUS_DMA_NOWAIT,
7942		    &sc->sc_rx_bdata.rbd_buf[i].rb_dmap);
7943		if (error) {
7944			printf(": cannot create RX mbuf DMA map\n");
7945			for (j = 0; j < i; ++j) {
7946				bus_dmamap_destroy(sc->sc_dmat,
7947				    sc->sc_rx_bdata.rbd_buf[j].rb_dmap);
7948			}
7949			break;
7950		}
7951	}
7952	if (error) {
7953		bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 0);
7954		for (i = 0; i < BWI_TX_NRING; ++i)
7955			km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC,
7956			    &kv_intrsafe, &bwi_pa_mode);
7957		km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC * MCLBYTES,
7958		    &kv_intrsafe, &bwi_pa_mode);
7959		return (error);
7960	}
7961
7962	for (i = 0; i < BWI_RX_NDESC; ++i) {
7963		error = bwi_newbuf30(sc, i, 1);
7964		if (error) {
7965			printf(": cannot create RX mbuf DMA map\n");
7966			break;
7967		}
7968	}
7969	if (error) {
7970		bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
7971		for (i = 0; i < BWI_TX_NRING; ++i)
7972			km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC,
7973			    &kv_intrsafe, &bwi_pa_mode);
7974		km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC * MCLBYTES,
7975		    &kv_intrsafe, &bwi_pa_mode);
7976		return (error);
7977	}
7978
7979	return (0);
7980}
7981
7982int
7983bwi_dma_mbuf_create(struct bwi_softc *sc)
7984{
7985	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7986	int i, j, k, ntx, error;
7987
7988	ntx = 0;
7989
7990	/*
7991	 * Create TX mbuf DMA map
7992	 */
7993	for (i = 0; i < BWI_TX_NRING; ++i) {
7994		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7995
7996		for (j = 0; j < BWI_TX_NDESC; ++j) {
7997			error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
7998			    0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
7999			if (error) {
8000				printf(
8001				    "%s: can't create %dth tbd, %dth DMA map\n",
8002				    sc->sc_dev.dv_xname, i, j);
8003				ntx = i;
8004				for (k = 0; k < j; ++k) {
8005					bus_dmamap_destroy(sc->sc_dmat,
8006					    tbd->tbd_buf[k].tb_dmap);
8007				}
8008				goto fail;
8009			}
8010		}
8011	}
8012	ntx = BWI_TX_NRING;
8013
8014	/*
8015	 * Create RX mbuf DMA map and a spare DMA map
8016	 */
8017	error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8018	    BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
8019	if (error) {
8020		printf("%s: can't create spare RX buf DMA map\n",
8021		    sc->sc_dev.dv_xname);
8022		goto fail;
8023	}
8024
8025	for (j = 0; j < BWI_RX_NDESC; ++j) {
8026		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8027		    BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
8028		if (error) {
8029			printf("%s: can't create %dth RX buf DMA map\n",
8030			    sc->sc_dev.dv_xname, j);
8031
8032			for (k = 0; k < j; ++k) {
8033				bus_dmamap_destroy(sc->sc_dmat,
8034				    rbd->rbd_buf[k].rb_dmap);
8035			}
8036			bus_dmamap_destroy(sc->sc_dmat,
8037			    rbd->rbd_tmp_dmap);
8038			goto fail;
8039		}
8040	}
8041
8042	return 0;
8043fail:
8044	bwi_dma_mbuf_destroy(sc, ntx, 0);
8045
8046	return (error);
8047}
8048
8049void
8050bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
8051{
8052	struct ieee80211com *ic = &sc->sc_ic;
8053	int i, j;
8054
8055	for (i = 0; i < ntx; ++i) {
8056		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8057
8058		for (j = 0; j < BWI_TX_NDESC; ++j) {
8059			struct bwi_txbuf *tb = &tbd->tbd_buf[j];
8060
8061			if (tb->tb_mbuf != NULL) {
8062				bus_dmamap_unload(sc->sc_dmat,
8063				    tb->tb_dmap);
8064				m_freem(tb->tb_mbuf);
8065			}
8066			if (tb->tb_ni != NULL)
8067				ieee80211_release_node(ic, tb->tb_ni);
8068			bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
8069		}
8070	}
8071
8072	if (nrx) {
8073		struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8074
8075		bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
8076		for (j = 0; j < BWI_RX_NDESC; ++j) {
8077			struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
8078
8079			if (rb->rb_mbuf != NULL) {
8080				bus_dmamap_unload(sc->sc_dmat,
8081						  rb->rb_dmap);
8082				m_freem(rb->rb_mbuf);
8083			}
8084			bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
8085		}
8086	}
8087}
8088
8089void
8090bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
8091{
8092	CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
8093}
8094
8095void
8096bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
8097{
8098	CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
8099}
8100
8101int
8102bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
8103{
8104	struct bwi_ring_data *rd;
8105	struct bwi_txbuf_data *tbd;
8106	uint32_t val, addr_hi, addr_lo;
8107
8108	KASSERT(ring_idx < BWI_TX_NRING);
8109	rd = &sc->sc_tx_rdata[ring_idx];
8110	tbd = &sc->sc_tx_bdata[ring_idx];
8111
8112	tbd->tbd_idx = 0;
8113	tbd->tbd_used = 0;
8114
8115	bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
8116	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8117	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8118
8119	addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8120	addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8121
8122	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8123	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8124	    BWI_TXRX32_RINGINFO_FUNC_MASK);
8125	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
8126
8127	val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8128	      BWI_TXRX32_CTRL_ENABLE;
8129	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
8130
8131	return (0);
8132}
8133
8134void
8135bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
8136    bus_addr_t paddr, int hdr_size, int ndesc)
8137{
8138	uint32_t val, addr_hi, addr_lo;
8139
8140	addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8141	addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8142
8143	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8144	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8145	      		BWI_TXRX32_RINGINFO_FUNC_MASK);
8146	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
8147
8148	val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
8149	    __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8150	    BWI_TXRX32_CTRL_ENABLE;
8151	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
8152
8153	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8154	    (ndesc - 1) * sizeof(struct bwi_desc32));
8155}
8156
8157int
8158bwi_init_rx_ring32(struct bwi_softc *sc)
8159{
8160	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8161	int i, error;
8162
8163	sc->sc_rx_bdata.rbd_idx = 0;
8164	bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_RX_NDESC);
8165
8166	for (i = 0; i < BWI_RX_NDESC; ++i) {
8167		error = sc->sc_newbuf(sc, i, 1);
8168		if (error) {
8169			printf("%s: can't allocate %dth RX buffer\n",
8170			    sc->sc_dev.dv_xname, i);
8171			return (error);
8172		}
8173	}
8174	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8175	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8176
8177	bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
8178	    sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
8179	return (0);
8180}
8181
8182int
8183bwi_init_txstats32(struct bwi_softc *sc)
8184{
8185	struct bwi_txstats_data *st = sc->sc_txstats;
8186	bus_addr_t stats_paddr;
8187	int i;
8188
8189	bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
8190	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8191	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8192
8193	st->stats_idx = 0;
8194
8195	stats_paddr = st->stats_paddr;
8196	for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
8197		bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
8198				 stats_paddr, sizeof(struct bwi_txstats), 0);
8199		stats_paddr += sizeof(struct bwi_txstats);
8200	}
8201	bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
8202	    st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8203
8204	bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
8205	    st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
8206
8207	return (0);
8208}
8209
8210void
8211bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8212    int buf_len)
8213{
8214	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8215
8216	KASSERT(buf_idx < BWI_RX_NDESC);
8217	bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
8218	    paddr, buf_len, 0);
8219}
8220
8221void
8222bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
8223    int buf_idx, bus_addr_t paddr, int buf_len)
8224{
8225	KASSERT(buf_idx < BWI_TX_NDESC);
8226	bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
8227	    paddr, buf_len, 1);
8228}
8229
8230int
8231bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
8232{
8233	/* TODO: 64 */
8234	return (EOPNOTSUPP);
8235}
8236
8237int
8238bwi_init_rx_ring64(struct bwi_softc *sc)
8239{
8240	/* TODO: 64 */
8241	return (EOPNOTSUPP);
8242}
8243
8244int
8245bwi_init_txstats64(struct bwi_softc *sc)
8246{
8247	/* TODO: 64 */
8248	return (EOPNOTSUPP);
8249}
8250
8251void
8252bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8253    int buf_len)
8254{
8255	/* TODO: 64 */
8256}
8257
8258void
8259bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
8260    int buf_idx, bus_addr_t paddr, int buf_len)
8261{
8262	/* TODO: 64 */
8263}
8264
8265int
8266bwi_newbuf30(struct bwi_softc *sc, int buf_idx, int init)
8267{
8268	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8269	struct bwi_rxbuf *rb = &rbd->rbd_buf[buf_idx];
8270	struct mbuf *m;
8271	struct bwi_rxbuf_hdr *hdr;
8272	int error;
8273
8274	KASSERT(buf_idx < BWI_RX_NDESC);
8275
8276	/* Create host-side mbuf. */
8277	MGETHDR(m, init ? M_WAITOK : M_NOWAIT, MT_DATA);
8278	if (m == NULL)
8279		return (ENOBUFS);
8280	MCLGET(m, init ? M_WAITOK : M_NOWAIT);
8281	if (m == NULL)
8282		return (ENOBUFS);
8283	m->m_len = m->m_pkthdr.len = MCLBYTES;
8284
8285	if (init) {
8286		/* Load device-side RX DMA buffer. */
8287		error = bus_dmamap_load(sc->sc_dmat, rb->rb_dmap,
8288		    sc->sc_bounce_rx_data + (MCLBYTES * buf_idx),
8289		    MCLBYTES, NULL, BUS_DMA_WAITOK);
8290		if (error) {
8291			m_freem(m);
8292			return (error);
8293		}
8294	}
8295
8296	rb->rb_mbuf = m;
8297	rb->rb_paddr = rb->rb_dmap->dm_segs[0].ds_addr;
8298
8299	/*
8300	 * Clear RX buf header
8301	 */
8302	hdr = (struct bwi_rxbuf_hdr *)(sc->sc_bounce_rx_data +
8303	    (MCLBYTES * buf_idx));
8304	bzero(hdr, sizeof(*hdr));
8305	bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
8306	    rb->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8307
8308	/*
8309	 * Setup RX buf descriptor
8310	 */
8311	sc->sc_setup_rxdesc(sc, buf_idx, rb->rb_paddr,
8312	    m->m_len - sizeof(*hdr));
8313
8314	return (0);
8315}
8316
8317int
8318bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
8319{
8320	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8321	struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
8322	struct bwi_rxbuf_hdr *hdr;
8323	bus_dmamap_t map;
8324	bus_addr_t paddr;
8325	struct mbuf *m;
8326	int error;
8327
8328	KASSERT(buf_idx < BWI_RX_NDESC);
8329
8330	MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
8331	if (m == NULL)
8332		return (ENOBUFS);
8333	MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
8334	if (m == NULL) {
8335		error = ENOBUFS;
8336
8337		/*
8338		 * If the NIC is up and running, we need to:
8339		 * - Clear RX buffer's header.
8340		 * - Restore RX descriptor settings.
8341		 */
8342		if (init)
8343			return error;
8344		else
8345			goto back;
8346	}
8347	m->m_len = m->m_pkthdr.len = MCLBYTES;
8348
8349	/*
8350	 * Try to load RX buf into temporary DMA map
8351	 */
8352	error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
8353	    init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
8354	if (error) {
8355		m_freem(m);
8356
8357		/*
8358		 * See the comment above
8359		 */
8360		if (init)
8361			return error;
8362		else
8363			goto back;
8364	}
8365
8366	if (!init)
8367		bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
8368	rxbuf->rb_mbuf = m;
8369
8370	/*
8371	 * Swap RX buf's DMA map with the loaded temporary one
8372	 */
8373	map = rxbuf->rb_dmap;
8374	rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
8375	rbd->rbd_tmp_dmap = map;
8376	paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
8377	rxbuf->rb_paddr = paddr;
8378
8379back:
8380	/*
8381	 * Clear RX buf header
8382	 */
8383	hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
8384	bzero(hdr, sizeof(*hdr));
8385	bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
8386	    rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8387
8388	/*
8389	 * Setup RX buf descriptor
8390	 */
8391	sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr,
8392	    rxbuf->rb_mbuf->m_len - sizeof(*hdr));
8393	return error;
8394}
8395
8396void
8397bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
8398    const uint8_t *addr)
8399{
8400	int i;
8401
8402	CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
8403	    BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
8404
8405	for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
8406		uint16_t addr_val;
8407
8408		addr_val = (uint16_t)addr[i * 2] |
8409		    (((uint16_t)addr[(i * 2) + 1]) << 8);
8410		CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
8411	}
8412}
8413
8414int
8415bwi_set_chan(struct bwi_softc *sc, uint8_t chan)
8416{
8417	struct bwi_mac *mac;
8418
8419	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8420	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8421
8422	bwi_rf_set_chan(mac, chan, 0);
8423
8424	return (0);
8425}
8426
8427void
8428bwi_next_scan(void *xsc)
8429{
8430	struct bwi_softc *sc = xsc;
8431	struct ieee80211com *ic = &sc->sc_ic;
8432	struct ifnet *ifp = &ic->ic_if;
8433	int s;
8434
8435	s = splnet();
8436
8437	if (ic->ic_state == IEEE80211_S_SCAN)
8438		ieee80211_next_scan(ifp);
8439
8440	splx(s);
8441}
8442
8443int
8444bwi_rxeof(struct bwi_softc *sc, int end_idx)
8445{
8446	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8447	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8448	struct ieee80211com *ic = &sc->sc_ic;
8449	struct ifnet *ifp = &ic->ic_if;
8450	int idx, rx_data = 0;
8451
8452	idx = rbd->rbd_idx;
8453	while (idx != end_idx) {
8454		struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
8455		struct bwi_rxbuf_hdr *hdr;
8456		struct ieee80211_frame *wh;
8457		struct ieee80211_rxinfo rxi;
8458		struct ieee80211_node *ni;
8459		struct mbuf *m;
8460		uint32_t plcp;
8461		uint16_t flags2;
8462		int buflen, wh_ofs, hdr_extra, rssi, type, rate;
8463
8464		bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
8465		    rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8466
8467		if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
8468			/* Bounce for 30bit devices. */
8469			if (m_copyback(rb->rb_mbuf, 0, MCLBYTES,
8470			    sc->sc_bounce_rx_data + (MCLBYTES * idx),
8471			    M_NOWAIT) == ENOBUFS) {
8472				ifp->if_ierrors++;
8473				goto next;
8474			}
8475		}
8476
8477		m = rb->rb_mbuf;
8478
8479		if (sc->sc_newbuf(sc, idx, 0)) {
8480			ifp->if_ierrors++;
8481			goto next;
8482		}
8483
8484		hdr = mtod(m, struct bwi_rxbuf_hdr *);
8485		flags2 = letoh16(hdr->rxh_flags2);
8486
8487		hdr_extra = 0;
8488		if (flags2 & BWI_RXH_F2_TYPE2FRAME)
8489			hdr_extra = 2;
8490		wh_ofs = hdr_extra + 6;
8491
8492		buflen = letoh16(hdr->rxh_buflen);
8493		if (buflen <= wh_ofs) {
8494			printf("%s: zero length data, hdr_extra %d\n",
8495			    sc->sc_dev.dv_xname, hdr_extra);
8496			ifp->if_ierrors++;
8497			m_freem(m);
8498			goto next;
8499		}
8500
8501		bcopy((uint8_t *)(hdr + 1) + hdr_extra, &plcp, sizeof(plcp));
8502		rssi = bwi_calc_rssi(sc, hdr);
8503
8504		m->m_pkthdr.rcvif = ifp;
8505		m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
8506		m_adj(m, sizeof(*hdr) + wh_ofs);
8507
8508		if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
8509			rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11G);
8510		else
8511			rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11B);
8512
8513#if NBPFILTER > 0
8514		/* RX radio tap */
8515		if (sc->sc_drvbpf != NULL) {
8516			struct mbuf mb;
8517			struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
8518
8519			tap->wr_tsf = hdr->rxh_tsf;
8520			tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
8521			tap->wr_rate = rate;
8522			tap->wr_chan_freq =
8523			    htole16(ic->ic_bss->ni_chan->ic_freq);
8524			tap->wr_chan_flags =
8525			    htole16(ic->ic_bss->ni_chan->ic_flags);
8526			tap->wr_antsignal = rssi;
8527			tap->wr_antnoise = BWI_NOISE_FLOOR;
8528
8529			mb.m_data = (caddr_t)tap;
8530			mb.m_len = sc->sc_rxtap_len;
8531			mb.m_next = m;
8532			mb.m_nextpkt = NULL;
8533			mb.m_type = 0;
8534			mb.m_flags = 0;
8535			bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
8536		}
8537#endif
8538
8539		m_adj(m, -IEEE80211_CRC_LEN);
8540
8541		wh = mtod(m, struct ieee80211_frame *);
8542		ni = ieee80211_find_rxnode(ic, wh);
8543		type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
8544
8545		rxi.rxi_rssi = hdr->rxh_rssi;
8546		rxi.rxi_tstamp = letoh16(hdr->rxh_tsf);
8547		ieee80211_input(ifp, m, ni, &rxi);
8548
8549		ieee80211_release_node(ic, ni);
8550
8551		if (type == IEEE80211_FC0_TYPE_DATA) {
8552			rx_data = 1;
8553			sc->sc_rx_rate = rate;
8554		}
8555next:
8556		idx = (idx + 1) % BWI_RX_NDESC;
8557	}
8558
8559	rbd->rbd_idx = idx;
8560	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8561	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8562
8563	return (rx_data);
8564}
8565
8566int
8567bwi_rxeof32(struct bwi_softc *sc)
8568{
8569	uint32_t val, rx_ctrl;
8570	int end_idx, rx_data;
8571
8572	rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
8573
8574	val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8575	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
8576	    sizeof(struct bwi_desc32);
8577
8578	rx_data = bwi_rxeof(sc, end_idx);
8579
8580	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
8581	    end_idx * sizeof(struct bwi_desc32));
8582
8583	return (rx_data);
8584}
8585
8586int
8587bwi_rxeof64(struct bwi_softc *sc)
8588{
8589	/* TODO: 64 */
8590	return (0);
8591}
8592
8593void
8594bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
8595{
8596	int i;
8597
8598	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
8599
8600#define NRETRY 10
8601	for (i = 0; i < NRETRY; ++i) {
8602		uint32_t status;
8603
8604		status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8605		if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
8606		    BWI_RX32_STATUS_STATE_DISABLED)
8607			break;
8608
8609		DELAY(1000);
8610	}
8611	if (i == NRETRY)
8612		printf("%s: reset rx ring timedout\n", sc->sc_dev.dv_xname);
8613#undef NRETRY
8614
8615	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
8616}
8617
8618void
8619bwi_free_txstats32(struct bwi_softc *sc)
8620{
8621	bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
8622}
8623
8624void
8625bwi_free_rx_ring32(struct bwi_softc *sc)
8626{
8627	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8628	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8629	int i;
8630
8631	bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
8632
8633	for (i = 0; i < BWI_RX_NDESC; ++i) {
8634		struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
8635
8636		if (rb->rb_mbuf != NULL) {
8637			bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
8638			m_freem(rb->rb_mbuf);
8639			rb->rb_mbuf = NULL;
8640		}
8641	}
8642}
8643
8644void
8645bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
8646{
8647	struct ieee80211com *ic = &sc->sc_ic;
8648	struct bwi_ring_data *rd;
8649	struct bwi_txbuf_data *tbd;
8650	uint32_t state, val;
8651	int i;
8652
8653	KASSERT(ring_idx < BWI_TX_NRING);
8654	rd = &sc->sc_tx_rdata[ring_idx];
8655	tbd = &sc->sc_tx_bdata[ring_idx];
8656
8657#define NRETRY 10
8658	for (i = 0; i < NRETRY; ++i) {
8659		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8660		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8661		if (state == BWI_TX32_STATUS_STATE_DISABLED ||
8662		    state == BWI_TX32_STATUS_STATE_IDLE ||
8663		    state == BWI_TX32_STATUS_STATE_STOPPED)
8664			break;
8665
8666		DELAY(1000);
8667	}
8668	if (i == NRETRY) {
8669		printf("%s: wait for TX ring(%d) stable timed out\n",
8670		    sc->sc_dev.dv_xname, ring_idx);
8671	}
8672
8673	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
8674	for (i = 0; i < NRETRY; ++i) {
8675		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8676		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8677		if (state == BWI_TX32_STATUS_STATE_DISABLED)
8678			break;
8679
8680		DELAY(1000);
8681	}
8682	if (i == NRETRY)
8683		printf("%s: reset TX ring (%d) timed out\n",
8684		    sc->sc_dev.dv_xname, ring_idx);
8685#undef NRETRY
8686
8687	DELAY(1000);
8688
8689	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
8690
8691	for (i = 0; i < BWI_TX_NDESC; ++i) {
8692		struct bwi_txbuf *tb = &tbd->tbd_buf[i];
8693
8694		if (tb->tb_mbuf != NULL) {
8695			bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
8696			m_freem(tb->tb_mbuf);
8697			tb->tb_mbuf = NULL;
8698		}
8699		if (tb->tb_ni != NULL) {
8700			ieee80211_release_node(ic, tb->tb_ni);
8701			tb->tb_ni = NULL;
8702		}
8703	}
8704}
8705
8706void
8707bwi_free_txstats64(struct bwi_softc *sc)
8708{
8709	/* TODO: 64 */
8710}
8711
8712void
8713bwi_free_rx_ring64(struct bwi_softc *sc)
8714{
8715	/* TODO: 64 */
8716}
8717
8718void
8719bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
8720{
8721	/* TODO: 64 */
8722}
8723
8724uint8_t
8725bwi_plcp2rate(uint32_t plcp0, enum ieee80211_phymode phymode)
8726{
8727	uint32_t plcp = letoh32(plcp0) & IEEE80211_OFDM_PLCP_RATE_MASK;
8728	return (ieee80211_plcp2rate(plcp, phymode));
8729}
8730
8731void
8732bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
8733{
8734	uint32_t plcp;
8735
8736	plcp = __SHIFTIN(ieee80211_rate2plcp(rate, IEEE80211_MODE_11G),
8737	    IEEE80211_OFDM_PLCP_RATE_MASK) |
8738	    __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
8739	*plcp0 = htole32(plcp);
8740}
8741
8742void
8743bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
8744    uint8_t rate)
8745{
8746	int len, service, pkt_bitlen;
8747
8748	pkt_bitlen = pkt_len * NBBY;
8749	len = howmany(pkt_bitlen * 2, rate);
8750
8751	service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
8752	if (rate == (11 * 2)) {
8753		int pkt_bitlen1;
8754
8755		/*
8756		 * PLCP service field needs to be adjusted,
8757		 * if TX rate is 11Mbytes/s
8758		 */
8759		pkt_bitlen1 = len * 11;
8760		if (pkt_bitlen1 - pkt_bitlen >= NBBY)
8761			service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
8762	}
8763
8764	plcp->i_signal = ieee80211_rate2plcp(rate, IEEE80211_MODE_11B);
8765	plcp->i_service = service;
8766	plcp->i_length = htole16(len);
8767	/* NOTE: do NOT touch i_crc */
8768}
8769
8770void
8771bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
8772{
8773	enum bwi_modtype modtype;
8774
8775	/*
8776	 * Assume caller has zeroed 'plcp'
8777	 */
8778
8779	modtype = bwi_rate2modtype(rate);
8780	if (modtype == IEEE80211_MODTYPE_OFDM)
8781		bwi_ofdm_plcp_header(plcp, pkt_len, rate);
8782	else if (modtype == IEEE80211_MODTYPE_DS)
8783		bwi_ds_plcp_header(plcp, pkt_len, rate);
8784	else
8785		panic("unsupport modulation type %u", modtype);
8786}
8787
8788enum bwi_modtype
8789bwi_rate2modtype(uint8_t rate)
8790{
8791	rate &= IEEE80211_RATE_VAL;
8792
8793	if (rate == 44)
8794		return IEEE80211_MODTYPE_PBCC;
8795	else if (rate == 22 || rate < 12)
8796		return IEEE80211_MODTYPE_DS;
8797	else
8798		return IEEE80211_MODTYPE_OFDM;
8799}
8800
8801uint8_t
8802bwi_ack_rate(struct ieee80211_node *ni, uint8_t rate)
8803{
8804	const struct ieee80211_rateset *rs = &ni->ni_rates;
8805	uint8_t ack_rate = 0;
8806	enum bwi_modtype modtype;
8807	int i;
8808
8809	rate &= IEEE80211_RATE_VAL;
8810
8811	modtype = bwi_rate2modtype(rate);
8812
8813	for (i = 0; i < rs->rs_nrates; ++i) {
8814		uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
8815
8816		if (rate1 > rate) {
8817			if (ack_rate != 0)
8818				return ack_rate;
8819			else
8820				break;
8821		}
8822
8823		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
8824		    bwi_rate2modtype(rate1) == modtype)
8825			ack_rate = rate1;
8826	}
8827
8828	switch (rate) {
8829	/* CCK */
8830	case 2:
8831	case 4:
8832	case 11:
8833	case 22:
8834		ack_rate = rate;
8835		break;
8836	/* PBCC */
8837	case 44:
8838		ack_rate = 22;
8839		break;
8840
8841	/* OFDM */
8842	case 12:
8843	case 18:
8844		ack_rate = 12;
8845		break;
8846	case 24:
8847	case 36:
8848		ack_rate = 24;
8849		break;
8850	case 48:
8851	case 72:
8852	case 96:
8853	case 108:
8854		ack_rate = 48;
8855		break;
8856	default:
8857		panic("unsupported rate %d", rate);
8858	}
8859	return ack_rate;
8860}
8861
8862#define IEEE80211_OFDM_TXTIME(kbps, frmlen)	\
8863	(IEEE80211_OFDM_PREAMBLE_TIME +		\
8864	 IEEE80211_OFDM_SIGNAL_TIME +		\
8865	(IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
8866
8867#define IEEE80211_OFDM_SYM_TIME			4
8868#define IEEE80211_OFDM_PREAMBLE_TIME		16
8869#define IEEE80211_OFDM_SIGNAL_EXT_TIME		6
8870#define IEEE80211_OFDM_SIGNAL_TIME		4
8871
8872#define IEEE80211_OFDM_PLCP_SERVICE_NBITS	16
8873#define IEEE80211_OFDM_TAIL_NBITS		6
8874
8875#define IEEE80211_OFDM_NBITS(frmlen)		\
8876	(IEEE80211_OFDM_PLCP_SERVICE_NBITS +	\
8877	 ((frmlen) * NBBY) +			\
8878	 IEEE80211_OFDM_TAIL_NBITS)
8879
8880#define IEEE80211_OFDM_NBITS_PER_SYM(kbps)	\
8881	(((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
8882
8883#define IEEE80211_OFDM_NSYMS(kbps, frmlen)	\
8884	howmany(IEEE80211_OFDM_NBITS((frmlen)),	\
8885	IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
8886
8887#define IEEE80211_CCK_TXTIME(kbps, frmlen)	\
8888	(((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
8889
8890#define IEEE80211_CCK_PREAMBLE_LEN		144
8891#define IEEE80211_CCK_PLCP_HDR_TIME		48
8892#define IEEE80211_CCK_SHPREAMBLE_LEN		72
8893#define IEEE80211_CCK_SHPLCP_HDR_TIME		24
8894
8895#define IEEE80211_CCK_NBITS(frmlen)		((frmlen) * NBBY)
8896
8897uint16_t
8898bwi_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, uint len,
8899    uint8_t rs_rate, uint32_t flags)
8900{
8901	enum bwi_modtype modtype;
8902	uint16_t txtime;
8903	int rate;
8904
8905	rs_rate &= IEEE80211_RATE_VAL;
8906
8907	rate = rs_rate * 500;	/* ieee80211 rate -> kbps */
8908
8909	modtype = bwi_rate2modtype(rs_rate);
8910	if (modtype == IEEE80211_MODTYPE_OFDM) {
8911		/*
8912		 * IEEE Std 802.11a-1999, page 37, equation (29)
8913		 * IEEE Std 802.11g-2003, page 44, equation (42)
8914		 */
8915		txtime = IEEE80211_OFDM_TXTIME(rate, len);
8916		if (ic->ic_curmode == IEEE80211_MODE_11G)
8917			txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
8918	} else {
8919		/*
8920		 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
8921		 * IEEE Std 802.11g-2003, page 45, equation (43)
8922		 */
8923		if (modtype == IEEE80211_MODTYPE_PBCC)
8924			++len;
8925		txtime = IEEE80211_CCK_TXTIME(rate, len);
8926
8927		/*
8928		 * Short preamble is not applicable for DS 1Mbits/s
8929		 */
8930		if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
8931			txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
8932				  IEEE80211_CCK_SHPLCP_HDR_TIME;
8933		} else {
8934			txtime += IEEE80211_CCK_PREAMBLE_LEN +
8935				  IEEE80211_CCK_PLCP_HDR_TIME;
8936		}
8937	}
8938	return txtime;
8939}
8940
8941int
8942bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
8943    struct ieee80211_node *ni)
8944{
8945	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
8946
8947	struct ieee80211com *ic = &sc->sc_ic;
8948	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
8949	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
8950	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
8951	struct bwi_mac *mac;
8952	struct bwi_txbuf_hdr *hdr;
8953	struct ieee80211_frame *wh;
8954	uint8_t rate;
8955	uint32_t mac_ctrl;
8956	uint16_t phy_ctrl;
8957	bus_addr_t paddr;
8958	int pkt_len, error = 0;
8959#if 0
8960	const uint8_t *p;
8961	int i;
8962#endif
8963
8964	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8965	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8966
8967	wh = mtod(m, struct ieee80211_frame *);
8968
8969	/* Get 802.11 frame len before prepending TX header */
8970	pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
8971
8972	/*
8973	 * Find TX rate
8974	 */
8975	bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx));
8976	if (ni != NULL) {
8977		if (ic->ic_fixed_rate != -1) {
8978			rate = ic->ic_sup_rates[ic->ic_curmode].
8979			    rs_rates[ic->ic_fixed_rate];
8980		} else {
8981			/* AMRR rate control */
8982			rate = ni->ni_rates.rs_rates[ni->ni_txrate];
8983		}
8984	} else {
8985		/* Fixed at 1Mbytes/s for mgt frames */
8986		rate = (1 * 2);
8987	}
8988
8989	rate &= IEEE80211_RATE_VAL;
8990
8991	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
8992		rate = (1 * 2);
8993
8994	if (rate == 0) {
8995		printf("%s: invalid rate %u or fallback rate",
8996		    sc->sc_dev.dv_xname, rate);
8997		rate = (1 * 2); /* Force 1Mbytes/s */
8998	}
8999	sc->sc_tx_rate = rate;
9000
9001#if NBPFILTER > 0
9002	/* TX radio tap */
9003	if (sc->sc_drvbpf != NULL) {
9004		struct mbuf mb;
9005		struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
9006
9007		tap->wt_flags = 0;
9008		tap->wt_rate = rate;
9009		tap->wt_chan_freq =
9010		    htole16(ic->ic_bss->ni_chan->ic_freq);
9011		tap->wt_chan_flags =
9012		    htole16(ic->ic_bss->ni_chan->ic_flags);
9013
9014		mb.m_data = (caddr_t)tap;
9015		mb.m_len = sc->sc_txtap_len;
9016		mb.m_next = m;
9017		mb.m_nextpkt = NULL;
9018		mb.m_type = 0;
9019		mb.m_flags = 0;
9020		bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
9021	}
9022#endif
9023
9024	/*
9025	 * Setup the embedded TX header
9026	 */
9027	M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
9028	if (m == NULL) {
9029		printf("%s: prepend TX header failed\n", sc->sc_dev.dv_xname);
9030		return (ENOBUFS);
9031	}
9032	hdr = mtod(m, struct bwi_txbuf_hdr *);
9033
9034	bzero(hdr, sizeof(*hdr));
9035
9036	bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
9037	bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
9038
9039	if (ni != NULL && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
9040		uint16_t dur;
9041		uint8_t ack_rate;
9042
9043		ack_rate = bwi_ack_rate(ni, rate);
9044		dur = bwi_txtime(ic, ni,
9045		    sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
9046		    ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE);
9047
9048		hdr->txh_fb_duration = htole16(dur);
9049	}
9050
9051	hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
9052	    __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
9053
9054	bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
9055	bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate);
9056
9057	phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
9058	    BWI_TXH_PHY_C_ANTMODE_MASK);
9059	if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9060		phy_ctrl |= BWI_TXH_PHY_C_OFDM;
9061	else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
9062		phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
9063
9064	mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
9065	if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
9066		mac_ctrl |= BWI_TXH_MAC_C_ACK;
9067	if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9068		mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
9069
9070	hdr->txh_mac_ctrl = htole32(mac_ctrl);
9071	hdr->txh_phy_ctrl = htole16(phy_ctrl);
9072
9073	/* Catch any further usage */
9074	hdr = NULL;
9075	wh = NULL;
9076
9077	if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
9078		/* Bounce for 30bit devices. */
9079		m_copydata(m, 0, m->m_pkthdr.len,
9080		    sc->sc_bounce_tx_data[BWI_TX_DATA_RING] +
9081		    (MCLBYTES * idx));
9082	} else {
9083		/* DMA load */
9084		error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9085		    BUS_DMA_NOWAIT);
9086		if (error && error != EFBIG) {
9087			printf("%s: can't load TX buffer (1) %d\n",
9088			    sc->sc_dev.dv_xname, error);
9089			goto back;
9090		}
9091
9092		if (error) {	/* error == EFBIG */
9093			if (m_defrag(m, M_DONTWAIT)) {
9094				printf("%s: can't defrag TX buffer\n",
9095				    sc->sc_dev.dv_xname);
9096				goto back;
9097			}
9098			error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap,
9099			    m, BUS_DMA_NOWAIT);
9100			if (error) {
9101				printf("%s: can't load TX buffer (2) %d\n",
9102				    sc->sc_dev.dv_xname, error);
9103				goto back;
9104			}
9105		}
9106		error = 0;
9107	}
9108
9109	bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
9110	    tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9111
9112	tb->tb_mbuf = m;
9113	tb->tb_ni = ni;
9114
9115#if 0
9116	p = mtod(m, const uint8_t *);
9117	for (i = 0; i < m->m_pkthdr.len; ++i) {
9118		if (i != 0 && i % 8 == 0)
9119			printf("\n");
9120		printf("%02x ", p[i]);
9121	}
9122	printf("\n");
9123
9124	DPRINTF(1, "%s: idx %d, pkt_len %d, buflen %d\n",
9125	    sc->sc_dev.dv_xname, idx, pkt_len, m->m_pkthdr.len);
9126#endif
9127
9128	/* Setup TX descriptor */
9129	paddr = tb->tb_dmap->dm_segs[0].ds_addr;
9130	sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len);
9131	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
9132	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9133
9134	/* Kick start */
9135	sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
9136
9137back:
9138	if (error)
9139		m_freem(m);
9140	return (error);
9141}
9142
9143void
9144bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9145{
9146	idx = (idx + 1) % BWI_TX_NDESC;
9147	CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
9148	    idx * sizeof(struct bwi_desc32));
9149}
9150
9151void
9152bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9153{
9154	/* TODO: 64 */
9155}
9156
9157void
9158bwi_txeof_status32(struct bwi_softc *sc)
9159{
9160	struct ifnet *ifp = &sc->sc_ic.ic_if;
9161	uint32_t val, ctrl_base;
9162	int end_idx;
9163
9164	ctrl_base = sc->sc_txstats->stats_ctrl_base;
9165
9166	val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
9167	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
9168	    sizeof(struct bwi_desc32);
9169
9170	bwi_txeof_status(sc, end_idx);
9171
9172	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
9173	    end_idx * sizeof(struct bwi_desc32));
9174
9175	if ((ifp->if_flags & IFF_OACTIVE) == 0)
9176		ifp->if_start(ifp);
9177}
9178
9179void
9180bwi_txeof_status64(struct bwi_softc *sc)
9181{
9182	/* TODO: 64 */
9183}
9184
9185void
9186_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
9187{
9188	struct ieee80211com *ic = &sc->sc_ic;
9189	struct ifnet *ifp = &sc->sc_ic.ic_if;
9190	struct bwi_txbuf_data *tbd;
9191	struct bwi_txbuf *tb;
9192	int ring_idx, buf_idx;
9193
9194	if (tx_id == 0) {
9195		printf("%s: zero tx id\n", sc->sc_dev.dv_xname);
9196		return;
9197	}
9198
9199	ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
9200	buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
9201
9202	KASSERT(ring_idx == BWI_TX_DATA_RING);
9203	KASSERT(buf_idx < BWI_TX_NDESC);
9204#if 0
9205	DPRINTF(1, "%s: txeof idx %d\n", sc->sc_dev.dv_xname, buf_idx);
9206#endif
9207	tbd = &sc->sc_tx_bdata[ring_idx];
9208	KASSERT(tbd->tbd_used > 0);
9209	tbd->tbd_used--;
9210
9211	tb = &tbd->tbd_buf[buf_idx];
9212
9213	bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
9214	m_freem(tb->tb_mbuf);
9215	tb->tb_mbuf = NULL;
9216
9217	if (tb->tb_ni != NULL) {
9218		ieee80211_release_node(ic, tb->tb_ni);
9219		tb->tb_ni = NULL;
9220	}
9221
9222	if (tbd->tbd_used == 0)
9223		sc->sc_tx_timer = 0;
9224
9225	ifp->if_flags &= ~IFF_OACTIVE;
9226}
9227
9228void
9229bwi_txeof_status(struct bwi_softc *sc, int end_idx)
9230{
9231	struct bwi_txstats_data *st = sc->sc_txstats;
9232	int idx;
9233
9234	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
9235	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
9236
9237	idx = st->stats_idx;
9238	while (idx != end_idx) {
9239		_bwi_txeof(sc, letoh16(st->stats[idx].txs_id));
9240		idx = (idx + 1) % BWI_TXSTATS_NDESC;
9241	}
9242	st->stats_idx = idx;
9243}
9244
9245void
9246bwi_txeof(struct bwi_softc *sc)
9247{
9248	struct ifnet *ifp = &sc->sc_ic.ic_if;
9249
9250	for (;;) {
9251		uint32_t tx_status0, tx_status1;
9252		uint16_t tx_id, tx_info;
9253
9254		tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
9255		if (tx_status0 == 0)
9256			break;
9257		tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1);
9258
9259		tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
9260		tx_info = BWI_TXSTATUS_0_INFO(tx_status0);
9261
9262		if (tx_info & 0x30) /* XXX */
9263			continue;
9264
9265		_bwi_txeof(sc, letoh16(tx_id));
9266
9267		ifp->if_opackets++;
9268	}
9269
9270	if ((ifp->if_flags & IFF_OACTIVE) == 0)
9271		ifp->if_start(ifp);
9272}
9273
9274int
9275bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
9276{
9277	bwi_power_on(sc, 1);
9278
9279	return (bwi_set_clock_mode(sc, clk_mode));
9280}
9281
9282void
9283bwi_bbp_power_off(struct bwi_softc *sc)
9284{
9285	bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
9286	bwi_power_off(sc, 1);
9287}
9288
9289int
9290bwi_get_pwron_delay(struct bwi_softc *sc)
9291{
9292	struct bwi_regwin *com, *old;
9293	struct bwi_clock_freq freq;
9294	uint32_t val;
9295	int error;
9296
9297	com = &sc->sc_com_regwin;
9298	KASSERT(BWI_REGWIN_EXIST(com));
9299
9300	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
9301		return (0);
9302
9303	error = bwi_regwin_switch(sc, com, &old);
9304	if (error)
9305		return (error);
9306
9307	bwi_get_clock_freq(sc, &freq);
9308
9309	val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
9310	sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
9311	DPRINTF(1, "%s: power on delay %u\n",
9312	    sc->sc_dev.dv_xname, sc->sc_pwron_delay);
9313
9314	return (bwi_regwin_switch(sc, old, NULL));
9315}
9316
9317int
9318bwi_bus_attach(struct bwi_softc *sc)
9319{
9320	struct bwi_regwin *bus, *old;
9321	int error;
9322
9323	bus = &sc->sc_bus_regwin;
9324
9325	error = bwi_regwin_switch(sc, bus, &old);
9326	if (error)
9327		return (error);
9328
9329	if (!bwi_regwin_is_enabled(sc, bus))
9330		bwi_regwin_enable(sc, bus, 0);
9331
9332	/* Disable interripts */
9333	CSR_WRITE_4(sc, BWI_INTRVEC, 0);
9334
9335	return (bwi_regwin_switch(sc, old, NULL));
9336}
9337
9338const char *
9339bwi_regwin_name(const struct bwi_regwin *rw)
9340{
9341	switch (rw->rw_type) {
9342	case BWI_REGWIN_T_COM:
9343		return ("COM");
9344	case BWI_REGWIN_T_BUSPCI:
9345		return ("PCI");
9346	case BWI_REGWIN_T_MAC:
9347		return ("MAC");
9348	case BWI_REGWIN_T_BUSPCIE:
9349		return ("PCIE");
9350	}
9351	panic("unknown regwin type 0x%04x", rw->rw_type);
9352
9353	return (NULL);
9354}
9355
9356uint32_t
9357bwi_regwin_disable_bits(struct bwi_softc *sc)
9358{
9359	uint32_t busrev;
9360
9361	/* XXX cache this */
9362	busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
9363	DPRINTF(1, "%s: bus rev %u\n", sc->sc_dev.dv_xname, busrev);
9364
9365	if (busrev == BWI_BUSREV_0)
9366		return (BWI_STATE_LO_DISABLE1);
9367	else if (busrev == BWI_BUSREV_1)
9368		return (BWI_STATE_LO_DISABLE2);
9369	else
9370		return ((BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2));
9371}
9372
9373int
9374bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
9375{
9376	uint32_t val, disable_bits;
9377
9378	disable_bits = bwi_regwin_disable_bits(sc);
9379	val = CSR_READ_4(sc, BWI_STATE_LO);
9380
9381	if ((val & (BWI_STATE_LO_CLOCK |
9382	    BWI_STATE_LO_RESET |
9383	    disable_bits)) == BWI_STATE_LO_CLOCK) {
9384		DPRINTF(1, "%s: %s is enabled\n",
9385		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9386		return (1);
9387	} else {
9388		DPRINTF(1, "%s: %s is disabled\n",
9389		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9390		return (0);
9391	}
9392}
9393
9394void
9395bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9396{
9397	uint32_t state_lo, disable_bits;
9398	int i;
9399
9400	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9401
9402	/*
9403	 * If current regwin is in 'reset' state, it was already disabled.
9404	 */
9405	if (state_lo & BWI_STATE_LO_RESET) {
9406		DPRINTF(1, "%s: %s was already disabled\n",
9407		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9408		return;
9409	}
9410
9411	disable_bits = bwi_regwin_disable_bits(sc);
9412
9413	/*
9414	 * Disable normal clock
9415	 */
9416	state_lo = BWI_STATE_LO_CLOCK | disable_bits;
9417	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9418
9419	/*
9420	 * Wait until normal clock is disabled
9421	 */
9422#define NRETRY	1000
9423	for (i = 0; i < NRETRY; ++i) {
9424		state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9425		if (state_lo & disable_bits)
9426			break;
9427		DELAY(10);
9428	}
9429	if (i == NRETRY) {
9430		printf("%s: %s disable clock timeout\n",
9431		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9432	}
9433
9434	for (i = 0; i < NRETRY; ++i) {
9435		uint32_t state_hi;
9436
9437		state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9438		if ((state_hi & BWI_STATE_HI_BUSY) == 0)
9439			break;
9440		DELAY(10);
9441	}
9442	if (i == NRETRY) {
9443		printf("%s: %s wait BUSY unset timeout\n",
9444		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9445	}
9446#undef NRETRY
9447
9448	/*
9449	 * Reset and disable regwin with gated clock
9450	 */
9451	state_lo = BWI_STATE_LO_RESET | disable_bits |
9452	    BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
9453	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9454	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9455
9456	/* Flush pending bus write */
9457	CSR_READ_4(sc, BWI_STATE_LO);
9458	DELAY(1);
9459
9460	/* Reset and disable regwin */
9461	state_lo = BWI_STATE_LO_RESET | disable_bits |
9462		   __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9463	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9464
9465	/* Flush pending bus write */
9466	CSR_READ_4(sc, BWI_STATE_LO);
9467	DELAY(1);
9468}
9469
9470void
9471bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9472{
9473	uint32_t state_lo, state_hi, imstate;
9474
9475	bwi_regwin_disable(sc, rw, flags);
9476
9477	/* Reset regwin with gated clock */
9478	state_lo = BWI_STATE_LO_RESET |
9479	    BWI_STATE_LO_CLOCK |
9480	    BWI_STATE_LO_GATED_CLOCK |
9481	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9482	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9483
9484	/* Flush pending bus write */
9485	CSR_READ_4(sc, BWI_STATE_LO);
9486	DELAY(1);
9487
9488	state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9489	if (state_hi & BWI_STATE_HI_SERROR)
9490		CSR_WRITE_4(sc, BWI_STATE_HI, 0);
9491
9492	imstate = CSR_READ_4(sc, BWI_IMSTATE);
9493	if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
9494		imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
9495		CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
9496	}
9497
9498	/* Enable regwin with gated clock */
9499	state_lo = BWI_STATE_LO_CLOCK |
9500	    BWI_STATE_LO_GATED_CLOCK |
9501	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9502	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9503
9504	/* Flush pending bus write */
9505	CSR_READ_4(sc, BWI_STATE_LO);
9506	DELAY(1);
9507
9508	/* Enable regwin with normal clock */
9509	state_lo = BWI_STATE_LO_CLOCK |
9510	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9511	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9512
9513	/* Flush pending bus write */
9514	CSR_READ_4(sc, BWI_STATE_LO);
9515	DELAY(1);
9516}
9517
9518void
9519bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
9520{
9521	struct ieee80211com *ic = &sc->sc_ic;
9522	struct bwi_mac *mac;
9523	struct bwi_myaddr_bssid buf;
9524	const uint8_t *p;
9525	uint32_t val;
9526	int n, i;
9527
9528	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9529	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9530
9531	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
9532
9533	bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr));
9534	bcopy(bssid, buf.bssid, sizeof(buf.bssid));
9535
9536	n = sizeof(buf) / sizeof(val);
9537	p = (const uint8_t *)&buf;
9538	for (i = 0; i < n; ++i) {
9539		int j;
9540
9541		val = 0;
9542		for (j = 0; j < sizeof(val); ++j)
9543			val |= ((uint32_t)(*p++)) << (j * 8);
9544
9545		TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
9546	}
9547}
9548
9549void
9550bwi_updateslot(struct ieee80211com *ic)
9551{
9552	struct bwi_softc *sc = ic->ic_if.if_softc;
9553	struct bwi_mac *mac;
9554	struct ifnet *ifp = &ic->ic_if;
9555
9556	if ((ifp->if_flags & IFF_RUNNING) == 0)
9557		return;
9558
9559	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
9560
9561	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9562	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9563
9564	bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
9565}
9566
9567void
9568bwi_calibrate(void *xsc)
9569{
9570	struct bwi_softc *sc = xsc;
9571	struct ieee80211com *ic = &sc->sc_ic;
9572	int s;
9573
9574	s = splnet();
9575
9576	if (ic->ic_state == IEEE80211_S_RUN) {
9577		struct bwi_mac *mac;
9578
9579		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9580		mac = (struct bwi_mac *)sc->sc_cur_regwin;
9581
9582		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
9583			bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
9584			sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
9585		}
9586
9587		/* XXX 15 seconds */
9588		timeout_add_sec(&sc->sc_calib_ch, 15);
9589	}
9590
9591	splx(s);
9592}
9593
9594int
9595bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
9596{
9597	struct bwi_mac *mac;
9598
9599	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9600	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9601
9602	return (bwi_rf_calc_rssi(mac, hdr));
9603}
9604