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