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