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