bwi.c revision 1.47
1/*	$OpenBSD: bwi.c,v 1.47 2007/09/27 05:58:57 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
3932#if 0
3933		KKASSERT(rf_atten < MAP_MAX);
3934		rf_atten = map[rf_atten];
3935#else
3936		if (rf_atten >= MAP_MAX) {
3937			rf_atten = 0;	/* XXX */
3938		} else {
3939			rf_atten = map[rf_atten];
3940		}
3941#endif
3942#undef MAP_MAX
3943	}
3944
3945	return (bwi_get_rf_lo(mac, rf_atten, bbp_atten));
3946}
3947
3948void
3949bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
3950{
3951	const struct bwi_rf_lo *lo;
3952
3953	lo = bwi_rf_lo_find(mac, tpctl);
3954	RF_LO_WRITE(mac, lo);
3955}
3956
3957void
3958bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
3959{
3960	uint16_t val;
3961
3962	val = (uint8_t)lo->ctrl_lo;
3963	val |= ((uint8_t)lo->ctrl_hi) << 8;
3964
3965	PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
3966}
3967
3968int
3969bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
3970{
3971	PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
3972	PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
3973	PHY_SETBITS(mac, 0x15, 0xf000);
3974
3975	DELAY(20);
3976
3977	return ((PHY_READ(mac, 0x2d) >= 0xdfc));
3978}
3979
3980/* XXX use bitmap array */
3981uint16_t
3982bwi_bitswap4(uint16_t val)
3983{
3984	uint16_t ret;
3985
3986	ret = (val & 0x8) >> 3;
3987	ret |= (val & 0x4) >> 1;
3988	ret |= (val & 0x2) << 1;
3989	ret |= (val & 0x1) << 3;
3990
3991	return (ret);
3992}
3993
3994uint16_t
3995bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
3996{
3997	struct bwi_softc *sc = mac->mac_sc;
3998	struct bwi_phy *phy = &mac->mac_phy;
3999	struct bwi_rf *rf = &mac->mac_rf;
4000	uint16_t lo_gain, ext_lna, loop;
4001
4002	if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
4003		return (0);
4004
4005	lo_gain = rf->rf_lo_gain;
4006	if (rf->rf_rev == 8)
4007		lo_gain += 0x3e;
4008	else
4009		lo_gain += 0x26;
4010
4011	if (lo_gain >= 0x46) {
4012		lo_gain -= 0x46;
4013		ext_lna = 0x3000;
4014	} else if (lo_gain >= 0x3a) {
4015		lo_gain -= 0x3a;
4016		ext_lna = 0x1000;
4017	} else if (lo_gain >= 0x2e) {
4018		lo_gain -= 0x2e;
4019		ext_lna = 0x2000;
4020	} else {
4021		lo_gain -= 0x10;
4022		ext_lna = 0;
4023	}
4024
4025	for (loop = 0; loop < 16; ++loop) {
4026		lo_gain -= (6 * loop);
4027		if (lo_gain < 6)
4028			break;
4029	}
4030
4031	if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
4032		if (ext_lna)
4033			ext_lna |= 0x8000;
4034		ext_lna |= (loop << 8);
4035		switch (lpd) {
4036		case 0x011:
4037			return (0x8f92);
4038		case 0x001:
4039			return ((0x8092 | ext_lna));
4040		case 0x101:
4041			return ((0x2092 | ext_lna));
4042		case 0x100:
4043			return ((0x2093 | ext_lna));
4044		default:
4045			panic("unsupported lpd\n");
4046		}
4047	} else {
4048		ext_lna |= (loop << 8);
4049		switch (lpd) {
4050		case 0x011:
4051			return (0xf92);
4052		case 0x001:
4053		case 0x101:
4054			return ((0x92 | ext_lna));
4055		case 0x100:
4056			return ((0x93 | ext_lna));
4057		default:
4058			panic("unsupported lpd\n");
4059		}
4060	}
4061
4062	panic("never reached\n");
4063
4064	return (0);
4065}
4066
4067void
4068bwi_rf_init_bcm2050(struct bwi_mac *mac)
4069{
4070#define SAVE_RF_MAX		3
4071#define SAVE_PHY_COMM_MAX	4
4072#define SAVE_PHY_11G_MAX	6
4073	uint16_t save_rf[SAVE_RF_MAX];
4074	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
4075	uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
4076	uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
4077	uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
4078	uint16_t phy812_val;
4079	uint16_t calib;
4080	uint32_t test_lim, test;
4081	struct bwi_softc *sc = mac->mac_sc;
4082	struct bwi_phy *phy = &mac->mac_phy;
4083	struct bwi_rf *rf = &mac->mac_rf;
4084	int i;
4085
4086	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4087	    { 0x0043, 0x0051, 0x0052 };
4088	static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
4089	    { 0x0015, 0x005a, 0x0059, 0x0058 };
4090	static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
4091	    { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
4092
4093	/*
4094	 * Save registers for later restoring
4095	 */
4096	for (i = 0; i < SAVE_RF_MAX; ++i)
4097		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4098	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
4099		save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
4100
4101	if (phy->phy_mode == IEEE80211_MODE_11B) {
4102		phyr_30 = PHY_READ(mac, 0x30);
4103		bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
4104
4105		PHY_WRITE(mac, 0x30, 0xff);
4106		CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
4107	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4108		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4109			save_phy_11g[i] =
4110			    PHY_READ(mac, save_phy_regs_11g[i]);
4111		}
4112
4113		PHY_SETBITS(mac, 0x814, 0x3);
4114		PHY_CLRBITS(mac, 0x815, 0x3);
4115		PHY_CLRBITS(mac, 0x429, 0x8000);
4116		PHY_CLRBITS(mac, 0x802, 0x3);
4117
4118		phyr_80f = PHY_READ(mac, 0x80f);
4119		phyr_810 = PHY_READ(mac, 0x810);
4120
4121		if (phy->phy_rev >= 3)
4122			PHY_WRITE(mac, 0x80f, 0xc020);
4123		else
4124			PHY_WRITE(mac, 0x80f, 0x8020);
4125		PHY_WRITE(mac, 0x810, 0);
4126
4127		phy812_val = bwi_phy812_value(mac, 0x011);
4128		PHY_WRITE(mac, 0x812, phy812_val);
4129		if (phy->phy_rev < 7 ||
4130		    (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
4131			PHY_WRITE(mac, 0x811, 0x1b3);
4132		else
4133			PHY_WRITE(mac, 0x811, 0x9b3);
4134	}
4135	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4136
4137	phyr_35 = PHY_READ(mac, 0x35);
4138	PHY_CLRBITS(mac, 0x35, 0x80);
4139
4140	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4141	rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4142
4143	if (phy->phy_version == 0) {
4144		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
4145	} else {
4146		if (phy->phy_version >= 2)
4147			PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
4148		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
4149	}
4150
4151	calib = bwi_rf_calibval(mac);
4152
4153	if (phy->phy_mode == IEEE80211_MODE_11B)
4154		RF_WRITE(mac, 0x78, 0x26);
4155
4156	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4157		phy812_val = bwi_phy812_value(mac, 0x011);
4158		PHY_WRITE(mac, 0x812, phy812_val);
4159	}
4160
4161	PHY_WRITE(mac, 0x15, 0xbfaf);
4162	PHY_WRITE(mac, 0x2b, 0x1403);
4163
4164	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4165		phy812_val = bwi_phy812_value(mac, 0x001);
4166		PHY_WRITE(mac, 0x812, phy812_val);
4167	}
4168
4169	PHY_WRITE(mac, 0x15, 0xbfa0);
4170
4171	RF_SETBITS(mac, 0x51, 0x4);
4172	if (rf->rf_rev == 8)
4173		RF_WRITE(mac, 0x43, 0x1f);
4174	else {
4175		RF_WRITE(mac, 0x52, 0);
4176		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
4177	}
4178
4179	test_lim = 0;
4180	PHY_WRITE(mac, 0x58, 0);
4181	for (i = 0; i < 16; ++i) {
4182		PHY_WRITE(mac, 0x5a, 0x480);
4183		PHY_WRITE(mac, 0x59, 0xc810);
4184
4185		PHY_WRITE(mac, 0x58, 0xd);
4186		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4187			phy812_val = bwi_phy812_value(mac, 0x101);
4188			PHY_WRITE(mac, 0x812, phy812_val);
4189		}
4190		PHY_WRITE(mac, 0x15, 0xafb0);
4191		DELAY(10);
4192
4193		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4194			phy812_val = bwi_phy812_value(mac, 0x101);
4195			PHY_WRITE(mac, 0x812, phy812_val);
4196		}
4197		PHY_WRITE(mac, 0x15, 0xefb0);
4198		DELAY(10);
4199
4200		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4201			phy812_val = bwi_phy812_value(mac, 0x100);
4202			PHY_WRITE(mac, 0x812, phy812_val);
4203		}
4204		PHY_WRITE(mac, 0x15, 0xfff0);
4205		DELAY(20);
4206
4207		test_lim += PHY_READ(mac, 0x2d);
4208
4209		PHY_WRITE(mac, 0x58, 0);
4210		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4211			phy812_val = bwi_phy812_value(mac, 0x101);
4212			PHY_WRITE(mac, 0x812, phy812_val);
4213		}
4214		PHY_WRITE(mac, 0x15, 0xafb0);
4215	}
4216	++test_lim;
4217	test_lim >>= 9;
4218
4219	DELAY(10);
4220
4221	test = 0;
4222	PHY_WRITE(mac, 0x58, 0);
4223	for (i = 0; i < 16; ++i) {
4224		int j;
4225
4226		rfr_78 = (bwi_bitswap4(i) << 1) | 0x20;
4227		RF_WRITE(mac, 0x78, rfr_78);
4228		DELAY(10);
4229
4230		/* NB: This block is slight different than the above one */
4231		for (j = 0; j < 16; ++j) {
4232			PHY_WRITE(mac, 0x5a, 0xd80);
4233			PHY_WRITE(mac, 0x59, 0xc810);
4234
4235			PHY_WRITE(mac, 0x58, 0xd);
4236			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4237			    phy->phy_rev >= 2) {
4238				phy812_val = bwi_phy812_value(mac, 0x101);
4239				PHY_WRITE(mac, 0x812, phy812_val);
4240			}
4241			PHY_WRITE(mac, 0x15, 0xafb0);
4242			DELAY(10);
4243
4244			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4245			    phy->phy_rev >= 2) {
4246				phy812_val = bwi_phy812_value(mac, 0x101);
4247				PHY_WRITE(mac, 0x812, phy812_val);
4248			}
4249			PHY_WRITE(mac, 0x15, 0xefb0);
4250			DELAY(10);
4251
4252			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4253			    phy->phy_rev >= 2) {
4254				phy812_val = bwi_phy812_value(mac, 0x100);
4255				PHY_WRITE(mac, 0x812, phy812_val);
4256			}
4257			PHY_WRITE(mac, 0x15, 0xfff0);
4258			DELAY(10);
4259
4260			test += PHY_READ(mac, 0x2d);
4261
4262			PHY_WRITE(mac, 0x58, 0);
4263			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4264			    phy->phy_rev >= 2) {
4265				phy812_val = bwi_phy812_value(mac, 0x101);
4266				PHY_WRITE(mac, 0x812, phy812_val);
4267			}
4268			PHY_WRITE(mac, 0x15, 0xafb0);
4269		}
4270
4271		++test;
4272		test >>= 8;
4273
4274		if (test > test_lim)
4275			break;
4276	}
4277	if (i > 15)
4278		rf->rf_calib = rfr_78;
4279	else
4280		rf->rf_calib = calib;
4281	if (rf->rf_calib != 0xffff) {
4282		DPRINTF(1, "%s: RF calibration value: 0x%04x\n",
4283		    sc->sc_dev.dv_xname, rf->rf_calib);
4284		rf->rf_flags |= BWI_RF_F_INITED;
4285	}
4286
4287	/*
4288	 * Restore trashes registers
4289	 */
4290	PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
4291
4292	for (i = 0; i < SAVE_RF_MAX; ++i) {
4293		int pos = (i + 1) % SAVE_RF_MAX;
4294
4295		RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
4296	}
4297	for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
4298		PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
4299
4300	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
4301	if (phy->phy_version != 0)
4302		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
4303
4304	PHY_WRITE(mac, 0x35, phyr_35);
4305	bwi_rf_work_around(mac, rf->rf_curchan);
4306
4307	if (phy->phy_mode == IEEE80211_MODE_11B) {
4308		PHY_WRITE(mac, 0x30, phyr_30);
4309		CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
4310	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4311		/* XXX Spec only says when PHY is linked (gmode) */
4312		CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4313
4314		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4315			PHY_WRITE(mac, save_phy_regs_11g[i],
4316				  save_phy_11g[i]);
4317		}
4318
4319		PHY_WRITE(mac, 0x80f, phyr_80f);
4320		PHY_WRITE(mac, 0x810, phyr_810);
4321	}
4322
4323#undef SAVE_PHY_11G_MAX
4324#undef SAVE_PHY_COMM_MAX
4325#undef SAVE_RF_MAX
4326}
4327
4328uint16_t
4329bwi_rf_calibval(struct bwi_mac *mac)
4330{
4331	uint16_t val, calib;
4332	int idx;
4333
4334	/* http://bcm-specs.sipsolutions.net/RCCTable */
4335	static const uint16_t rf_calibvals[] = {
4336		0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
4337		0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
4338	};
4339
4340	val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
4341	idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
4342	KKASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
4343
4344	calib = rf_calibvals[idx] << 1;
4345	if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
4346		calib |= 0x1;
4347	calib |= 0x20;
4348
4349	return (calib);
4350}
4351
4352int32_t
4353_bwi_adjust_devide(int32_t num, int32_t den)
4354{
4355	if (num < 0)
4356		return ((num / den));
4357	else
4358		return ((num + den / 2) / den);
4359}
4360
4361/*
4362 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
4363 * "calculating table entries"
4364 */
4365int
4366bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
4367{
4368	int32_t m1, m2, f, dbm;
4369	int i;
4370
4371	m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
4372	m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
4373
4374#define ITER_MAX	16
4375	f = 256;
4376	for (i = 0; i < ITER_MAX; ++i) {
4377		int32_t q, d;
4378
4379		q = _bwi_adjust_devide(
4380		    f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
4381		d = abs(q - f);
4382		f = q;
4383
4384		if (d < 2)
4385			break;
4386	}
4387	if (i == ITER_MAX)
4388		return (EINVAL);
4389#undef ITER_MAX
4390
4391	dbm = _bwi_adjust_devide(m1 * f, 8192);
4392	if (dbm < -127)
4393		dbm = -127;
4394	else if (dbm > 128)
4395		dbm = 128;
4396
4397	*txpwr = dbm;
4398
4399	return (0);
4400}
4401
4402int
4403bwi_rf_map_txpower(struct bwi_mac *mac)
4404{
4405	struct bwi_softc *sc = mac->mac_sc;
4406	struct bwi_rf *rf = &mac->mac_rf;
4407	struct bwi_phy *phy = &mac->mac_phy;
4408	uint16_t sprom_ofs, val, mask;
4409	int16_t pa_params[3];
4410	int error = 0, i, ant_gain, reg_txpower_max;
4411
4412	/*
4413	 * Find out max TX power
4414	 */
4415	val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
4416	if (phy->phy_mode == IEEE80211_MODE_11A) {
4417		rf->rf_txpower_max = __SHIFTOUT(val,
4418		    BWI_SPROM_MAX_TXPWR_MASK_11A);
4419	} else {
4420		rf->rf_txpower_max = __SHIFTOUT(val,
4421		    BWI_SPROM_MAX_TXPWR_MASK_11BG);
4422
4423		if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
4424		    phy->phy_mode == IEEE80211_MODE_11G)
4425			rf->rf_txpower_max -= 3;
4426	}
4427	if (rf->rf_txpower_max <= 0) {
4428		DPRINTF(1, "%s: invalid max txpower in sprom\n",
4429		    sc->sc_dev.dv_xname);
4430		rf->rf_txpower_max = 74;
4431	}
4432	DPRINTF(1, "%s: max txpower from sprom: %d dBm\n",
4433	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4434
4435	/*
4436	 * Find out region/domain max TX power, which is adjusted
4437	 * by antenna gain and 1.5 dBm fluctuation as mentioned
4438	 * in v3 spec.
4439	 */
4440	val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
4441	if (phy->phy_mode == IEEE80211_MODE_11A)
4442		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
4443	else
4444		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
4445	if (ant_gain == 0xff) {
4446		DPRINTF(1, "%s: invalid antenna gain in sprom\n",
4447		    sc->sc_dev.dv_xname);
4448		ant_gain = 2;
4449	}
4450	ant_gain *= 4;
4451	DPRINTF(1, "%s: ant gain %d dBm\n", sc->sc_dev.dv_xname, ant_gain);
4452
4453	reg_txpower_max = 90 - ant_gain - 6;	/* XXX magic number */
4454	DPRINTF(1, "%s: region/domain max txpower %d dBm\n",
4455	    sc->sc_dev.dv_xname, reg_txpower_max);
4456
4457	/*
4458	 * Force max TX power within region/domain TX power limit
4459	 */
4460	if (rf->rf_txpower_max > reg_txpower_max)
4461		rf->rf_txpower_max = reg_txpower_max;
4462	DPRINTF(1, "%s: max txpower %d dBm\n",
4463	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4464
4465	/*
4466	 * Create TSSI to TX power mapping
4467	 */
4468
4469	if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
4470	    rf->rf_type != BWI_RF_T_BCM2050) {
4471		rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4472		bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0,
4473		      sizeof(rf->rf_txpower_map0));
4474		goto back;
4475	}
4476
4477#define IS_VALID_PA_PARAM(p)	((p) != 0 && (p) != -1)
4478#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
4479	/*
4480	 * Extract PA parameters
4481	 */
4482	if (phy->phy_mode == IEEE80211_MODE_11A)
4483		sprom_ofs = BWI_SPROM_PA_PARAM_11A;
4484	else
4485		sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
4486	for (i = 0; i < N(pa_params); ++i)
4487		pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
4488
4489	for (i = 0; i < N(pa_params); ++i) {
4490		/*
4491		 * If one of the PA parameters from SPROM is not valid,
4492		 * fall back to the default values, if there are any.
4493		 */
4494		if (!IS_VALID_PA_PARAM(pa_params[i])) {
4495			const int8_t *txpower_map;
4496
4497			if (phy->phy_mode == IEEE80211_MODE_11A) {
4498				printf("%s: no tssi2dbm table for 11a PHY\n",
4499				    sc->sc_dev.dv_xname);
4500				return (ENXIO);
4501			}
4502
4503			if (phy->phy_mode == IEEE80211_MODE_11G) {
4504				DPRINTF(1, "%s: use default 11g TSSI map\n",
4505				    sc->sc_dev.dv_xname);
4506				txpower_map = bwi_txpower_map_11g;
4507			} else {
4508				txpower_map = bwi_txpower_map_11b;
4509			}
4510
4511			rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4512			bcopy(txpower_map, rf->rf_txpower_map0,
4513			      sizeof(rf->rf_txpower_map0));
4514			goto back;
4515		}
4516	}
4517#undef N
4518
4519	/*
4520	 * All of the PA parameters from SPROM are valid.
4521	 */
4522
4523	/*
4524	 * Extract idle TSSI from SPROM.
4525	 */
4526	val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
4527	DPRINTF(1, "%s: sprom idle tssi: 0x%04x\n", sc->sc_dev.dv_xname, val);
4528
4529	if (phy->phy_mode == IEEE80211_MODE_11A)
4530		mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
4531	else
4532		mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
4533
4534	rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
4535	if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
4536		rf->rf_idle_tssi0 = 62;
4537
4538#undef IS_VALID_PA_PARAM
4539
4540	/*
4541	 * Calculate TX power map, which is indexed by TSSI
4542	 */
4543	DPRINTF(1, "%s: TSSI-TX power map:\n", sc->sc_dev.dv_xname);
4544	for (i = 0; i < BWI_TSSI_MAX; ++i) {
4545		error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
4546					    pa_params);
4547		if (error) {
4548			DPRINTF(1, "%s: bwi_rf_calc_txpower failed\n",
4549			    sc->sc_dev.dv_xname);
4550			break;
4551		}
4552		if (i != 0 && i % 8 == 0)
4553			printf("\n");
4554		printf("%d ", rf->rf_txpower_map0[i]);
4555	}
4556	printf("\n");
4557back:
4558	DPRINTF(1, "%s: idle tssi0: %d\n",
4559	    sc->sc_dev.dv_xname, rf->rf_idle_tssi0);
4560
4561	return (error);
4562}
4563
4564void
4565bwi_rf_lo_update(struct bwi_mac *mac)
4566{
4567	struct bwi_softc *sc = mac->mac_sc;
4568	struct ifnet *ifp = &sc->sc_ic.ic_if;
4569	struct bwi_rf *rf = &mac->mac_rf;
4570	struct bwi_phy *phy = &mac->mac_phy;
4571	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
4572	struct rf_saveregs regs;
4573	uint16_t ant_div, chan_ex;
4574	uint8_t devi_ctrl;
4575	u_int orig_chan;
4576
4577	/*
4578	 * Save RF/PHY registers for later restoration
4579	 */
4580	orig_chan = rf->rf_curchan;
4581	bzero(&regs, sizeof(regs));
4582
4583	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4584		SAVE_PHY_REG(mac, &regs, 429);
4585		SAVE_PHY_REG(mac, &regs, 802);
4586
4587		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4588		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4589	}
4590
4591	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
4592	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
4593	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4594
4595	SAVE_PHY_REG(mac, &regs, 15);
4596	SAVE_PHY_REG(mac, &regs, 2a);
4597	SAVE_PHY_REG(mac, &regs, 35);
4598	SAVE_PHY_REG(mac, &regs, 60);
4599	SAVE_RF_REG(mac, &regs, 43);
4600	SAVE_RF_REG(mac, &regs, 7a);
4601	SAVE_RF_REG(mac, &regs, 52);
4602	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4603		SAVE_PHY_REG(mac, &regs, 811);
4604		SAVE_PHY_REG(mac, &regs, 812);
4605		SAVE_PHY_REG(mac, &regs, 814);
4606		SAVE_PHY_REG(mac, &regs, 815);
4607	}
4608
4609	/* Force to channel 6 */
4610	bwi_rf_set_chan(mac, 6, 0);
4611
4612	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4613		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4614		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4615		bwi_mac_dummy_xmit(mac);
4616	}
4617	RF_WRITE(mac, 0x43, 0x6);
4618
4619	bwi_phy_set_bbp_atten(mac, 2);
4620
4621	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
4622
4623	PHY_WRITE(mac, 0x2e, 0x7f);
4624	PHY_WRITE(mac, 0x80f, 0x78);
4625	PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
4626	RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
4627	PHY_WRITE(mac, 0x2b, 0x203);
4628	PHY_WRITE(mac, 0x2a, 0x8a3);
4629
4630	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4631		PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
4632		PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
4633		PHY_WRITE(mac, 0x811, 0x1b3);
4634		PHY_WRITE(mac, 0x812, 0xb2);
4635	}
4636
4637	if ((ifp->if_flags & IFF_RUNNING) == 0)
4638		tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
4639	PHY_WRITE(mac, 0x80f, 0x8078);
4640
4641	/*
4642	 * Measure all RF LO
4643	 */
4644	devi_ctrl = _bwi_rf_lo_update(mac, regs.rf_7a);
4645
4646	/*
4647	 * Restore saved RF/PHY registers
4648	 */
4649	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4650		PHY_WRITE(mac, 0x15, 0xe300);
4651		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
4652		DELAY(5);
4653		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
4654		DELAY(2);
4655		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
4656	} else
4657		PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
4658
4659	if ((ifp->if_flags & IFF_RUNNING) == 0)
4660		tpctl = NULL;
4661	bwi_rf_lo_adjust(mac, tpctl);
4662
4663	PHY_WRITE(mac, 0x2e, 0x807f);
4664	if (phy->phy_flags & BWI_PHY_F_LINKED)
4665		PHY_WRITE(mac, 0x2f, 0x202);
4666	else
4667		PHY_WRITE(mac, 0x2f, 0x101);
4668
4669	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
4670
4671	RESTORE_PHY_REG(mac, &regs, 15);
4672	RESTORE_PHY_REG(mac, &regs, 2a);
4673	RESTORE_PHY_REG(mac, &regs, 35);
4674	RESTORE_PHY_REG(mac, &regs, 60);
4675
4676	RESTORE_RF_REG(mac, &regs, 43);
4677	RESTORE_RF_REG(mac, &regs, 7a);
4678
4679	regs.rf_52 &= 0xf0;
4680	regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
4681	RF_WRITE(mac, 0x52, regs.rf_52);
4682
4683	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
4684
4685	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4686		RESTORE_PHY_REG(mac, &regs, 811);
4687		RESTORE_PHY_REG(mac, &regs, 812);
4688		RESTORE_PHY_REG(mac, &regs, 814);
4689		RESTORE_PHY_REG(mac, &regs, 815);
4690		RESTORE_PHY_REG(mac, &regs, 429);
4691		RESTORE_PHY_REG(mac, &regs, 802);
4692	}
4693
4694	bwi_rf_set_chan(mac, orig_chan, 1);
4695}
4696
4697uint32_t
4698bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
4699{
4700	struct bwi_phy *phy = &mac->mac_phy;
4701	uint32_t devi = 0;
4702	int i;
4703
4704	if (phy->phy_flags & BWI_PHY_F_LINKED)
4705		ctrl <<= 8;
4706
4707	for (i = 0; i < 8; ++i) {
4708		if (phy->phy_flags & BWI_PHY_F_LINKED) {
4709			PHY_WRITE(mac, 0x15, 0xe300);
4710			PHY_WRITE(mac, 0x812, ctrl | 0xb0);
4711			DELAY(5);
4712			PHY_WRITE(mac, 0x812, ctrl | 0xb2);
4713			DELAY(2);
4714			PHY_WRITE(mac, 0x812, ctrl | 0xb3);
4715			DELAY(4);
4716			PHY_WRITE(mac, 0x15, 0xf300);
4717		} else {
4718			PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
4719			DELAY(2);
4720			PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
4721			DELAY(4);
4722			PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
4723		}
4724		DELAY(8);
4725		devi += PHY_READ(mac, 0x2d);
4726	}
4727
4728	return (devi);
4729}
4730
4731uint16_t
4732bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
4733{
4734	uint32_t devi_min;
4735	uint16_t tp_ctrl2 = 0;
4736	int i;
4737
4738	RF_WRITE(mac, 0x52, 0);
4739	DELAY(10);
4740	devi_min = bwi_rf_lo_devi_measure(mac, 0);
4741
4742	for (i = 0; i < 16; ++i) {
4743		uint32_t devi;
4744
4745		RF_WRITE(mac, 0x52, i);
4746		DELAY(10);
4747		devi = bwi_rf_lo_devi_measure(mac, 0);
4748
4749		if (devi < devi_min) {
4750			devi_min = devi;
4751			tp_ctrl2 = i;
4752		}
4753	}
4754
4755	return (tp_ctrl2);
4756}
4757
4758uint8_t
4759_bwi_rf_lo_update(struct bwi_mac *mac, uint16_t orig_rf7a)
4760{
4761#define RF_ATTEN_LISTSZ	14
4762#define BBP_ATTEN_MAX	4	/* half */
4763	struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if;
4764	struct bwi_rf_lo lo_save, *lo;
4765	uint8_t devi_ctrl = 0;
4766	int idx, adj_rf7a = 0;
4767
4768	static const int rf_atten_list[RF_ATTEN_LISTSZ] =
4769	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
4770	static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
4771            { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
4772	static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
4773	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
4774
4775	bzero(&lo_save, sizeof(lo_save));
4776	for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
4777		int init_rf_atten = rf_atten_init_list[idx];
4778		int rf_atten = rf_atten_list[idx];
4779		int bbp_atten;
4780
4781		for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
4782			uint16_t tp_ctrl2, rf7a;
4783
4784			if ((ifp->if_flags & IFF_RUNNING) == 0) {
4785				if (idx == 0) {
4786					bzero(&lo_save, sizeof(lo_save));
4787				} else if (init_rf_atten < 0) {
4788					lo = bwi_get_rf_lo(mac,
4789					    rf_atten, 2 * bbp_atten);
4790					bcopy(lo, &lo_save, sizeof(lo_save));
4791				} else {
4792					lo = bwi_get_rf_lo(mac,
4793					    init_rf_atten, 0);
4794					bcopy(lo, &lo_save, sizeof(lo_save));
4795				}
4796
4797				devi_ctrl = 0;
4798				adj_rf7a = 0;
4799
4800				/*
4801				 * XXX
4802				 * Linux driver overflows 'val'
4803				 */
4804				if (init_rf_atten >= 0) {
4805					int val;
4806
4807					val = rf_atten * 2 + bbp_atten;
4808					if (val > 14) {
4809						adj_rf7a = 1;
4810						if (val > 17)
4811							devi_ctrl = 1;
4812						if (val > 19)
4813							devi_ctrl = 2;
4814					}
4815				}
4816			} else {
4817				lo = bwi_get_rf_lo(mac,
4818					rf_atten, 2 * bbp_atten);
4819				if (!bwi_rf_lo_isused(mac, lo))
4820					continue;
4821				bcopy(lo, &lo_save, sizeof(lo_save));
4822
4823				devi_ctrl = 3;
4824				adj_rf7a = 0;
4825			}
4826
4827			RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
4828
4829			tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
4830			if (init_rf_atten < 0)
4831				tp_ctrl2 |= (3 << 4);
4832			RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
4833
4834			DELAY(10);
4835
4836			bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
4837
4838			rf7a = orig_rf7a & 0xfff0;
4839			if (adj_rf7a)
4840				rf7a |= 0x8;
4841			RF_WRITE(mac, 0x7a, rf7a);
4842
4843			lo = bwi_get_rf_lo(mac,
4844				rf_lo_measure_order[idx], bbp_atten * 2);
4845			bwi_rf_lo_measure(mac, &lo_save, lo, devi_ctrl);
4846		}
4847	}
4848
4849	return (devi_ctrl);
4850
4851#undef RF_ATTEN_LISTSZ
4852#undef BBP_ATTEN_MAX
4853}
4854
4855void
4856bwi_rf_lo_measure(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
4857    struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
4858{
4859#define LO_ADJUST_MIN	1
4860#define LO_ADJUST_MAX	8
4861#define LO_ADJUST(hi, lo)	{ .ctrl_hi = hi, .ctrl_lo = lo }
4862	static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
4863		LO_ADJUST(1,	1),
4864		LO_ADJUST(1,	0),
4865		LO_ADJUST(1,	-1),
4866		LO_ADJUST(0,	-1),
4867		LO_ADJUST(-1,	-1),
4868		LO_ADJUST(-1,	0),
4869		LO_ADJUST(-1,	1),
4870		LO_ADJUST(0,	1)
4871	};
4872#undef LO_ADJUST
4873
4874	struct bwi_rf_lo lo_min;
4875	uint32_t devi_min;
4876	int found, loop_count, adjust_state;
4877
4878	bcopy(src_lo, &lo_min, sizeof(lo_min));
4879	RF_LO_WRITE(mac, &lo_min);
4880	devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
4881
4882	loop_count = 12;	/* XXX */
4883	adjust_state = 0;
4884	do {
4885		struct bwi_rf_lo lo_base;
4886		int i, fin;
4887
4888		found = 0;
4889		if (adjust_state == 0) {
4890			i = LO_ADJUST_MIN;
4891			fin = LO_ADJUST_MAX;
4892		} else if (adjust_state % 2 == 0) {
4893			i = adjust_state - 1;
4894			fin = adjust_state + 1;
4895		} else {
4896			i = adjust_state - 2;
4897			fin = adjust_state + 2;
4898		}
4899
4900		if (i < LO_ADJUST_MIN)
4901			i += LO_ADJUST_MAX;
4902		KKASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
4903
4904		if (fin > LO_ADJUST_MAX)
4905			fin -= LO_ADJUST_MAX;
4906		KKASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
4907
4908		bcopy(&lo_min, &lo_base, sizeof(lo_base));
4909		for (;;) {
4910			struct bwi_rf_lo lo;
4911
4912			lo.ctrl_hi = lo_base.ctrl_hi +
4913				rf_lo_adjust[i - 1].ctrl_hi;
4914			lo.ctrl_lo = lo_base.ctrl_lo +
4915				rf_lo_adjust[i - 1].ctrl_lo;
4916
4917			if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
4918				uint32_t devi;
4919
4920				RF_LO_WRITE(mac, &lo);
4921				devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
4922				if (devi < devi_min) {
4923					devi_min = devi;
4924					adjust_state = i;
4925					found = 1;
4926					bcopy(&lo, &lo_min, sizeof(lo_min));
4927				}
4928			}
4929			if (i == fin)
4930				break;
4931			if (i == LO_ADJUST_MAX)
4932				i = LO_ADJUST_MIN;
4933			else
4934				++i;
4935		}
4936	} while (loop_count-- && found);
4937
4938	bcopy(&lo_min, dst_lo, sizeof(*dst_lo));
4939
4940#undef LO_ADJUST_MIN
4941#undef LO_ADJUST_MAX
4942}
4943
4944void
4945bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
4946{
4947#define SAVE_RF_MAX	3
4948#define SAVE_PHY_MAX	8
4949	struct bwi_softc *sc = mac->mac_sc;
4950	struct bwi_rf *rf = &mac->mac_rf;
4951	struct bwi_phy *phy = &mac->mac_phy;
4952	uint16_t save_rf[SAVE_RF_MAX];
4953	uint16_t save_phy[SAVE_PHY_MAX];
4954	uint16_t ant_div, bbp_atten, chan_ex;
4955	int16_t nrssi[2];
4956	int i;
4957
4958	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4959	    { 0x7a, 0x52, 0x43 };
4960	static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
4961	    { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
4962
4963	/*
4964	 * Save RF/PHY registers for later restoration
4965	 */
4966	for (i = 0; i < SAVE_RF_MAX; ++i)
4967		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4968	for (i = 0; i < SAVE_PHY_MAX; ++i)
4969		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
4970
4971	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
4972	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4973	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4974
4975	/*
4976	 * Calculate nrssi0
4977	 */
4978	if (phy->phy_rev >= 5)
4979		RF_CLRBITS(mac, 0x7a, 0xff80);
4980	else
4981		RF_CLRBITS(mac, 0x7a, 0xfff0);
4982	PHY_WRITE(mac, 0x30, 0xff);
4983
4984	CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
4985
4986	PHY_WRITE(mac, 0x26, 0);
4987	PHY_SETBITS(mac, 0x15, 0x20);
4988	PHY_WRITE(mac, 0x2a, 0x8a3);
4989	RF_SETBITS(mac, 0x7a, 0x80);
4990
4991	nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
4992
4993	/*
4994	 * Calculate nrssi1
4995	 */
4996	RF_CLRBITS(mac, 0x7a, 0xff80);
4997	if (phy->phy_version >= 2)
4998		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
4999	else if (phy->phy_version == 0)
5000		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
5001	else
5002		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
5003
5004	PHY_WRITE(mac, 0x20, 0x3f3f);
5005	PHY_WRITE(mac, 0x15, 0xf330);
5006
5007	RF_WRITE(mac, 0x5a, 0x60);
5008	RF_CLRBITS(mac, 0x43, 0xff0f);
5009
5010	PHY_WRITE(mac, 0x5a, 0x480);
5011	PHY_WRITE(mac, 0x59, 0x810);
5012	PHY_WRITE(mac, 0x58, 0xd);
5013
5014	DELAY(20);
5015
5016	nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
5017
5018	/*
5019	 * Restore saved RF/PHY registers
5020	 */
5021	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
5022	RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
5023
5024	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5025
5026	for (i = 1; i < 4; ++i)
5027		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5028
5029	bwi_rf_work_around(mac, rf->rf_curchan);
5030
5031	if (phy->phy_version != 0)
5032		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5033
5034	for (; i < SAVE_PHY_MAX; ++i)
5035		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5036
5037	for (i = 1; i < SAVE_RF_MAX; ++i)
5038		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5039
5040	/*
5041	 * Install calculated narrow RSSI values
5042	 */
5043	if (nrssi[0] == nrssi[1])
5044		rf->rf_nrssi_slope = 0x10000;
5045	else
5046		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5047	if (nrssi[0] <= -4) {
5048		rf->rf_nrssi[0] = nrssi[0];
5049		rf->rf_nrssi[1] = nrssi[1];
5050	}
5051
5052#undef SAVE_RF_MAX
5053#undef SAVE_PHY_MAX
5054}
5055
5056void
5057bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
5058{
5059#define SAVE_RF_MAX		2
5060#define SAVE_PHY_COMM_MAX	10
5061#define SAVE_PHY6_MAX		8
5062	struct bwi_phy *phy = &mac->mac_phy;
5063	uint16_t save_rf[SAVE_RF_MAX];
5064	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5065	uint16_t save_phy6[SAVE_PHY6_MAX];
5066	uint16_t rf7b = 0xffff;
5067	int16_t nrssi;
5068	int i, phy6_idx = 0;
5069
5070	static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 };
5071	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
5072		0x0001, 0x0811, 0x0812, 0x0814,
5073		0x0815, 0x005a, 0x0059, 0x0058,
5074		0x000a, 0x0003
5075	};
5076	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
5077		0x002e, 0x002f, 0x080f, 0x0810,
5078		0x0801, 0x0060, 0x0014, 0x0478
5079	};
5080
5081	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5082		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5083	for (i = 0; i < SAVE_RF_MAX; ++i)
5084		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5085
5086	PHY_CLRBITS(mac, 0x429, 0x8000);
5087	PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
5088	PHY_SETBITS(mac, 0x811, 0xc);
5089	PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
5090	PHY_CLRBITS(mac, 0x802, 0x3);
5091
5092	if (phy->phy_rev >= 6) {
5093		for (i = 0; i < SAVE_PHY6_MAX; ++i)
5094			save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
5095
5096		PHY_WRITE(mac, 0x2e, 0);
5097		PHY_WRITE(mac, 0x2f, 0);
5098		PHY_WRITE(mac, 0x80f, 0);
5099		PHY_WRITE(mac, 0x810, 0);
5100		PHY_SETBITS(mac, 0x478, 0x100);
5101		PHY_SETBITS(mac, 0x801, 0x40);
5102		PHY_SETBITS(mac, 0x60, 0x40);
5103		PHY_SETBITS(mac, 0x14, 0x200);
5104	}
5105
5106	RF_SETBITS(mac, 0x7a, 0x70);
5107	RF_SETBITS(mac, 0x7a, 0x80);
5108
5109	DELAY(30);
5110
5111	nrssi = bwi_nrssi_11g(mac);
5112	if (nrssi == 31) {
5113		for (i = 7; i >= 4; --i) {
5114			RF_WRITE(mac, 0x7b, i);
5115			DELAY(20);
5116			nrssi = bwi_nrssi_11g(mac);
5117			if (nrssi < 31 && rf7b == 0xffff)
5118				rf7b = i;
5119		}
5120		if (rf7b == 0xffff)
5121			rf7b = 4;
5122	} else {
5123		struct bwi_gains gains;
5124
5125		RF_CLRBITS(mac, 0x7a, 0xff80);
5126
5127		PHY_SETBITS(mac, 0x814, 0x1);
5128		PHY_CLRBITS(mac, 0x815, 0x1);
5129		PHY_SETBITS(mac, 0x811, 0xc);
5130		PHY_SETBITS(mac, 0x812, 0xc);
5131		PHY_SETBITS(mac, 0x811, 0x30);
5132		PHY_SETBITS(mac, 0x812, 0x30);
5133		PHY_WRITE(mac, 0x5a, 0x480);
5134		PHY_WRITE(mac, 0x59, 0x810);
5135		PHY_WRITE(mac, 0x58, 0xd);
5136		if (phy->phy_version == 0)
5137			PHY_WRITE(mac, 0x3, 0x122);
5138		else
5139			PHY_SETBITS(mac, 0xa, 0x2000);
5140		PHY_SETBITS(mac, 0x814, 0x4);
5141		PHY_CLRBITS(mac, 0x815, 0x4);
5142		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5143		RF_SETBITS(mac, 0x7a, 0xf);
5144
5145		bzero(&gains, sizeof(gains));
5146		gains.tbl_gain1 = 3;
5147		gains.tbl_gain2 = 0;
5148		gains.phy_gain = 1;
5149		bwi_set_gains(mac, &gains);
5150
5151		RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
5152		DELAY(30);
5153
5154		nrssi = bwi_nrssi_11g(mac);
5155		if (nrssi == -32) {
5156			for (i = 0; i < 4; ++i) {
5157				RF_WRITE(mac, 0x7b, i);
5158				DELAY(20);
5159				nrssi = bwi_nrssi_11g(mac);
5160				if (nrssi > -31 && rf7b == 0xffff)
5161					rf7b = i;
5162			}
5163			if (rf7b == 0xffff)
5164				rf7b = 3;
5165		} else {
5166			rf7b = 0;
5167		}
5168	}
5169	RF_WRITE(mac, 0x7b, rf7b);
5170
5171	/*
5172	 * Restore saved RF/PHY registers
5173	 */
5174	if (phy->phy_rev >= 6) {
5175		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
5176			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5177			    save_phy6[phy6_idx]);
5178		}
5179	}
5180
5181	/* Saved PHY registers 0, 1, 2 are handled later */
5182	for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
5183		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5184
5185	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
5186		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5187
5188	PHY_SETBITS(mac, 0x802, 0x3);
5189	PHY_SETBITS(mac, 0x429, 0x8000);
5190
5191	bwi_set_gains(mac, NULL);
5192
5193	if (phy->phy_rev >= 6) {
5194		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
5195			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5196			    save_phy6[phy6_idx]);
5197		}
5198	}
5199
5200	PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
5201	PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
5202	PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
5203
5204#undef SAVE_RF_MAX
5205#undef SAVE_PHY_COMM_MAX
5206#undef SAVE_PHY6_MAX
5207}
5208
5209void
5210bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
5211{
5212#define SAVE_RF_MAX		3
5213#define SAVE_PHY_COMM_MAX	4
5214#define SAVE_PHY3_MAX		8
5215	struct bwi_softc *sc = mac->mac_sc;
5216	struct bwi_phy *phy = &mac->mac_phy;
5217	struct bwi_rf *rf = &mac->mac_rf;
5218	uint16_t save_rf[SAVE_RF_MAX];
5219	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5220	uint16_t save_phy3[SAVE_PHY3_MAX];
5221	uint16_t ant_div, bbp_atten, chan_ex;
5222	struct bwi_gains gains;
5223	int16_t nrssi[2];
5224	int i, phy3_idx = 0;
5225
5226	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5227	    { 0x7a, 0x52, 0x43 };
5228	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
5229	    { 0x15, 0x5a, 0x59, 0x58 };
5230	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
5231		0x002e, 0x002f, 0x080f, 0x0810,
5232		0x0801, 0x0060, 0x0014, 0x0478
5233	};
5234
5235	if (rf->rf_rev >= 9)
5236		return;
5237	else if (rf->rf_rev == 8)
5238		bwi_rf_set_nrssi_ofs_11g(mac);
5239
5240	PHY_CLRBITS(mac, 0x429, 0x8000);
5241	PHY_CLRBITS(mac, 0x802, 0x3);
5242
5243	/*
5244	 * Save RF/PHY registers for later restoration
5245	 */
5246	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5247	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
5248
5249	for (i = 0; i < SAVE_RF_MAX; ++i)
5250		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5251	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5252		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5253
5254	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
5255	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5256
5257	if (phy->phy_rev >= 3) {
5258		for (i = 0; i < SAVE_PHY3_MAX; ++i)
5259			save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
5260
5261		PHY_WRITE(mac, 0x2e, 0);
5262		PHY_WRITE(mac, 0x810, 0);
5263
5264		if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
5265		    phy->phy_rev == 7) {
5266			PHY_SETBITS(mac, 0x478, 0x100);
5267			PHY_SETBITS(mac, 0x810, 0x40);
5268		} else if (phy->phy_rev == 3 || phy->phy_rev == 5)
5269			PHY_CLRBITS(mac, 0x810, 0x40);
5270
5271		PHY_SETBITS(mac, 0x60, 0x40);
5272		PHY_SETBITS(mac, 0x14, 0x200);
5273	}
5274
5275	/*
5276	 * Calculate nrssi0
5277	 */
5278	RF_SETBITS(mac, 0x7a, 0x70);
5279
5280	bzero(&gains, sizeof(gains));
5281	gains.tbl_gain1 = 0;
5282	gains.tbl_gain2 = 8;
5283	gains.phy_gain = 0;
5284	bwi_set_gains(mac, &gains);
5285
5286	RF_CLRBITS(mac, 0x7a, 0xff08);
5287	if (phy->phy_rev >= 2) {
5288		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
5289		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
5290	}
5291
5292	RF_SETBITS(mac, 0x7a, 0x80);
5293	DELAY(20);
5294	nrssi[0] = bwi_nrssi_11g(mac);
5295
5296	/*
5297	 * Calculate nrssi1
5298	 */
5299	RF_CLRBITS(mac, 0x7a, 0xff80);
5300	if (phy->phy_version >= 2)
5301		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5302	CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
5303
5304	RF_SETBITS(mac, 0x7a, 0xf);
5305	PHY_WRITE(mac, 0x15, 0xf330);
5306	if (phy->phy_rev >= 2) {
5307		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
5308		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
5309	}
5310
5311	bzero(&gains, sizeof(gains));
5312	gains.tbl_gain1 = 3;
5313	gains.tbl_gain2 = 0;
5314	gains.phy_gain = 1;
5315	bwi_set_gains(mac, &gains);
5316
5317	if (rf->rf_rev == 8) {
5318		RF_WRITE(mac, 0x43, 0x1f);
5319	} else {
5320		RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
5321		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
5322	}
5323	PHY_WRITE(mac, 0x5a, 0x480);
5324	PHY_WRITE(mac, 0x59, 0x810);
5325	PHY_WRITE(mac, 0x58, 0xd);
5326	DELAY(20);
5327
5328	nrssi[1] = bwi_nrssi_11g(mac);
5329
5330	/*
5331	 * Install calculated narrow RSSI values
5332	 */
5333	if (nrssi[1] == nrssi[0])
5334		rf->rf_nrssi_slope = 0x10000;
5335	else
5336		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5337	if (nrssi[0] >= -4) {
5338		rf->rf_nrssi[0] = nrssi[1];
5339		rf->rf_nrssi[1] = nrssi[0];
5340	}
5341
5342	/*
5343	 * Restore saved RF/PHY registers
5344	 */
5345	if (phy->phy_rev >= 3) {
5346		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
5347			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5348				  save_phy3[phy3_idx]);
5349		}
5350	}
5351	if (phy->phy_rev >= 2) {
5352		PHY_CLRBITS(mac, 0x812, 0x30);
5353		PHY_CLRBITS(mac, 0x811, 0x30);
5354	}
5355
5356	for (i = 0; i < SAVE_RF_MAX; ++i)
5357		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5358
5359	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5360	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
5361	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5362
5363	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5364		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5365
5366	bwi_rf_work_around(mac, rf->rf_curchan);
5367	PHY_SETBITS(mac, 0x802, 0x3);
5368	bwi_set_gains(mac, NULL);
5369	PHY_SETBITS(mac, 0x429, 0x8000);
5370
5371	if (phy->phy_rev >= 3) {
5372		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
5373			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5374			    save_phy3[phy3_idx]);
5375		}
5376	}
5377
5378	bwi_rf_init_sw_nrssi_table(mac);
5379	bwi_rf_set_nrssi_thr_11g(mac);
5380
5381#undef SAVE_RF_MAX
5382#undef SAVE_PHY_COMM_MAX
5383#undef SAVE_PHY3_MAX
5384}
5385
5386void
5387bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
5388{
5389	struct bwi_rf *rf = &mac->mac_rf;
5390	int d, i;
5391
5392	d = 0x1f - rf->rf_nrssi[0];
5393	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5394		int val;
5395
5396		val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
5397		if (val < 0)
5398			val = 0;
5399		else if (val > 0x3f)
5400			val = 0x3f;
5401
5402		rf->rf_nrssi_table[i] = val;
5403	}
5404}
5405
5406void
5407bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
5408{
5409	int i;
5410
5411	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5412		int16_t val;
5413
5414		val = bwi_nrssi_read(mac, i);
5415
5416		val -= adjust;
5417		if (val < -32)
5418			val = -32;
5419		else if (val > 31);
5420			val = 31;
5421
5422		bwi_nrssi_write(mac, i, val);
5423	}
5424}
5425
5426void
5427bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
5428{
5429	struct bwi_rf *rf = &mac->mac_rf;
5430	int32_t thr;
5431
5432	if (rf->rf_type != BWI_RF_T_BCM2050 ||
5433	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
5434		return;
5435
5436	/*
5437	 * Calculate nrssi threshold
5438	 */
5439	if (rf->rf_rev >= 6) {
5440		thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
5441		thr += 20 * (rf->rf_nrssi[0] + 1);
5442		thr /= 40;
5443	} else {
5444		thr = rf->rf_nrssi[1] - 5;
5445	}
5446	if (thr < 0)
5447		thr = 0;
5448	else if (thr > 0x3e)
5449		thr = 0x3e;
5450
5451	PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B);	/* dummy read */
5452	PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
5453
5454	if (rf->rf_rev >= 6) {
5455		PHY_WRITE(mac, 0x87, 0xe0d);
5456		PHY_WRITE(mac, 0x86, 0xc0b);
5457		PHY_WRITE(mac, 0x85, 0xa09);
5458		PHY_WRITE(mac, 0x84, 0x808);
5459		PHY_WRITE(mac, 0x83, 0x808);
5460		PHY_WRITE(mac, 0x82, 0x604);
5461		PHY_WRITE(mac, 0x81, 0x302);
5462		PHY_WRITE(mac, 0x80, 0x100);
5463	}
5464}
5465
5466int32_t
5467_nrssi_threshold(const struct bwi_rf *rf, int32_t val)
5468{
5469	val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
5470	val += (rf->rf_nrssi[0] << 6);
5471	if (val < 32)
5472		val += 31;
5473	else
5474		val += 32;
5475	val >>= 6;
5476	if (val < -31)
5477		val = -31;
5478	else if (val > 31)
5479		val = 31;
5480
5481	return (val);
5482}
5483
5484void
5485bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
5486{
5487	int32_t thr1, thr2;
5488	uint16_t thr;
5489
5490	/*
5491	 * Find the two nrssi thresholds
5492	 */
5493	if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
5494	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
5495	    	int16_t nrssi;
5496
5497		nrssi = bwi_nrssi_read(mac, 0x20);
5498		if (nrssi >= 32)
5499			nrssi -= 64;
5500
5501		if (nrssi < 3) {
5502			thr1 = 0x2b;
5503			thr2 = 0x27;
5504		} else {
5505			thr1 = 0x2d;
5506			thr2 = 0x2b;
5507		}
5508	} else {
5509		/* TODO Interfere mode */
5510		thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
5511		thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
5512	}
5513
5514#define NRSSI_THR1_MASK		0x003f
5515#define NRSSI_THR2_MASK		0x0fc0
5516	thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
5517	    __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
5518	PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
5519#undef NRSSI_THR1_MASK
5520#undef NRSSI_THR2_MASK
5521}
5522
5523void
5524bwi_rf_clear_tssi(struct bwi_mac *mac)
5525{
5526	/* XXX use function pointer */
5527	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
5528		/* TODO:11A */
5529	} else {
5530		uint16_t val;
5531		int i;
5532
5533		val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
5534		    __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
5535
5536		for (i = 0; i < 2; ++i) {
5537			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5538			    BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
5539		}
5540
5541		for (i = 0; i < 2; ++i) {
5542			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5543			    BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
5544		}
5545	}
5546}
5547
5548void
5549bwi_rf_clear_state(struct bwi_rf *rf)
5550{
5551	int i;
5552
5553	rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
5554	bzero(rf->rf_lo, sizeof(rf->rf_lo));
5555	bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used));
5556
5557	rf->rf_nrssi_slope = 0;
5558	rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
5559	rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
5560
5561	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
5562		rf->rf_nrssi_table[i] = i;
5563
5564	rf->rf_lo_gain = 0;
5565	rf->rf_rx_gain = 0;
5566
5567	bcopy(rf->rf_txpower_map0, rf->rf_txpower_map,
5568	      sizeof(rf->rf_txpower_map));
5569	rf->rf_idle_tssi = rf->rf_idle_tssi0;
5570}
5571
5572void
5573bwi_rf_on_11a(struct bwi_mac *mac)
5574{
5575	/* TODO:11A */
5576}
5577
5578void
5579bwi_rf_on_11bg(struct bwi_mac *mac)
5580{
5581	struct bwi_phy *phy = &mac->mac_phy;
5582
5583	PHY_WRITE(mac, 0x15, 0x8000);
5584	PHY_WRITE(mac, 0x15, 0xcc00);
5585	if (phy->phy_flags & BWI_PHY_F_LINKED)
5586		PHY_WRITE(mac, 0x15, 0xc0);
5587	else
5588		PHY_WRITE(mac, 0x15, 0);
5589
5590	bwi_rf_set_chan(mac, 6 /* XXX */, 1);
5591}
5592
5593void
5594bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
5595{
5596	struct bwi_softc *sc = mac->mac_sc;
5597	struct bwi_phy *phy = &mac->mac_phy;
5598	uint16_t val;
5599
5600	KKASSERT(ant_mode == BWI_ANT_MODE_0 ||
5601	    ant_mode == BWI_ANT_MODE_1 ||
5602	    ant_mode == BWI_ANT_MODE_AUTO);
5603
5604	HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5605
5606	if (phy->phy_mode == IEEE80211_MODE_11B) {
5607		/* NOTE: v4/v3 conflicts, take v3 */
5608		if (mac->mac_rev == 2)
5609			val = BWI_ANT_MODE_AUTO;
5610		else
5611			val = ant_mode;
5612		val <<= 7;
5613		PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
5614	} else {	/* 11a/g */
5615		/* XXX reg/value naming */
5616		val = ant_mode << 7;
5617		PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
5618
5619		if (ant_mode == BWI_ANT_MODE_AUTO)
5620			PHY_CLRBITS(mac, 0x42b, 0x100);
5621
5622		if (phy->phy_mode == IEEE80211_MODE_11A) {
5623			/* TODO:11A */
5624		} else {	/* 11g */
5625			if (ant_mode == BWI_ANT_MODE_AUTO)
5626				PHY_SETBITS(mac, 0x48c, 0x2000);
5627			else
5628				PHY_CLRBITS(mac, 0x48c, 0x2000);
5629
5630			if (phy->phy_rev >= 2) {
5631				PHY_SETBITS(mac, 0x461, 0x10);
5632				PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
5633				if (phy->phy_rev == 2) {
5634					PHY_WRITE(mac, 0x427, 0x8);
5635				} else {
5636					PHY_FILT_SETBITS(mac, 0x427,
5637							 0xff00, 0x8);
5638				}
5639
5640				if (phy->phy_rev >= 6)
5641					PHY_WRITE(mac, 0x49b, 0xdc);
5642			}
5643		}
5644	}
5645
5646	/* XXX v4 set AUTO_ANTDIV unconditionally */
5647	if (ant_mode == BWI_ANT_MODE_AUTO)
5648		HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5649
5650	val = ant_mode << 8;
5651	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
5652	    0xfc3f, val);
5653	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
5654	    0xfc3f, val);
5655	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
5656	    0xfc3f, val);
5657
5658	/* XXX what's these */
5659	if (phy->phy_mode == IEEE80211_MODE_11B)
5660		CSR_SETBITS_2(sc, 0x5e, 0x4);
5661
5662	CSR_WRITE_4(sc, 0x100, 0x1000000);
5663	if (mac->mac_rev < 5)
5664		CSR_WRITE_4(sc, 0x10c, 0x1000000);
5665
5666	mac->mac_rf.rf_ant_mode = ant_mode;
5667}
5668
5669int
5670bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
5671{
5672	int i;
5673
5674	for (i = 0; i < 4; ) {
5675		uint16_t val;
5676
5677		val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
5678		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
5679		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
5680	}
5681
5682	for (i = 0; i < 4; ++i) {
5683		if (tssi[i] == BWI_INVALID_TSSI)
5684			return (EINVAL);
5685	}
5686
5687	return (0);
5688}
5689
5690int
5691bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
5692{
5693	struct bwi_rf *rf = &mac->mac_rf;
5694	int pwr_idx;
5695
5696	pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
5697#if 0
5698	if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
5699		return EINVAL;
5700#else
5701	if (pwr_idx < 0)
5702		pwr_idx = 0;
5703	else if (pwr_idx >= BWI_TSSI_MAX)
5704		pwr_idx = BWI_TSSI_MAX - 1;
5705#endif
5706	*txpwr = rf->rf_txpower_map[pwr_idx];
5707
5708	return (0);
5709}
5710
5711/* IF_BWI */
5712
5713uint16_t
5714bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
5715{
5716	return (CSR_READ_2(sc, ofs + BWI_SPROM_START));
5717}
5718
5719void
5720bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
5721    int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx)
5722{
5723	struct bwi_desc32 *desc = &desc_array[desc_idx];
5724	uint32_t ctrl, addr, addr_hi, addr_lo;
5725
5726	addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK);
5727	addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK);
5728
5729	addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) |
5730	    __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK);
5731
5732	ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) |
5733	     __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK);
5734	if (desc_idx == ndesc - 1)
5735		ctrl |= BWI_DESC32_C_EOR;
5736	if (tx) {
5737		/* XXX */
5738		ctrl |= BWI_DESC32_C_FRAME_START |
5739		    BWI_DESC32_C_FRAME_END |
5740		    BWI_DESC32_C_INTR;
5741	}
5742
5743	desc->addr = htole32(addr);
5744	desc->ctrl = htole32(ctrl);
5745}
5746
5747void
5748bwi_power_on(struct bwi_softc *sc, int with_pll)
5749{
5750	uint32_t gpio_in, gpio_out, gpio_en, status;
5751
5752	DPRINTF(1, "%s\n", __func__);
5753
5754	gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN);
5755	if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
5756		goto back;
5757
5758	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
5759	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
5760
5761	gpio_out |= BWI_PCIM_GPIO_PWR_ON;
5762	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
5763	if (with_pll) {
5764		/* Turn off PLL first */
5765		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5766		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5767	}
5768
5769	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5770	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
5771	DELAY(1000);
5772
5773	if (with_pll) {
5774		/* Turn on PLL */
5775		gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
5776		(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5777		DELAY(5000);
5778	}
5779
5780back:
5781	/* Clear "Signaled Target Abort" */
5782	status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG);
5783	status &= ~PCI_STATUS_TARGET_TARGET_ABORT;
5784	(sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status);
5785}
5786
5787int
5788bwi_power_off(struct bwi_softc *sc, int with_pll)
5789{
5790	uint32_t gpio_out, gpio_en;
5791
5792	DPRINTF(1, "%s\n", __func__);
5793
5794	(sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */
5795	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
5796	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
5797
5798	gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
5799	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
5800	if (with_pll) {
5801		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5802		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5803	}
5804
5805	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5806	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
5807
5808	return (0);
5809}
5810
5811int
5812bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
5813    struct bwi_regwin **old_rw)
5814{
5815	int error;
5816
5817	if (old_rw != NULL)
5818		*old_rw = NULL;
5819
5820	if (!BWI_REGWIN_EXIST(rw))
5821		return (EINVAL);
5822
5823	if (sc->sc_cur_regwin != rw) {
5824		error = bwi_regwin_select(sc, rw->rw_id);
5825		if (error) {
5826			DPRINTF(1, "%s: can't select regwin %d\n",
5827			    sc->sc_dev.dv_xname, rw->rw_id);
5828			return (error);
5829		}
5830	}
5831
5832	if (old_rw != NULL)
5833		*old_rw = sc->sc_cur_regwin;
5834	sc->sc_cur_regwin = rw;
5835
5836	return (0);
5837}
5838
5839int
5840bwi_regwin_select(struct bwi_softc *sc, int id)
5841{
5842	uint32_t win = BWI_PCIM_REGWIN(id);
5843	int i;
5844
5845#define RETRY_MAX	50
5846	for (i = 0; i < RETRY_MAX; ++i) {
5847		(sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win);
5848		if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win)
5849			return (0);
5850		DELAY(10);
5851	}
5852#undef RETRY_MAX
5853
5854	return (ENXIO);
5855}
5856
5857void
5858bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
5859{
5860	uint32_t val;
5861
5862	val = CSR_READ_4(sc, BWI_ID_HI);
5863	*type = BWI_ID_HI_REGWIN_TYPE(val);
5864	*rev = BWI_ID_HI_REGWIN_REV(val);
5865
5866	DPRINTF(1, "%s: regwin: type 0x%03x, rev %d, vendor 0x%04x\n",
5867	    sc->sc_dev.dv_xname,
5868	    *type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
5869}
5870
5871int
5872bwi_bbp_attach(struct bwi_softc *sc)
5873{
5874#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
5875	uint16_t bbp_id, rw_type;
5876	uint8_t rw_rev;
5877	uint32_t info;
5878	int error, nregwin, i;
5879
5880	/*
5881	 * Get 0th regwin information
5882	 * NOTE: 0th regwin should exist
5883	 */
5884	error = bwi_regwin_select(sc, 0);
5885	if (error) {
5886		DPRINTF(1, "%s: can't select regwin 0\n", sc->sc_dev.dv_xname);
5887		return (error);
5888	}
5889	bwi_regwin_info(sc, &rw_type, &rw_rev);
5890
5891	/*
5892	 * Find out BBP id
5893	 */
5894	bbp_id = 0;
5895	info = 0;
5896	if (rw_type == BWI_REGWIN_T_COM) {
5897		info = CSR_READ_4(sc, BWI_INFO);
5898		bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
5899
5900		BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
5901
5902		sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
5903	} else {
5904		uint16_t did = sc->sc_pci_did;
5905		uint8_t revid = sc->sc_pci_revid;
5906
5907		for (i = 0; i < N(bwi_bbpid_map); ++i) {
5908			if (did >= bwi_bbpid_map[i].did_min &&
5909			    did <= bwi_bbpid_map[i].did_max) {
5910				bbp_id = bwi_bbpid_map[i].bbp_id;
5911				break;
5912			}
5913		}
5914		if (bbp_id == 0) {
5915			DPRINTF(1, "%s: no BBP id for device id 0x%04x\n",
5916			    sc->sc_dev.dv_xname, did);
5917			return (ENXIO);
5918		}
5919
5920		info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) |
5921		    __SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
5922	}
5923
5924	/*
5925	 * Find out number of regwins
5926	 */
5927	nregwin = 0;
5928	if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
5929		nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
5930	} else {
5931		for (i = 0; i < N(bwi_regwin_count); ++i) {
5932			if (bwi_regwin_count[i].bbp_id == bbp_id) {
5933				nregwin = bwi_regwin_count[i].nregwin;
5934				break;
5935			}
5936		}
5937		if (nregwin == 0) {
5938			DPRINTF(1, "%s: no number of win for BBP id 0x%04x\n",
5939			    sc->sc_dev.dv_xname, bbp_id);
5940			return (ENXIO);
5941		}
5942	}
5943
5944	/* Record BBP id/rev for later using */
5945	sc->sc_bbp_id = bbp_id;
5946	sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
5947	sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
5948	DPRINTF(1, "%s: BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
5949	    sc->sc_dev.dv_xname, sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
5950	DPRINTF(1, "%s: nregwin %d, cap 0x%08x\n",
5951	    sc->sc_dev.dv_xname, nregwin, sc->sc_cap);
5952
5953	/*
5954	 * Create rest of the regwins
5955	 */
5956
5957	/* Don't re-create common regwin, if it is already created */
5958	i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
5959
5960	for (; i < nregwin; ++i) {
5961		/*
5962		 * Get regwin information
5963		 */
5964		error = bwi_regwin_select(sc, i);
5965		if (error) {
5966			DPRINTF(1, "%s: can't select regwin %d\n",
5967			    sc->sc_dev.dv_xname, i);
5968			return (error);
5969		}
5970		bwi_regwin_info(sc, &rw_type, &rw_rev);
5971
5972		/*
5973		 * Try attach:
5974		 * 1) Bus (PCI/PCIE) regwin
5975		 * 2) MAC regwin
5976		 * Ignore rest types of regwin
5977		 */
5978		if (rw_type == BWI_REGWIN_T_BUSPCI ||
5979		    rw_type == BWI_REGWIN_T_BUSPCIE) {
5980			if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
5981				DPRINTF(1, "%s: bus regwin already exists\n",
5982				    sc->sc_dev.dv_xname);
5983			} else {
5984				BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
5985				    rw_type, rw_rev);
5986			}
5987		} else if (rw_type == BWI_REGWIN_T_MAC) {
5988			/* XXX ignore return value */
5989			bwi_mac_attach(sc, i, rw_rev);
5990		}
5991	}
5992
5993	/* At least one MAC shold exist */
5994	if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
5995		DPRINTF(1, "%s: no MAC was found\n", sc->sc_dev.dv_xname);
5996		return (ENXIO);
5997	}
5998	KKASSERT(sc->sc_nmac > 0);
5999
6000	/* Bus regwin must exist */
6001	if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6002		DPRINTF(1, "%s: no bus regwin was found\n",
6003		    sc->sc_dev.dv_xname);
6004		return (ENXIO);
6005	}
6006
6007	/* Start with first MAC */
6008	error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
6009	if (error)
6010		return (error);
6011
6012	return (0);
6013#undef N
6014}
6015
6016int
6017bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6018{
6019	struct bwi_regwin *old, *bus;
6020	uint32_t val;
6021	int error;
6022
6023	bus = &sc->sc_bus_regwin;
6024	KKASSERT(sc->sc_cur_regwin == &mac->mac_regwin);
6025
6026	/*
6027	 * Tell bus to generate requested interrupts
6028	 */
6029	if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6030		/*
6031		 * NOTE: Read BWI_FLAGS from MAC regwin
6032		 */
6033		val = CSR_READ_4(sc, BWI_FLAGS);
6034
6035		error = bwi_regwin_switch(sc, bus, &old);
6036		if (error)
6037			return (error);
6038
6039		CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
6040	} else {
6041		uint32_t mac_mask;
6042
6043		mac_mask = 1 << mac->mac_id;
6044
6045		error = bwi_regwin_switch(sc, bus, &old);
6046		if (error)
6047			return (error);
6048
6049		val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL);
6050		val |= mac_mask << 8;
6051		(sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val);
6052	}
6053
6054	if (sc->sc_flags & BWI_F_BUS_INITED)
6055		goto back;
6056
6057	if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6058		/*
6059		 * Enable prefetch and burst
6060		 */
6061		CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
6062		    BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
6063
6064		if (bus->rw_rev < 5) {
6065			struct bwi_regwin *com = &sc->sc_com_regwin;
6066
6067			/*
6068			 * Configure timeouts for bus operation
6069			 */
6070
6071			/*
6072			 * Set service timeout and request timeout
6073			 */
6074			CSR_SETBITS_4(sc, BWI_CONF_LO,
6075			    __SHIFTIN(BWI_CONF_LO_SERVTO,
6076			    BWI_CONF_LO_SERVTO_MASK) |
6077			    __SHIFTIN(BWI_CONF_LO_REQTO,
6078			    BWI_CONF_LO_REQTO_MASK));
6079
6080			/*
6081			 * If there is common regwin, we switch to that regwin
6082			 * and switch back to bus regwin once we have done.
6083			 */
6084			if (BWI_REGWIN_EXIST(com)) {
6085				error = bwi_regwin_switch(sc, com, NULL);
6086				if (error)
6087					return (error);
6088			}
6089
6090			/* Let bus know what we have changed */
6091			CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
6092			CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
6093			CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
6094			CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
6095
6096			if (BWI_REGWIN_EXIST(com)) {
6097				error = bwi_regwin_switch(sc, bus, NULL);
6098				if (error)
6099					return (error);
6100			}
6101		} else if (bus->rw_rev >= 11) {
6102			/*
6103			 * Enable memory read multiple
6104			 */
6105			CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
6106		}
6107	} else {
6108		/* TODO:PCIE */
6109	}
6110
6111	sc->sc_flags |= BWI_F_BUS_INITED;
6112back:
6113	return (bwi_regwin_switch(sc, old, NULL));
6114}
6115
6116void
6117bwi_get_card_flags(struct bwi_softc *sc)
6118{
6119	sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
6120	if (sc->sc_card_flags == 0xffff)
6121		sc->sc_card_flags = 0;
6122
6123	if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
6124	    sc->sc_pci_subdid == 0x4e && /* XXX */
6125	    sc->sc_pci_revid > 0x40)
6126		sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
6127
6128	DPRINTF(1, "%s: card flags 0x%04x\n",
6129	    sc->sc_dev.dv_xname, sc->sc_card_flags);
6130}
6131
6132void
6133bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
6134{
6135	int i;
6136
6137	for (i = 0; i < 3; ++i) {
6138		*((uint16_t *)eaddr + i) =
6139		    htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
6140	}
6141}
6142
6143void
6144bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
6145{
6146	struct bwi_regwin *com;
6147	uint32_t val;
6148	u_int div;
6149	int src;
6150
6151	bzero(freq, sizeof(*freq));
6152	com = &sc->sc_com_regwin;
6153
6154	KKASSERT(BWI_REGWIN_EXIST(com));
6155	KKASSERT(sc->sc_cur_regwin == com);
6156	KKASSERT(sc->sc_cap & BWI_CAP_CLKMODE);
6157
6158	/*
6159	 * Calculate clock frequency
6160	 */
6161	src = -1;
6162	div = 0;
6163	if (com->rw_rev < 6) {
6164		val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6165		if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
6166			src = BWI_CLKSRC_PCI;
6167			div = 64;
6168		} else {
6169			src = BWI_CLKSRC_CS_OSC;
6170			div = 32;
6171		}
6172	} else if (com->rw_rev < 10) {
6173		val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6174
6175		src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
6176		if (src == BWI_CLKSRC_LP_OSC)
6177			div = 1;
6178		else {
6179			div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
6180
6181			/* Unknown source */
6182			if (src >= BWI_CLKSRC_MAX)
6183				src = BWI_CLKSRC_CS_OSC;
6184		}
6185	} else {
6186		val = CSR_READ_4(sc, BWI_CLOCK_INFO);
6187
6188		src = BWI_CLKSRC_CS_OSC;
6189		div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
6190	}
6191
6192	KKASSERT(src >= 0 && src < BWI_CLKSRC_MAX);
6193	KKASSERT(div != 0);
6194
6195	DPRINTF(1, "%s: clksrc %s\n",
6196	    sc->sc_dev.dv_xname,
6197	    src == BWI_CLKSRC_PCI ? "PCI" :
6198	    (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
6199
6200	freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
6201	freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
6202
6203	DPRINTF(1, "%s: clkfreq min %u, max %u\n",
6204	    sc->sc_dev.dv_xname, freq->clkfreq_min, freq->clkfreq_max);
6205}
6206
6207int
6208bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
6209{
6210	struct bwi_regwin *old, *com;
6211	uint32_t clk_ctrl, clk_src;
6212	int error, pwr_off = 0;
6213
6214	com = &sc->sc_com_regwin;
6215	if (!BWI_REGWIN_EXIST(com))
6216		return (0);
6217
6218	if (com->rw_rev >= 10 || com->rw_rev < 6)
6219		return (0);
6220
6221	/*
6222	 * For common regwin whose rev is [6, 10), the chip
6223	 * must be capable to change clock mode.
6224	 */
6225	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
6226		return (0);
6227
6228	error = bwi_regwin_switch(sc, com, &old);
6229	if (error)
6230		return (error);
6231
6232	if (clk_mode == BWI_CLOCK_MODE_FAST)
6233		bwi_power_on(sc, 0);	/* Don't turn on PLL */
6234
6235	clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6236	clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
6237
6238	switch (clk_mode) {
6239	case BWI_CLOCK_MODE_FAST:
6240		clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
6241		clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
6242		break;
6243	case BWI_CLOCK_MODE_SLOW:
6244		clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
6245		break;
6246	case BWI_CLOCK_MODE_DYN:
6247		clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
6248		    BWI_CLOCK_CTRL_IGNPLL |
6249		    BWI_CLOCK_CTRL_NODYN);
6250		if (clk_src != BWI_CLKSRC_CS_OSC) {
6251			clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
6252			pwr_off = 1;
6253		}
6254		break;
6255	}
6256	CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
6257
6258	if (pwr_off)
6259		bwi_power_off(sc, 0);	/* Leave PLL as it is */
6260
6261	return (bwi_regwin_switch(sc, old, NULL));
6262}
6263
6264int
6265bwi_set_clock_delay(struct bwi_softc *sc)
6266{
6267	struct bwi_regwin *old, *com;
6268	int error;
6269
6270	com = &sc->sc_com_regwin;
6271	if (!BWI_REGWIN_EXIST(com))
6272		return (0);
6273
6274	error = bwi_regwin_switch(sc, com, &old);
6275	if (error)
6276		return (error);
6277
6278	if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
6279		if (sc->sc_bbp_rev == 0)
6280			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
6281		else if (sc->sc_bbp_rev == 1)
6282			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
6283	}
6284
6285	if (sc->sc_cap & BWI_CAP_CLKMODE) {
6286		if (com->rw_rev >= 10)
6287			CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
6288		else {
6289			struct bwi_clock_freq freq;
6290
6291			bwi_get_clock_freq(sc, &freq);
6292			CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
6293			    howmany(freq.clkfreq_max * 150, 1000000));
6294			CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
6295			    howmany(freq.clkfreq_max * 15, 1000000));
6296		}
6297	}
6298
6299	return (bwi_regwin_switch(sc, old, NULL));
6300}
6301
6302int
6303bwi_init(struct ifnet *ifp)
6304{
6305	struct bwi_softc *sc = ifp->if_softc;
6306	struct ieee80211com *ic = &sc->sc_ic;
6307	struct bwi_mac *mac;
6308	int error;
6309
6310	DPRINTF(1, "%s\n", __func__);
6311
6312	error = bwi_stop(sc);
6313	if (error) {
6314		DPRINTF(1, "%s: can't stop\n", sc->sc_dev.dv_xname);
6315		return (1);
6316	}
6317
6318	/* power on cardbus socket */
6319	if (sc->sc_enable != NULL)
6320		(*sc->sc_enable)(sc);
6321
6322	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
6323
6324	/* TODO: 2 MAC */
6325
6326	mac = &sc->sc_mac[0];
6327	error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
6328	if (error)
6329		goto back;
6330
6331	error = bwi_mac_init(mac);
6332	if (error)
6333		goto back;
6334
6335	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
6336
6337	IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
6338
6339	bwi_set_bssid(sc, bwi_zero_addr);	/* Clear BSSID */
6340	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr);
6341
6342	bwi_mac_reset_hwkeys(mac);
6343
6344	if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
6345		int i;
6346
6347#define NRETRY	1000
6348		/*
6349		 * Drain any possible pending TX status
6350		 */
6351		for (i = 0; i < NRETRY; ++i) {
6352			if ((CSR_READ_4(sc, BWI_TXSTATUS_0) &
6353			     BWI_TXSTATUS_0_MORE) == 0)
6354				break;
6355			CSR_READ_4(sc, BWI_TXSTATUS_1);
6356		}
6357		if (i == NRETRY)
6358			DPRINTF(1, "%s: can't drain TX status\n",
6359			    sc->sc_dev.dv_xname);
6360#undef NRETRY
6361	}
6362
6363	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
6364		bwi_mac_updateslot(mac, 1);
6365
6366	/* Start MAC */
6367	error = bwi_mac_start(mac);
6368	if (error)
6369		goto back;
6370
6371	/* Enable intrs */
6372	bwi_enable_intrs(sc, BWI_INIT_INTRS);
6373
6374	ifp->if_flags |= IFF_RUNNING;
6375	ifp->if_flags &= ~IFF_OACTIVE;
6376
6377	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6378		/* start background scanning */
6379		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
6380	else
6381		/* in monitor mode change directly into run state */
6382		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
6383back:
6384	if (error)
6385		bwi_stop(sc);
6386
6387	return (0);
6388}
6389
6390int
6391bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
6392{
6393	struct bwi_softc *sc = ifp->if_softc;
6394	struct ieee80211com *ic = &sc->sc_ic;
6395	struct ifaddr *ifa;
6396	struct ifreq *ifr;
6397	int s, error = 0;
6398	uint8_t chan;
6399
6400	s = splnet();
6401
6402	switch (cmd) {
6403	case SIOCSIFADDR:
6404		ifa = (struct ifaddr *)data;
6405		ifp->if_flags |= IFF_UP;
6406#ifdef INET
6407		if (ifa->ifa_addr->sa_family == AF_INET)
6408			arp_ifinit(&ic->ic_ac, ifa);
6409#endif
6410		/* FALLTHROUGH */
6411	case SIOCSIFFLAGS:
6412		if (ifp->if_flags & IFF_UP) {
6413			if ((ifp->if_flags & IFF_RUNNING) == 0)
6414				bwi_init(ifp);
6415		} else {
6416			if (ifp->if_flags & IFF_RUNNING)
6417				bwi_stop(sc);
6418		}
6419		break;
6420        case SIOCADDMULTI:
6421        case SIOCDELMULTI:
6422		ifr = (struct ifreq *)data;
6423		error = (cmd == SIOCADDMULTI) ?
6424		    ether_addmulti(ifr, &ic->ic_ac) :
6425		    ether_delmulti(ifr, &ic->ic_ac);
6426
6427		if (error == ENETRESET)
6428			error = 0;
6429		break;
6430	case SIOCS80211CHANNEL:
6431		/* allow fast channel switching in monitor mode */
6432		error = ieee80211_ioctl(ifp, cmd, data);
6433		if (error == ENETRESET &&
6434		    ic->ic_opmode == IEEE80211_M_MONITOR) {
6435			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6436			    (IFF_UP | IFF_RUNNING)) {
6437				ic->ic_bss->ni_chan = ic->ic_ibss_chan;
6438				chan = ieee80211_chan2ieee(ic,
6439				    ic->ic_bss->ni_chan);
6440				bwi_set_chan(sc, chan);
6441			}
6442			error = 0;
6443		}
6444		break;
6445	default:
6446		error = ieee80211_ioctl(ifp, cmd, data);
6447		break;
6448	}
6449
6450	if (error == ENETRESET) {
6451		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6452		    (IFF_UP | IFF_RUNNING))
6453			bwi_init(ifp);
6454		error = 0;
6455	}
6456
6457	splx(s);
6458
6459	return (error);
6460}
6461
6462void
6463bwi_start(struct ifnet *ifp)
6464{
6465	struct bwi_softc *sc = ifp->if_softc;
6466	struct ieee80211com *ic = &sc->sc_ic;
6467	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
6468	int trans, idx;
6469
6470	if ((ifp->if_flags & IFF_OACTIVE) || (ifp->if_flags & IFF_RUNNING) == 0)
6471		return;
6472
6473	trans = 0;
6474	idx = tbd->tbd_idx;
6475
6476	while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
6477		struct ieee80211_frame *wh;
6478		struct ieee80211_node *ni;
6479		struct mbuf *m;
6480		int mgt_pkt = 0;
6481
6482		IF_POLL(&ic->ic_mgtq, m);
6483		if (m != NULL) {
6484			IF_DEQUEUE(&ic->ic_mgtq, m);
6485
6486			ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
6487			m->m_pkthdr.rcvif = NULL;
6488
6489			mgt_pkt = 1;
6490		} else {
6491			struct ether_header *eh;
6492
6493			if (ic->ic_state != IEEE80211_S_RUN)
6494				break;
6495
6496			IFQ_POLL(&ifp->if_snd, m);
6497			if (m == NULL)
6498				break;
6499
6500			IFQ_DEQUEUE(&ifp->if_snd, m);
6501
6502			if (m->m_len < sizeof(*eh)) {
6503				m = m_pullup(m, sizeof(*eh));
6504				if (m == NULL) {
6505					ifp->if_oerrors++;
6506					continue;
6507				}
6508			}
6509			eh = mtod(m, struct ether_header *);
6510
6511			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
6512			if (ni == NULL) {
6513				m_freem(m);
6514				ifp->if_oerrors++;
6515				continue;
6516			}
6517
6518			/* TODO: PS */
6519#if NBPFILTER > 0
6520			if (ifp->if_bpf != NULL)
6521				bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
6522#endif
6523			m = ieee80211_encap(ifp, m, &ni);
6524			if (m == NULL)
6525				continue;
6526		}
6527#if NBPFILTER > 0
6528		if (ic->ic_rawbpf != NULL)
6529			bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
6530#endif
6531		wh = mtod(m, struct ieee80211_frame *);
6532		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
6533			m = ieee80211_wep_crypt(ifp, m, 1);
6534			if (m == NULL)
6535				return;
6536		}
6537		wh = NULL;	/* Catch any invalid use */
6538
6539		if (mgt_pkt) {
6540			ieee80211_release_node(ic, ni);
6541			ni = NULL;
6542		}
6543
6544		if (bwi_encap(sc, idx, m, ni) != 0) {
6545			/* 'm' is freed in bwi_encap() if we reach here */
6546			if (ni != NULL)
6547				ieee80211_release_node(ic, ni);
6548			ifp->if_oerrors++;
6549			continue;
6550		}
6551
6552		trans = 1;
6553		tbd->tbd_used++;
6554		idx = (idx + 1) % BWI_TX_NDESC;
6555
6556		if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
6557			ifp->if_flags |= IFF_OACTIVE;
6558			break;
6559		}
6560	}
6561	tbd->tbd_idx = idx;
6562
6563	if (trans)
6564		sc->sc_tx_timer = 5;
6565	ifp->if_timer = 1;
6566}
6567
6568void
6569bwi_watchdog(struct ifnet *ifp)
6570{
6571	struct bwi_softc *sc = ifp->if_softc;
6572
6573	ifp->if_timer = 0;
6574
6575	if ((ifp->if_flags & IFF_RUNNING) == 0)
6576		return;
6577
6578	if (sc->sc_tx_timer) {
6579		if (--sc->sc_tx_timer == 0) {
6580			DPRINTF(1, "%s: watchdog timeout\n",
6581			    sc->sc_dev.dv_xname);
6582			ifp->if_oerrors++;
6583			/* TODO */
6584		} else
6585			ifp->if_timer = 1;
6586	}
6587
6588	ieee80211_watchdog(ifp);
6589}
6590
6591int
6592bwi_stop(struct bwi_softc *sc)
6593{
6594	struct ieee80211com *ic = &sc->sc_ic;
6595	struct ifnet *ifp = &ic->ic_if;
6596	struct bwi_mac *mac;
6597	int i, error, pwr_off = 0;
6598
6599	DPRINTF(1, "%s\n", __func__);
6600
6601	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
6602
6603	if (ifp->if_flags & IFF_RUNNING) {
6604		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
6605		mac = (struct bwi_mac *)sc->sc_cur_regwin;
6606
6607		bwi_disable_intrs(sc, BWI_ALL_INTRS);
6608		CSR_READ_4(sc, BWI_MAC_INTR_MASK);
6609		bwi_mac_stop(mac);
6610	}
6611
6612	for (i = 0; i < sc->sc_nmac; ++i) {
6613		struct bwi_regwin *old_rw;
6614
6615		mac = &sc->sc_mac[i];
6616		if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
6617			continue;
6618
6619		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
6620		if (error)
6621			continue;
6622
6623		bwi_mac_shutdown(mac);
6624		pwr_off = 1;
6625
6626		bwi_regwin_switch(sc, old_rw, NULL);
6627	}
6628
6629	if (pwr_off)
6630		bwi_bbp_power_off(sc);
6631
6632	sc->sc_tx_timer = 0;
6633	ifp->if_timer = 0;
6634	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
6635
6636	/* power off cardbus socket */
6637	if (sc->sc_disable)
6638		sc->sc_disable(sc);
6639
6640	return (0);
6641}
6642
6643int
6644bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
6645{
6646	struct bwi_softc *sc = ic->ic_if.if_softc;
6647	int error;
6648	uint8_t chan;
6649
6650	timeout_del(&sc->sc_scan_ch);
6651	timeout_del(&sc->sc_calib_ch);
6652
6653	if (nstate == IEEE80211_S_INIT)
6654		goto back;
6655
6656	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
6657	error = bwi_set_chan(sc, chan);
6658	if (error) {
6659		DPRINTF(1, "%s: can't set channel to %u\n",
6660		    sc->sc_dev.dv_xname,
6661		    ieee80211_chan2ieee(ic, ic->ic_des_chan));
6662		return (error);
6663	}
6664
6665	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6666		/* Nothing to do */
6667	} else if (nstate == IEEE80211_S_RUN) {
6668		struct bwi_mac *mac;
6669
6670		bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
6671
6672		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
6673		mac = (struct bwi_mac *)sc->sc_cur_regwin;
6674
6675		/* Initial TX power calibration */
6676		bwi_mac_calibrate_txpower(mac);
6677	} else
6678		bwi_set_bssid(sc, bwi_zero_addr);
6679
6680back:
6681	error = sc->sc_newstate(ic, nstate, arg);
6682
6683	if (nstate == IEEE80211_S_SCAN) {
6684		timeout_add(&sc->sc_scan_ch,
6685			      (sc->sc_dwell_time * hz) / 1000);
6686	} else if (nstate == IEEE80211_S_RUN) {
6687		/* XXX 15 seconds */
6688		timeout_add(&sc->sc_calib_ch, hz * 15);
6689	}
6690
6691	return (error);
6692}
6693
6694int
6695bwi_media_change(struct ifnet *ifp)
6696{
6697	int error;
6698
6699	error = ieee80211_media_change(ifp);
6700	if (error != ENETRESET)
6701		return (error);
6702
6703	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
6704		bwi_init(ifp);
6705
6706	return (0);
6707}
6708
6709int
6710bwi_dma_alloc(struct bwi_softc *sc)
6711{
6712	int error, i, has_txstats;
6713	bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
6714	uint32_t txrx_ctrl_step = 0;
6715
6716	has_txstats = 0;
6717	for (i = 0; i < sc->sc_nmac; ++i) {
6718		if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
6719			has_txstats = 1;
6720			break;
6721		}
6722	}
6723
6724	switch (sc->sc_bus_space) {
6725	case BWI_BUS_SPACE_30BIT:
6726	case BWI_BUS_SPACE_32BIT:
6727		desc_sz = sizeof(struct bwi_desc32);
6728		txrx_ctrl_step = 0x20;
6729
6730		sc->sc_init_tx_ring = bwi_init_tx_ring32;
6731		sc->sc_free_tx_ring = bwi_free_tx_ring32;
6732		sc->sc_init_rx_ring = bwi_init_rx_ring32;
6733		sc->sc_free_rx_ring = bwi_free_rx_ring32;
6734		sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
6735		sc->sc_setup_txdesc = bwi_setup_tx_desc32;
6736		sc->sc_rxeof = bwi_rxeof32;
6737		sc->sc_start_tx = bwi_start_tx32;
6738		if (has_txstats) {
6739			sc->sc_init_txstats = bwi_init_txstats32;
6740			sc->sc_free_txstats = bwi_free_txstats32;
6741			sc->sc_txeof_status = bwi_txeof_status32;
6742		}
6743		break;
6744
6745	case BWI_BUS_SPACE_64BIT:
6746		desc_sz = sizeof(struct bwi_desc64);
6747		txrx_ctrl_step = 0x40;
6748
6749		sc->sc_init_tx_ring = bwi_init_tx_ring64;
6750		sc->sc_free_tx_ring = bwi_free_tx_ring64;
6751		sc->sc_init_rx_ring = bwi_init_rx_ring64;
6752		sc->sc_free_rx_ring = bwi_free_rx_ring64;
6753		sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
6754		sc->sc_setup_txdesc = bwi_setup_tx_desc64;
6755		sc->sc_rxeof = bwi_rxeof64;
6756		sc->sc_start_tx = bwi_start_tx64;
6757		if (has_txstats) {
6758			sc->sc_init_txstats = bwi_init_txstats64;
6759			sc->sc_free_txstats = bwi_free_txstats64;
6760			sc->sc_txeof_status = bwi_txeof_status64;
6761		}
6762		break;
6763	}
6764
6765	KKASSERT(desc_sz != 0);
6766	KKASSERT(txrx_ctrl_step != 0);
6767
6768	tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
6769	rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
6770
6771#define TXRX_CTRL(idx)	(BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
6772	/*
6773	 * Create TX ring DMA stuffs
6774	 */
6775	for (i = 0; i < BWI_TX_NRING; ++i) {
6776		error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1,
6777		    tx_ring_sz, 0, BUS_DMA_NOWAIT,
6778		    &sc->sc_tx_rdata[i].rdata_dmap);
6779		if (error) {
6780			DPRINTF(1, "%s: %dth TX ring DMA create failed\n",
6781			    sc->sc_dev.dv_xname, i);
6782			return (error);
6783		}
6784		error = bwi_dma_ring_alloc(sc,
6785		    &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
6786		if (error) {
6787			DPRINTF(1, "%s: %dth TX ring DMA alloc failed\n",
6788			    sc->sc_dev.dv_xname, i);
6789			return (error);
6790		}
6791	}
6792
6793	/*
6794	 * Create RX ring DMA stuffs
6795	 */
6796	error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1,
6797	    rx_ring_sz, 0, BUS_DMA_NOWAIT,
6798	    &sc->sc_rx_rdata.rdata_dmap);
6799	if (error) {
6800		DPRINTF(1, "%s: RX ring DMA create failed\n",
6801		    sc->sc_dev.dv_xname);
6802		return (error);
6803	}
6804
6805	error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
6806	    rx_ring_sz, TXRX_CTRL(0));
6807	if (error) {
6808		DPRINTF(1, "%s: RX ring DMA alloc failed\n",
6809		    sc->sc_dev.dv_xname);
6810		return (error);
6811	}
6812
6813	if (has_txstats) {
6814		error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
6815		if (error) {
6816			DPRINTF(1, "%s: TX stats DMA alloc failed\n",
6817			    sc->sc_dev.dv_xname);
6818			return (error);
6819		}
6820	}
6821#undef TXRX_CTRL
6822
6823	return (bwi_dma_mbuf_create(sc));
6824}
6825
6826void
6827bwi_dma_free(struct bwi_softc *sc)
6828{
6829	int i;
6830
6831	for (i = 0; i < BWI_TX_NRING; ++i) {
6832		struct bwi_ring_data *rd = &sc->sc_tx_rdata[i];
6833
6834		if (rd->rdata_desc != NULL) {
6835			bus_dmamap_unload(sc->sc_dmat,
6836			    rd->rdata_dmap);
6837			bus_dmamem_free(sc->sc_dmat,
6838			    &rd->rdata_seg, 1);
6839		}
6840	}
6841
6842	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
6843
6844	if (rd->rdata_desc != NULL) {
6845		bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
6846		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1);
6847	}
6848
6849	bwi_dma_txstats_free(sc);
6850	bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
6851}
6852
6853int
6854bwi_dma_ring_alloc(struct bwi_softc *sc,
6855    struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
6856{
6857	int error, nsegs;
6858
6859	error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0,
6860	    &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT);
6861	if (error) {
6862		DPRINTF(1, "%s: can't allocate DMA mem\n", sc->sc_dev.dv_xname);
6863		return (error);
6864	}
6865
6866	error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs,
6867	    size, (caddr_t *)&rd->rdata_desc, BUS_DMA_NOWAIT);
6868	if (error) {
6869		DPRINTF(1, "%s: can't map DMA mem\n", sc->sc_dev.dv_xname);
6870		return (error);
6871	}
6872
6873	error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
6874	    size, NULL, BUS_DMA_WAITOK);
6875	if (error) {
6876		DPRINTF(1, "%s: can't load DMA mem\n", sc->sc_dev.dv_xname);
6877		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs);
6878		rd->rdata_desc = NULL;
6879		return (error);
6880	}
6881
6882	rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
6883	rd->rdata_txrx_ctrl = txrx_ctrl;
6884
6885	return (0);
6886}
6887
6888int
6889bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
6890    bus_size_t desc_sz)
6891{
6892	struct bwi_txstats_data *st;
6893	bus_size_t dma_size;
6894	int error, nsegs;
6895
6896	st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
6897	sc->sc_txstats = st;
6898
6899	/*
6900	 * Create TX stats descriptor DMA stuffs
6901	 */
6902	dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
6903
6904	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
6905	    BUS_DMA_NOWAIT, &st->stats_ring_dmap);
6906	if (error) {
6907		DPRINTF(1, "%s: can't create txstats ring DMA mem\n",
6908		    sc->sc_dev.dv_xname);
6909		return (error);
6910	}
6911
6912	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
6913	     &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
6914	if (error) {
6915		DPRINTF(1, "%s: can't allocate txstats ring DMA mem\n",
6916		    sc->sc_dev.dv_xname);
6917		return (error);
6918	}
6919
6920	error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
6921	    dma_size, (caddr_t *)&st->stats_ring, BUS_DMA_NOWAIT);
6922	if (error) {
6923		DPRINTF(1, "%s: can't map txstats ring DMA mem\n",
6924		    sc->sc_dev.dv_xname);
6925		return (error);
6926	}
6927
6928	error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
6929	    st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
6930	if (error) {
6931		DPRINTF(1, "%s: can't load txstats ring DMA mem\n",
6932		    sc->sc_dev.dv_xname);
6933		bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
6934		return (error);
6935	}
6936
6937	bzero(&st->stats_ring, dma_size);
6938	st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
6939
6940	/*
6941	 * Create TX stats DMA stuffs
6942	 */
6943	dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
6944	    BWI_ALIGN);
6945
6946	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
6947	    BUS_DMA_NOWAIT, &st->stats_dmap);
6948	if (error) {
6949		DPRINTF(1, "%s: can't create txstats ring DMA mem\n",
6950		    sc->sc_dev.dv_xname);
6951		return (error);
6952	}
6953	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
6954	    &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT);
6955	if (error) {
6956		DPRINTF(1, "%s: can't allocate txstats DMA mem\n",
6957		    sc->sc_dev.dv_xname);
6958		return (error);
6959	}
6960
6961	error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
6962	    dma_size, (caddr_t *)&st->stats, BUS_DMA_NOWAIT);
6963	if (error) {
6964		DPRINTF(1, "%s: can't map txstats DMA mem\n",
6965		    sc->sc_dev.dv_xname);
6966		return (error);
6967	}
6968
6969	error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
6970	    dma_size, NULL, BUS_DMA_WAITOK);
6971	if (error) {
6972		DPRINTF(1, "%s: can't load txstats DMA mem\n",
6973		    sc->sc_dev.dv_xname);
6974		bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
6975		return (error);
6976	}
6977
6978	bzero(&st->stats, dma_size);
6979	st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
6980	st->stats_ctrl_base = ctrl_base;
6981
6982	return (0);
6983}
6984
6985void
6986bwi_dma_txstats_free(struct bwi_softc *sc)
6987{
6988	struct bwi_txstats_data *st;
6989
6990	if (sc->sc_txstats == NULL)
6991		return;
6992	st = sc->sc_txstats;
6993
6994	bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
6995	bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
6996
6997	bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
6998	bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
6999
7000	free(st, M_DEVBUF);
7001}
7002
7003int
7004bwi_dma_mbuf_create(struct bwi_softc *sc)
7005{
7006	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7007	int i, j, k, ntx, error;
7008
7009	ntx = 0;
7010
7011	/*
7012	 * Create TX mbuf DMA map
7013	 */
7014	for (i = 0; i < BWI_TX_NRING; ++i) {
7015		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7016
7017		for (j = 0; j < BWI_TX_NDESC; ++j) {
7018			error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
7019			    0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
7020			if (error) {
7021				DPRINTF(1,
7022				    "%s: can't create %dth tbd, %dth DMA map\n",
7023				    sc->sc_dev.dv_xname, i, j);
7024				ntx = i;
7025				for (k = 0; k < j; ++k) {
7026					bus_dmamap_destroy(sc->sc_dmat,
7027					    tbd->tbd_buf[k].tb_dmap);
7028				}
7029				goto fail;
7030			}
7031		}
7032	}
7033	ntx = BWI_TX_NRING;
7034
7035	/*
7036	 * Create RX mbuf DMA map and a spare DMA map
7037	 */
7038	error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
7039	    BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
7040	if (error) {
7041		DPRINTF(1, "%s: can't create spare RX buf DMA map\n",
7042		    sc->sc_dev.dv_xname);
7043		goto fail;
7044	}
7045
7046	for (j = 0; j < BWI_RX_NDESC; ++j) {
7047		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
7048		    BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
7049		if (error) {
7050			DPRINTF(1, "%s: can't create %dth RX buf DMA map\n",
7051			    sc->sc_dev.dv_xname, j);
7052
7053			for (k = 0; k < j; ++k) {
7054				bus_dmamap_destroy(sc->sc_dmat,
7055				    rbd->rbd_buf[j].rb_dmap);
7056			}
7057			bus_dmamap_destroy(sc->sc_dmat,
7058			    rbd->rbd_tmp_dmap);
7059			goto fail;
7060		}
7061	}
7062
7063	return 0;
7064fail:
7065	bwi_dma_mbuf_destroy(sc, ntx, 0);
7066
7067	return (error);
7068}
7069
7070void
7071bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
7072{
7073	struct ieee80211com *ic = &sc->sc_ic;
7074	int i, j;
7075
7076	for (i = 0; i < ntx; ++i) {
7077		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7078
7079		for (j = 0; j < BWI_TX_NDESC; ++j) {
7080			struct bwi_txbuf *tb = &tbd->tbd_buf[j];
7081
7082			if (tb->tb_mbuf != NULL) {
7083				bus_dmamap_unload(sc->sc_dmat,
7084				    tb->tb_dmap);
7085				m_freem(tb->tb_mbuf);
7086			}
7087			if (tb->tb_ni != NULL)
7088				ieee80211_release_node(ic, tb->tb_ni);
7089			bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
7090		}
7091	}
7092
7093	if (nrx) {
7094		struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7095
7096		bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
7097		for (j = 0; j < BWI_RX_NDESC; ++j) {
7098			struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
7099
7100			if (rb->rb_mbuf != NULL) {
7101				bus_dmamap_unload(sc->sc_dmat,
7102						  rb->rb_dmap);
7103				m_freem(rb->rb_mbuf);
7104			}
7105			bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
7106		}
7107	}
7108}
7109
7110void
7111bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
7112{
7113	CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
7114}
7115
7116void
7117bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
7118{
7119	CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
7120}
7121
7122int
7123bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
7124{
7125	struct bwi_ring_data *rd;
7126	struct bwi_txbuf_data *tbd;
7127	uint32_t val, addr_hi, addr_lo;
7128
7129	KKASSERT(ring_idx < BWI_TX_NRING);
7130	rd = &sc->sc_tx_rdata[ring_idx];
7131	tbd = &sc->sc_tx_bdata[ring_idx];
7132
7133	tbd->tbd_idx = 0;
7134	tbd->tbd_used = 0;
7135
7136	bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
7137	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7138	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7139
7140	addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
7141	addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
7142
7143	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
7144	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
7145	    BWI_TXRX32_RINGINFO_FUNC_MASK);
7146	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
7147
7148	val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
7149	      BWI_TXRX32_CTRL_ENABLE;
7150	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
7151
7152	return (0);
7153}
7154
7155void
7156bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
7157    bus_addr_t paddr, int hdr_size, int ndesc)
7158{
7159	uint32_t val, addr_hi, addr_lo;
7160
7161	addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
7162	addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
7163
7164	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
7165	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
7166	      		BWI_TXRX32_RINGINFO_FUNC_MASK);
7167	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
7168
7169	val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
7170	    __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
7171	    BWI_TXRX32_CTRL_ENABLE;
7172	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
7173
7174	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
7175	    (ndesc - 1) * sizeof(struct bwi_desc32));
7176}
7177
7178int
7179bwi_init_rx_ring32(struct bwi_softc *sc)
7180{
7181	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7182	int i, error;
7183
7184	sc->sc_rx_bdata.rbd_idx = 0;
7185
7186	for (i = 0; i < BWI_RX_NDESC; ++i) {
7187		error = bwi_newbuf(sc, i, 1);
7188		if (error) {
7189			DPRINTF(1, "%s: can't allocate %dth RX buffer\n",
7190			    sc->sc_dev.dv_xname, i);
7191			return (error);
7192		}
7193	}
7194	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7195	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7196
7197	bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
7198	    sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
7199	return (0);
7200}
7201
7202int
7203bwi_init_txstats32(struct bwi_softc *sc)
7204{
7205	struct bwi_txstats_data *st = sc->sc_txstats;
7206	bus_addr_t stats_paddr;
7207	int i;
7208
7209	bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
7210	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
7211	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7212
7213	st->stats_idx = 0;
7214
7215	stats_paddr = st->stats_paddr;
7216	for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
7217		bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
7218				 stats_paddr, sizeof(struct bwi_txstats), 0);
7219		stats_paddr += sizeof(struct bwi_txstats);
7220	}
7221	bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
7222	    st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7223
7224	bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
7225	    st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
7226
7227	return (0);
7228}
7229
7230void
7231bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
7232    int buf_len)
7233{
7234	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7235
7236	KKASSERT(buf_idx < BWI_RX_NDESC);
7237	bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
7238	    paddr, buf_len, 0);
7239}
7240
7241void
7242bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
7243    int buf_idx, bus_addr_t paddr, int buf_len)
7244{
7245	KKASSERT(buf_idx < BWI_TX_NDESC);
7246	bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
7247	    paddr, buf_len, 1);
7248}
7249
7250int
7251bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
7252{
7253	/* TODO:64 */
7254	return (EOPNOTSUPP);
7255}
7256
7257int
7258bwi_init_rx_ring64(struct bwi_softc *sc)
7259{
7260	/* TODO:64 */
7261	return (EOPNOTSUPP);
7262}
7263
7264int
7265bwi_init_txstats64(struct bwi_softc *sc)
7266{
7267	/* TODO:64 */
7268	return (EOPNOTSUPP);
7269}
7270
7271void
7272bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
7273    int buf_len)
7274{
7275	/* TODO:64 */
7276}
7277
7278void
7279bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
7280    int buf_idx, bus_addr_t paddr, int buf_len)
7281{
7282	/* TODO:64 */
7283}
7284
7285int
7286bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
7287{
7288	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7289	struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
7290	struct bwi_rxbuf_hdr *hdr;
7291	bus_dmamap_t map;
7292	bus_addr_t paddr;
7293	struct mbuf *m;
7294	int error;
7295
7296	KKASSERT(buf_idx < BWI_RX_NDESC);
7297
7298	MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
7299	if (m == NULL)
7300		return (ENOBUFS);
7301	MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
7302	if (m == NULL) {
7303		error = ENOBUFS;
7304
7305		/*
7306		 * If the NIC is up and running, we need to:
7307		 * - Clear RX buffer's header.
7308		 * - Restore RX descriptor settings.
7309		 */
7310		if (init)
7311			return error;
7312		else
7313			goto back;
7314	}
7315	m->m_len = m->m_pkthdr.len = MCLBYTES;
7316
7317	/*
7318	 * Try to load RX buf into temporary DMA map
7319	 */
7320	error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
7321	    init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
7322	if (error) {
7323		m_freem(m);
7324
7325		/*
7326		 * See the comment above
7327		 */
7328		if (init)
7329			return error;
7330		else
7331			goto back;
7332	}
7333
7334	if (!init)
7335		bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
7336	rxbuf->rb_mbuf = m;
7337
7338	/*
7339	 * Swap RX buf's DMA map with the loaded temporary one
7340	 */
7341	map = rxbuf->rb_dmap;
7342	rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
7343	rbd->rbd_tmp_dmap = map;
7344	paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
7345	rxbuf->rb_paddr = paddr;
7346
7347back:
7348	/*
7349	 * Clear RX buf header
7350	 */
7351	hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
7352	bzero(hdr, sizeof(*hdr));
7353	bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
7354	    rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7355
7356	/*
7357	 * Setup RX buf descriptor
7358	 */
7359	sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr,
7360	    rxbuf->rb_mbuf->m_len - sizeof(*hdr));
7361	return error;
7362}
7363
7364void
7365bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
7366    const uint8_t *addr)
7367{
7368	int i;
7369
7370	CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
7371	    BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
7372
7373	for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
7374		uint16_t addr_val;
7375
7376		addr_val = (uint16_t)addr[i * 2] |
7377		    (((uint16_t)addr[(i * 2) + 1]) << 8);
7378		CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
7379	}
7380}
7381
7382int
7383bwi_set_chan(struct bwi_softc *sc, u_int8_t chan)
7384{
7385	struct bwi_mac *mac;
7386
7387	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7388	mac = (struct bwi_mac *)sc->sc_cur_regwin;
7389
7390	bwi_rf_set_chan(mac, chan, 0);
7391
7392	return (0);
7393}
7394
7395void
7396bwi_next_scan(void *xsc)
7397{
7398	struct bwi_softc *sc = xsc;
7399	struct ieee80211com *ic = &sc->sc_ic;
7400	struct ifnet *ifp = &ic->ic_if;
7401	int s;
7402
7403	s = splnet();
7404
7405	if (ic->ic_state == IEEE80211_S_SCAN)
7406		ieee80211_next_scan(ifp);
7407
7408	splx(s);
7409}
7410
7411void
7412bwi_rxeof(struct bwi_softc *sc, int end_idx)
7413{
7414	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7415	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7416	struct ieee80211com *ic = &sc->sc_ic;
7417	struct ifnet *ifp = &ic->ic_if;
7418	int idx;
7419
7420	idx = rbd->rbd_idx;
7421	while (idx != end_idx) {
7422		struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
7423		struct bwi_rxbuf_hdr *hdr;
7424		struct ieee80211_frame *wh;
7425		struct ieee80211_node *ni;
7426		struct mbuf *m;
7427		uint8_t plcp_signal;
7428		uint16_t flags2;
7429		int buflen, wh_ofs, hdr_extra;
7430
7431		m = rb->rb_mbuf;
7432		bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
7433		    rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
7434
7435		if (bwi_newbuf(sc, idx, 0)) {
7436			ifp->if_ierrors++;
7437			goto next;
7438		}
7439
7440		hdr = mtod(m, struct bwi_rxbuf_hdr *);
7441		flags2 = letoh16(hdr->rxh_flags2);
7442
7443		hdr_extra = 0;
7444		if (flags2 & BWI_RXH_F2_TYPE2FRAME)
7445			hdr_extra = 2;
7446		wh_ofs = hdr_extra + 6;
7447
7448		buflen = letoh16(hdr->rxh_buflen);
7449		if (buflen <= wh_ofs) {
7450			DPRINTF(1, "%s: zero length data, hdr_extra %d\n",
7451			    sc->sc_dev.dv_xname, hdr_extra);
7452			ifp->if_ierrors++;
7453			m_freem(m);
7454			goto next;
7455		}
7456
7457		plcp_signal = *((uint8_t *)(hdr + 1) + hdr_extra);
7458
7459		m->m_pkthdr.rcvif = ifp;
7460		m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
7461		m_adj(m, sizeof(*hdr) + wh_ofs);
7462
7463#if NBPFILTER > 0
7464		/* RX radio tap */
7465		if (sc->sc_drvbpf != NULL) {
7466			struct mbuf mb;
7467			struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
7468
7469			/* TODO: calculate rate and signal */
7470			tap->wr_tsf = hdr->rxh_tsf;
7471			tap->wr_flags = 0;
7472			tap->wr_rate = 0;
7473			tap->wr_chan_freq =
7474			    htole16(ic->ic_bss->ni_chan->ic_freq);
7475			tap->wr_chan_flags =
7476			    htole16(ic->ic_bss->ni_chan->ic_flags);
7477			tap->wr_antsignal = 0;
7478			tap->wr_antnoise = 0;
7479
7480			mb.m_data = (caddr_t)tap;
7481			mb.m_len = sc->sc_rxtap_len;
7482			mb.m_next = m;
7483			mb.m_nextpkt = NULL;
7484			mb.m_type = 0;
7485			mb.m_flags = 0;
7486			bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
7487		}
7488#endif
7489
7490		m_adj(m, -IEEE80211_CRC_LEN);
7491
7492		wh = mtod(m, struct ieee80211_frame *);
7493		ni = ieee80211_find_rxnode(ic, wh);
7494
7495		ieee80211_input(ifp, m, ni, hdr->rxh_rssi,
7496		    letoh16(hdr->rxh_tsf));
7497
7498		ieee80211_release_node(ic, ni);
7499next:
7500		idx = (idx + 1) % BWI_RX_NDESC;
7501	}
7502
7503	rbd->rbd_idx = idx;
7504	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7505	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7506}
7507
7508void
7509bwi_rxeof32(struct bwi_softc *sc)
7510{
7511	uint32_t val, rx_ctrl;
7512	int end_idx;
7513
7514	rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
7515
7516	val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
7517	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
7518	    sizeof(struct bwi_desc32);
7519
7520	bwi_rxeof(sc, end_idx);
7521
7522	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
7523	    end_idx * sizeof(struct bwi_desc32));
7524}
7525
7526void
7527bwi_rxeof64(struct bwi_softc *sc)
7528{
7529	/* TODO:64 */
7530}
7531
7532void
7533bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
7534{
7535	int i;
7536
7537	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
7538
7539#define NRETRY 10
7540	for (i = 0; i < NRETRY; ++i) {
7541		uint32_t status;
7542
7543		status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
7544		if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
7545		    BWI_RX32_STATUS_STATE_DISABLED)
7546			break;
7547
7548		DELAY(1000);
7549	}
7550	if (i == NRETRY)
7551		DPRINTF(1, "%s: reset rx ring timedout\n", sc->sc_dev.dv_xname);
7552#undef NRETRY
7553
7554	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
7555}
7556
7557void
7558bwi_free_txstats32(struct bwi_softc *sc)
7559{
7560	bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
7561}
7562
7563void
7564bwi_free_rx_ring32(struct bwi_softc *sc)
7565{
7566	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7567	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7568	int i;
7569
7570	bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
7571
7572	for (i = 0; i < BWI_RX_NDESC; ++i) {
7573		struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
7574
7575		if (rb->rb_mbuf != NULL) {
7576			bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
7577			m_freem(rb->rb_mbuf);
7578			rb->rb_mbuf = NULL;
7579		}
7580	}
7581}
7582
7583void
7584bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
7585{
7586	struct ieee80211com *ic = &sc->sc_ic;
7587	struct bwi_ring_data *rd;
7588	struct bwi_txbuf_data *tbd;
7589	uint32_t state, val;
7590	int i;
7591
7592	KKASSERT(ring_idx < BWI_TX_NRING);
7593	rd = &sc->sc_tx_rdata[ring_idx];
7594	tbd = &sc->sc_tx_bdata[ring_idx];
7595
7596#define NRETRY 10
7597	for (i = 0; i < NRETRY; ++i) {
7598		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
7599		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
7600		if (state == BWI_TX32_STATUS_STATE_DISABLED ||
7601		    state == BWI_TX32_STATUS_STATE_IDLE ||
7602		    state == BWI_TX32_STATUS_STATE_STOPPED)
7603			break;
7604
7605		DELAY(1000);
7606	}
7607	if (i == NRETRY) {
7608		DPRINTF(1, "%s: wait for TX ring(%d) stable timed out\n",
7609		    sc->sc_dev.dv_xname, ring_idx);
7610	}
7611
7612	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
7613	for (i = 0; i < NRETRY; ++i) {
7614		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
7615		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
7616		if (state == BWI_TX32_STATUS_STATE_DISABLED)
7617			break;
7618
7619		DELAY(1000);
7620	}
7621	if (i == NRETRY)
7622		DPRINTF(1, "%s: reset TX ring (%d) timed out\n",
7623		    sc->sc_dev.dv_xname, ring_idx);
7624#undef NRETRY
7625
7626	DELAY(1000);
7627
7628	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
7629
7630	for (i = 0; i < BWI_TX_NDESC; ++i) {
7631		struct bwi_txbuf *tb = &tbd->tbd_buf[i];
7632
7633		if (tb->tb_mbuf != NULL) {
7634			bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
7635			m_freem(tb->tb_mbuf);
7636			tb->tb_mbuf = NULL;
7637		}
7638		if (tb->tb_ni != NULL) {
7639			ieee80211_release_node(ic, tb->tb_ni);
7640			tb->tb_ni = NULL;
7641		}
7642	}
7643}
7644
7645void
7646bwi_free_txstats64(struct bwi_softc *sc)
7647{
7648	/* TODO:64 */
7649}
7650
7651void
7652bwi_free_rx_ring64(struct bwi_softc *sc)
7653{
7654	/* TODO:64 */
7655}
7656
7657void
7658bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
7659{
7660	/* TODO:64 */
7661}
7662
7663/* XXX does not belong here */
7664uint8_t
7665bwi_rate2plcp(uint8_t rate)
7666{
7667	rate &= IEEE80211_RATE_VAL;
7668
7669	switch (rate) {
7670	case 2:		return (0xa);
7671	case 4:		return (0x14);
7672	case 11:	return (0x37);
7673	case 22:	return (0x6e);
7674	case 44:	return (0xdc);
7675
7676	case 12:	return (0xb);
7677	case 18:	return (0xf);
7678	case 24:	return (0xa);
7679	case 36:	return (0xe);
7680	case 48:	return (0x9);
7681	case 72:	return (0xd);
7682	case 96:	return (0x8);
7683	case 108:	return (0xc);
7684
7685	default:
7686		panic("unsupported rate %u\n", rate);
7687	}
7688}
7689
7690void
7691bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
7692{
7693/* XXX does not belong here */
7694#define IEEE80211_OFDM_PLCP_SIG_MASK	0x0000000f
7695#define IEEE80211_OFDM_PLCP_LEN_MASK	0x0001ffe0
7696
7697	uint32_t plcp;
7698
7699	plcp = __SHIFTIN(bwi_rate2plcp(rate), IEEE80211_OFDM_PLCP_SIG_MASK) |
7700	    __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
7701	*plcp0 = htole32(plcp);
7702}
7703
7704void
7705bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
7706		   uint8_t rate)
7707{
7708	int len, service, pkt_bitlen;
7709
7710	pkt_bitlen = pkt_len * NBBY;
7711	len = howmany(pkt_bitlen * 2, rate);
7712
7713	service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
7714	if (rate == (11 * 2)) {
7715		int pkt_bitlen1;
7716
7717		/*
7718		 * PLCP service field needs to be adjusted,
7719		 * if TX rate is 11Mbytes/s
7720		 */
7721		pkt_bitlen1 = len * 11;
7722		if (pkt_bitlen1 - pkt_bitlen >= NBBY)
7723			service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
7724	}
7725
7726	plcp->i_signal = bwi_rate2plcp(rate);
7727	plcp->i_service = service;
7728	plcp->i_length = htole16(len);
7729	/* NOTE: do NOT touch i_crc */
7730}
7731
7732void
7733bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
7734{
7735	enum bwi_modtype modtype;
7736
7737	/*
7738	 * Assume caller has zeroed 'plcp'
7739	 */
7740
7741	modtype = bwi_rate2modtype(rate);
7742	if (modtype == IEEE80211_MODTYPE_OFDM)
7743		bwi_ofdm_plcp_header(plcp, pkt_len, rate);
7744	else if (modtype == IEEE80211_MODTYPE_DS)
7745		bwi_ds_plcp_header(plcp, pkt_len, rate);
7746	else
7747		panic("unsupport modulation type %u\n", modtype);
7748}
7749
7750enum bwi_modtype
7751bwi_rate2modtype(u_int8_t rate)
7752{
7753	rate &= IEEE80211_RATE_VAL;
7754
7755	if (rate == 44)
7756		return IEEE80211_MODTYPE_PBCC;
7757	else if (rate == 22 || rate < 12)
7758		return IEEE80211_MODTYPE_DS;
7759	else
7760		return IEEE80211_MODTYPE_OFDM;
7761}
7762
7763u_int8_t
7764bwi_ack_rate(struct ieee80211_node *ni, u_int8_t rate)
7765{
7766	const struct ieee80211_rateset *rs = &ni->ni_rates;
7767	u_int8_t ack_rate = 0;
7768	enum bwi_modtype modtype;
7769	int i;
7770
7771	rate &= IEEE80211_RATE_VAL;
7772
7773	modtype = bwi_rate2modtype(rate);
7774
7775	for (i = 0; i < rs->rs_nrates; ++i) {
7776		u_int8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7777
7778		if (rate1 > rate) {
7779			if (ack_rate != 0)
7780				return ack_rate;
7781			else
7782				break;
7783		}
7784
7785		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
7786		    bwi_rate2modtype(rate1) == modtype)
7787			ack_rate = rate1;
7788	}
7789
7790	switch (rate) {
7791	/* CCK */
7792	case 2:
7793	case 4:
7794	case 11:
7795	case 22:
7796		ack_rate = rate;
7797		break;
7798	/* PBCC */
7799	case 44:
7800		ack_rate = 22;
7801		break;
7802
7803	/* OFDM */
7804	case 12:
7805	case 18:
7806		ack_rate = 12;
7807		break;
7808	case 24:
7809	case 36:
7810		ack_rate = 24;
7811		break;
7812	case 48:
7813	case 72:
7814	case 96:
7815	case 108:
7816		ack_rate = 48;
7817		break;
7818	default:
7819		panic("unsupported rate %d\n", rate);
7820	}
7821	return ack_rate;
7822}
7823
7824#define IEEE80211_OFDM_TXTIME(kbps, frmlen) \
7825	(IEEE80211_OFDM_PREAMBLE_TIME + \
7826	 IEEE80211_OFDM_SIGNAL_TIME + \
7827	(IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
7828
7829#define IEEE80211_OFDM_SYM_TIME			4
7830#define IEEE80211_OFDM_PREAMBLE_TIME		16
7831#define IEEE80211_OFDM_SIGNAL_EXT_TIME		6
7832#define IEEE80211_OFDM_SIGNAL_TIME		4
7833
7834#define IEEE80211_OFDM_PLCP_SERVICE_NBITS	16
7835#define IEEE80211_OFDM_TAIL_NBITS		6
7836
7837#define IEEE80211_OFDM_NBITS(frmlen) \
7838	(IEEE80211_OFDM_PLCP_SERVICE_NBITS + \
7839	 ((frmlen) * NBBY) + \
7840	 IEEE80211_OFDM_TAIL_NBITS)
7841
7842#define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \
7843	(((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
7844
7845#define IEEE80211_OFDM_NSYMS(kbps, frmlen) \
7846	howmany(IEEE80211_OFDM_NBITS((frmlen)), \
7847		IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
7848
7849#define IEEE80211_CCK_TXTIME(kbps, frmlen) \
7850	(((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
7851
7852#define IEEE80211_CCK_PREAMBLE_LEN		144
7853#define IEEE80211_CCK_PLCP_HDR_TIME		48
7854#define IEEE80211_CCK_SHPREAMBLE_LEN		72
7855#define IEEE80211_CCK_SHPLCP_HDR_TIME		24
7856
7857#define IEEE80211_CCK_NBITS(frmlen)		((frmlen) * NBBY)
7858
7859u_int16_t
7860bwi_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, u_int len,
7861    u_int8_t rs_rate, uint32_t flags)
7862{
7863	enum bwi_modtype modtype;
7864	u_int16_t txtime;
7865	int rate;
7866
7867	rs_rate &= IEEE80211_RATE_VAL;
7868
7869	rate = rs_rate * 500;	/* ieee80211 rate -> kbps */
7870
7871	modtype = bwi_rate2modtype(rs_rate);
7872	if (modtype == IEEE80211_MODTYPE_OFDM) {
7873		/*
7874		 * IEEE Std 802.11a-1999, page 37, equation (29)
7875		 * IEEE Std 802.11g-2003, page 44, equation (42)
7876		 */
7877		txtime = IEEE80211_OFDM_TXTIME(rate, len);
7878		if (ic->ic_curmode == IEEE80211_MODE_11G)
7879			txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
7880	} else {
7881		/*
7882		 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
7883		 * IEEE Std 802.11g-2003, page 45, equation (43)
7884		 */
7885		if (modtype == IEEE80211_MODTYPE_PBCC)
7886			++len;
7887		txtime = IEEE80211_CCK_TXTIME(rate, len);
7888
7889		/*
7890		 * Short preamble is not applicable for DS 1Mbits/s
7891		 */
7892		if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
7893			txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
7894				  IEEE80211_CCK_SHPLCP_HDR_TIME;
7895		} else {
7896			txtime += IEEE80211_CCK_PREAMBLE_LEN +
7897				  IEEE80211_CCK_PLCP_HDR_TIME;
7898		}
7899	}
7900	return txtime;
7901}
7902
7903int
7904bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
7905    struct ieee80211_node *ni)
7906{
7907	DPRINTF(2, "%s\n", __func__);
7908
7909	struct ieee80211com *ic = &sc->sc_ic;
7910	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
7911	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
7912	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
7913	struct bwi_mac *mac;
7914	struct bwi_txbuf_hdr *hdr;
7915	struct ieee80211_frame *wh;
7916	uint8_t rate, rate_fb;
7917	uint32_t mac_ctrl;
7918	uint16_t phy_ctrl;
7919	bus_addr_t paddr;
7920	int pkt_len, error;
7921#if 0
7922	const uint8_t *p;
7923	int i;
7924#endif
7925
7926	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7927	mac = (struct bwi_mac *)sc->sc_cur_regwin;
7928
7929	wh = mtod(m, struct ieee80211_frame *);
7930
7931	/* Get 802.11 frame len before prepending TX header */
7932	pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
7933
7934	/*
7935	 * Find TX rate
7936	 */
7937	bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx));
7938	if (ni != NULL) {
7939		if (ic->ic_fixed_rate != -1) {
7940			rate = ic->ic_sup_rates[ic->ic_curmode].
7941			    rs_rates[ic->ic_fixed_rate];
7942		} else {
7943			/* TODO: TX rate control */
7944			rate = rate_fb = (1 * 2);
7945		}
7946	} else {
7947		/* Fixed at 1Mbytes/s for mgt frames */
7948		rate = rate_fb = (1 * 2);
7949	}
7950
7951	rate &= IEEE80211_RATE_VAL;
7952
7953	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
7954		rate = rate_fb = (1 * 2);
7955
7956	if (rate == 0 || rate_fb == 0) {
7957		DPRINTF(1, "%s: invalid rate %u or fallback rate %u",
7958		    sc->sc_dev.dv_xname, rate, rate_fb);
7959		rate = rate_fb = (1 * 2); /* Force 1Mbytes/s */
7960	}
7961
7962#if NBPFILTER > 0
7963	/* TX radio tap */
7964	if (sc->sc_drvbpf != NULL) {
7965		struct mbuf mb;
7966		struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
7967
7968		tap->wt_flags = 0;
7969		tap->wt_rate = rate;
7970		tap->wt_chan_freq =
7971		    htole16(ic->ic_bss->ni_chan->ic_freq);
7972		tap->wt_chan_flags =
7973		    htole16(ic->ic_bss->ni_chan->ic_flags);
7974
7975		mb.m_data = (caddr_t)tap;
7976		mb.m_len = sc->sc_txtap_len;
7977		mb.m_next = m;
7978		mb.m_nextpkt = NULL;
7979		mb.m_type = 0;
7980		mb.m_flags = 0;
7981		bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
7982	}
7983#endif
7984
7985	/*
7986	 * Setup the embedded TX header
7987	 */
7988	M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
7989	if (m == NULL) {
7990		DPRINTF(1, "%s: prepend TX header failed\n",
7991		    sc->sc_dev.dv_xname);
7992		return (ENOBUFS);
7993	}
7994	hdr = mtod(m, struct bwi_txbuf_hdr *);
7995
7996	bzero(hdr, sizeof(*hdr));
7997
7998	bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
7999	bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
8000
8001	if (ni != NULL && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
8002		uint16_t dur;
8003		uint8_t ack_rate;
8004
8005		ack_rate = bwi_ack_rate(ni, rate_fb);
8006		dur = bwi_txtime(ic, ni,
8007		    sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
8008		    ack_rate, ic->ic_flags & ~IEEE80211_F_SHPREAMBLE);
8009
8010		hdr->txh_fb_duration = htole16(dur);
8011	}
8012
8013	hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
8014	    __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
8015
8016	bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
8017	bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate_fb);
8018
8019	phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
8020	    BWI_TXH_PHY_C_ANTMODE_MASK);
8021	if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
8022		phy_ctrl |= BWI_TXH_PHY_C_OFDM;
8023	else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
8024		phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
8025
8026	mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
8027	if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
8028		mac_ctrl |= BWI_TXH_MAC_C_ACK;
8029	if (bwi_rate2modtype(rate_fb) == IEEE80211_MODTYPE_OFDM)
8030		mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
8031
8032	hdr->txh_mac_ctrl = htole32(mac_ctrl);
8033	hdr->txh_phy_ctrl = htole16(phy_ctrl);
8034
8035	/* Catch any further usage */
8036	hdr = NULL;
8037	wh = NULL;
8038
8039	/* DMA load */
8040	error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
8041	    BUS_DMA_NOWAIT);
8042	if (error && error != EFBIG) {
8043		DPRINTF(1, "%s: can't load TX buffer (1) %d\n",
8044		    sc->sc_dev.dv_xname, error);
8045		goto back;
8046	}
8047
8048	if (error) {	/* error == EFBIG */
8049		struct mbuf *m_new;
8050
8051		error = 0;
8052
8053		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
8054		if (m_new == NULL) {
8055			m_freem(m);
8056			error = ENOBUFS;
8057			printf("%s: can't defrag TX buffer\n",
8058			    sc->sc_dev.dv_xname);
8059			goto back;
8060		}
8061
8062		M_DUP_PKTHDR(m_new, m);
8063		if (m->m_pkthdr.len > MHLEN) {
8064			MCLGET(m_new, M_DONTWAIT);
8065			if (!(m_new->m_flags & M_EXT)) {
8066				m_freem(m);
8067				m_freem(m_new);
8068				error = ENOBUFS;
8069			}
8070		}
8071
8072		if (error) {
8073			printf("%s: can't defrag TX buffer\n",
8074			    sc->sc_dev.dv_xname);
8075			goto back;
8076		}
8077
8078		m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
8079		m_freem(m);
8080		m_new->m_len = m_new->m_pkthdr.len;
8081		m = m_new;
8082
8083		error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
8084		    BUS_DMA_NOWAIT);
8085		if (error) {
8086			DPRINTF(1, "%s: can't load TX buffer (2) %d\n",
8087			    sc->sc_dev.dv_xname, error);
8088			goto back;
8089		}
8090	}
8091	error = 0;
8092
8093	bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
8094	    tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8095
8096	tb->tb_mbuf = m;
8097	tb->tb_ni = ni;
8098
8099#if 0
8100	p = mtod(m, const uint8_t *);
8101	for (i = 0; i < m->m_pkthdr.len; ++i) {
8102		if (i != 0 && i % 8 == 0)
8103			printf("\n");
8104		printf("%02x ", p[i]);
8105	}
8106	printf("\n");
8107
8108	DPRINTF(1, "%s: idx %d, pkt_len %d, buflen %d\n",
8109	    sc->sc_dev.dv_xname, idx, pkt_len, m->m_pkthdr.len);
8110#endif
8111
8112	/* Setup TX descriptor */
8113	paddr = tb->tb_dmap->dm_segs[0].ds_addr;
8114	sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len);
8115	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8116	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8117
8118	/* Kick start */
8119	sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
8120
8121back:
8122	if (error)
8123		m_freem(m);
8124	return (error);
8125}
8126
8127void
8128bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
8129{
8130	idx = (idx + 1) % BWI_TX_NDESC;
8131	CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
8132	    idx * sizeof(struct bwi_desc32));
8133}
8134
8135void
8136bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
8137{
8138	/* TODO:64 */
8139}
8140
8141void
8142bwi_txeof_status32(struct bwi_softc *sc)
8143{
8144	struct ifnet *ifp = &sc->sc_ic.ic_if;
8145	uint32_t val, ctrl_base;
8146	int end_idx;
8147
8148	ctrl_base = sc->sc_txstats->stats_ctrl_base;
8149
8150	val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
8151	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
8152	    sizeof(struct bwi_desc32);
8153
8154	bwi_txeof_status(sc, end_idx);
8155
8156	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8157	    end_idx * sizeof(struct bwi_desc32));
8158
8159	if ((ifp->if_flags & IFF_OACTIVE) == 0)
8160		ifp->if_start(ifp);
8161}
8162
8163void
8164bwi_txeof_status64(struct bwi_softc *sc)
8165{
8166	/* TODO:64 */
8167}
8168
8169void
8170_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
8171{
8172	struct ieee80211com *ic = &sc->sc_ic;
8173	struct ifnet *ifp = &sc->sc_ic.ic_if;
8174	struct bwi_txbuf_data *tbd;
8175	struct bwi_txbuf *tb;
8176	int ring_idx, buf_idx;
8177
8178	if (tx_id == 0) {
8179		DPRINTF(1, "%s: zero tx id\n", sc->sc_dev.dv_xname);
8180		return;
8181	}
8182
8183	ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
8184	buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
8185
8186	KKASSERT(ring_idx == BWI_TX_DATA_RING);
8187	KKASSERT(buf_idx < BWI_TX_NDESC);
8188#if 0
8189	DPRINTF(1, "%s: txeof idx %d\n", sc->sc_dev.dv_xname, buf_idx);
8190#endif
8191	tbd = &sc->sc_tx_bdata[ring_idx];
8192	KKASSERT(tbd->tbd_used > 0);
8193	tbd->tbd_used--;
8194
8195	tb = &tbd->tbd_buf[buf_idx];
8196
8197	bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
8198	m_freem(tb->tb_mbuf);
8199	tb->tb_mbuf = NULL;
8200
8201	if (tb->tb_ni != NULL) {
8202		ieee80211_release_node(ic, tb->tb_ni);
8203		tb->tb_ni = NULL;
8204	}
8205
8206	if (tbd->tbd_used == 0)
8207		sc->sc_tx_timer = 0;
8208
8209	ifp->if_flags &= ~IFF_OACTIVE;
8210}
8211
8212void
8213bwi_txeof_status(struct bwi_softc *sc, int end_idx)
8214{
8215	struct bwi_txstats_data *st = sc->sc_txstats;
8216	int idx;
8217
8218	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8219	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8220
8221	idx = st->stats_idx;
8222	while (idx != end_idx) {
8223		_bwi_txeof(sc, letoh16(st->stats[idx].txs_id));
8224		idx = (idx + 1) % BWI_TXSTATS_NDESC;
8225	}
8226	st->stats_idx = idx;
8227}
8228
8229void
8230bwi_txeof(struct bwi_softc *sc)
8231{
8232	struct ifnet *ifp = &sc->sc_ic.ic_if;
8233
8234	for (;;) {
8235		uint32_t tx_status0, tx_status1;
8236		uint16_t tx_id, tx_info;
8237
8238		tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
8239		if (tx_status0 == 0)
8240			break;
8241		tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1);
8242
8243		tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
8244		tx_info = BWI_TXSTATUS_0_INFO(tx_status0);
8245
8246		if (tx_info & 0x30) /* XXX */
8247			continue;
8248
8249		_bwi_txeof(sc, tx_id);
8250	}
8251
8252	if ((ifp->if_flags & IFF_OACTIVE) == 0)
8253		ifp->if_start(ifp);
8254}
8255
8256int
8257bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
8258{
8259	bwi_power_on(sc, 1);
8260
8261	return (bwi_set_clock_mode(sc, clk_mode));
8262}
8263
8264void
8265bwi_bbp_power_off(struct bwi_softc *sc)
8266{
8267	bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
8268	bwi_power_off(sc, 1);
8269}
8270
8271int
8272bwi_get_pwron_delay(struct bwi_softc *sc)
8273{
8274	struct bwi_regwin *com, *old;
8275	struct bwi_clock_freq freq;
8276	uint32_t val;
8277	int error;
8278
8279	com = &sc->sc_com_regwin;
8280	KKASSERT(BWI_REGWIN_EXIST(com));
8281
8282	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
8283		return (0);
8284
8285	error = bwi_regwin_switch(sc, com, &old);
8286	if (error)
8287		return (error);
8288
8289	bwi_get_clock_freq(sc, &freq);
8290
8291	val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
8292	sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
8293	DPRINTF(1, "%s: power on delay %u\n",
8294	    sc->sc_dev.dv_xname, sc->sc_pwron_delay);
8295
8296	return (bwi_regwin_switch(sc, old, NULL));
8297}
8298
8299int
8300bwi_bus_attach(struct bwi_softc *sc)
8301{
8302	struct bwi_regwin *bus, *old;
8303	int error;
8304
8305	bus = &sc->sc_bus_regwin;
8306
8307	error = bwi_regwin_switch(sc, bus, &old);
8308	if (error)
8309		return (error);
8310
8311	if (!bwi_regwin_is_enabled(sc, bus))
8312		bwi_regwin_enable(sc, bus, 0);
8313
8314	/* Disable interripts */
8315	CSR_WRITE_4(sc, BWI_INTRVEC, 0);
8316
8317	return (bwi_regwin_switch(sc, old, NULL));
8318}
8319
8320const char *
8321bwi_regwin_name(const struct bwi_regwin *rw)
8322{
8323	switch (rw->rw_type) {
8324	case BWI_REGWIN_T_COM:
8325		return ("COM");
8326	case BWI_REGWIN_T_BUSPCI:
8327		return ("PCI");
8328	case BWI_REGWIN_T_MAC:
8329		return ("MAC");
8330	case BWI_REGWIN_T_BUSPCIE:
8331		return ("PCIE");
8332	}
8333	panic("unknown regwin type 0x%04x\n", rw->rw_type);
8334
8335	return (NULL);
8336}
8337
8338uint32_t
8339bwi_regwin_disable_bits(struct bwi_softc *sc)
8340{
8341	uint32_t busrev;
8342
8343	/* XXX cache this */
8344	busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
8345	DPRINTF(1, "%s: bus rev %u\n", sc->sc_dev.dv_xname, busrev);
8346
8347	if (busrev == BWI_BUSREV_0)
8348		return (BWI_STATE_LO_DISABLE1);
8349	else if (busrev == BWI_BUSREV_1)
8350		return (BWI_STATE_LO_DISABLE2);
8351	else
8352		return ((BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2));
8353}
8354
8355int
8356bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
8357{
8358	uint32_t val, disable_bits;
8359
8360	disable_bits = bwi_regwin_disable_bits(sc);
8361	val = CSR_READ_4(sc, BWI_STATE_LO);
8362
8363	if ((val & (BWI_STATE_LO_CLOCK |
8364	    BWI_STATE_LO_RESET |
8365	    disable_bits)) == BWI_STATE_LO_CLOCK) {
8366		DPRINTF(1, "%s: %s is enabled\n",
8367		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8368		return (1);
8369	} else {
8370		DPRINTF(1, "%s: %s is disabled\n",
8371		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8372		return (0);
8373	}
8374}
8375
8376void
8377bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
8378{
8379	uint32_t state_lo, disable_bits;
8380	int i;
8381
8382	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
8383
8384	/*
8385	 * If current regwin is in 'reset' state, it was already disabled.
8386	 */
8387	if (state_lo & BWI_STATE_LO_RESET) {
8388		DPRINTF(1, "%s: %s was already disabled\n",
8389		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8390		return;
8391	}
8392
8393	disable_bits = bwi_regwin_disable_bits(sc);
8394
8395	/*
8396	 * Disable normal clock
8397	 */
8398	state_lo = BWI_STATE_LO_CLOCK | disable_bits;
8399	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8400
8401	/*
8402	 * Wait until normal clock is disabled
8403	 */
8404#define NRETRY	1000
8405	for (i = 0; i < NRETRY; ++i) {
8406		state_lo = CSR_READ_4(sc, BWI_STATE_LO);
8407		if (state_lo & disable_bits)
8408			break;
8409		DELAY(10);
8410	}
8411	if (i == NRETRY) {
8412		DPRINTF(1, "%s: %s disable clock timeout\n",
8413		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8414	}
8415
8416	for (i = 0; i < NRETRY; ++i) {
8417		uint32_t state_hi;
8418
8419		state_hi = CSR_READ_4(sc, BWI_STATE_HI);
8420		if ((state_hi & BWI_STATE_HI_BUSY) == 0)
8421			break;
8422		DELAY(10);
8423	}
8424	if (i == NRETRY) {
8425		DPRINTF(1, "%s: %s wait BUSY unset timeout\n",
8426		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8427	}
8428#undef NRETRY
8429
8430	/*
8431	 * Reset and disable regwin with gated clock
8432	 */
8433	state_lo = BWI_STATE_LO_RESET | disable_bits |
8434	    BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
8435	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8436	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8437
8438	/* Flush pending bus write */
8439	CSR_READ_4(sc, BWI_STATE_LO);
8440	DELAY(1);
8441
8442	/* Reset and disable regwin */
8443	state_lo = BWI_STATE_LO_RESET | disable_bits |
8444		   __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8445	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8446
8447	/* Flush pending bus write */
8448	CSR_READ_4(sc, BWI_STATE_LO);
8449	DELAY(1);
8450}
8451
8452void
8453bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
8454{
8455	uint32_t state_lo, state_hi, imstate;
8456
8457	bwi_regwin_disable(sc, rw, flags);
8458
8459	/* Reset regwin with gated clock */
8460	state_lo = BWI_STATE_LO_RESET |
8461	    BWI_STATE_LO_CLOCK |
8462	    BWI_STATE_LO_GATED_CLOCK |
8463	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8464	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8465
8466	/* Flush pending bus write */
8467	CSR_READ_4(sc, BWI_STATE_LO);
8468	DELAY(1);
8469
8470	state_hi = CSR_READ_4(sc, BWI_STATE_HI);
8471	if (state_hi & BWI_STATE_HI_SERROR)
8472		CSR_WRITE_4(sc, BWI_STATE_HI, 0);
8473
8474	imstate = CSR_READ_4(sc, BWI_IMSTATE);
8475	if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
8476		imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
8477		CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
8478	}
8479
8480	/* Enable regwin with gated clock */
8481	state_lo = BWI_STATE_LO_CLOCK |
8482	    BWI_STATE_LO_GATED_CLOCK |
8483	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8484	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8485
8486	/* Flush pending bus write */
8487	CSR_READ_4(sc, BWI_STATE_LO);
8488	DELAY(1);
8489
8490	/* Enable regwin with normal clock */
8491	state_lo = BWI_STATE_LO_CLOCK |
8492	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8493	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8494
8495	/* Flush pending bus write */
8496	CSR_READ_4(sc, BWI_STATE_LO);
8497	DELAY(1);
8498}
8499
8500void
8501bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
8502{
8503	struct ieee80211com *ic = &sc->sc_ic;
8504	struct bwi_mac *mac;
8505	struct bwi_myaddr_bssid buf;
8506	const uint8_t *p;
8507	uint32_t val;
8508	int n, i;
8509
8510	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8511	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8512
8513	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
8514
8515	bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr));
8516	bcopy(bssid, buf.bssid, sizeof(buf.bssid));
8517
8518	n = sizeof(buf) / sizeof(val);
8519	p = (const uint8_t *)&buf;
8520	for (i = 0; i < n; ++i) {
8521		int j;
8522
8523		val = 0;
8524		for (j = 0; j < sizeof(val); ++j)
8525			val |= ((uint32_t)(*p++)) << (j * 8);
8526
8527		TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
8528	}
8529}
8530
8531void
8532bwi_updateslot(struct ieee80211com *ic)
8533{
8534	struct bwi_softc *sc = ic->ic_if.if_softc;
8535	struct bwi_mac *mac;
8536	struct ifnet *ifp = &ic->ic_if;
8537
8538	if ((ifp->if_flags & IFF_RUNNING) == 0)
8539		return;
8540
8541	DPRINTF(2, "%s\n", __func__);
8542
8543	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8544	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8545
8546	bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
8547}
8548
8549void
8550bwi_calibrate(void *xsc)
8551{
8552	struct bwi_softc *sc = xsc;
8553	struct ieee80211com *ic = &sc->sc_ic;
8554	int s;
8555
8556	s = splnet();
8557
8558	if (ic->ic_state == IEEE80211_S_RUN) {
8559		struct bwi_mac *mac;
8560
8561		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8562		mac = (struct bwi_mac *)sc->sc_cur_regwin;
8563
8564		if (ic->ic_opmode != IEEE80211_M_MONITOR)
8565			bwi_mac_calibrate_txpower(mac);
8566
8567		/* XXX 15 seconds */
8568		timeout_add(&sc->sc_calib_ch, hz * 15);
8569	}
8570
8571	splx(s);
8572}
8573