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