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