xref: /netbsd-src/sys/dev/ic/bwi.c (revision 7f21db1c0118155e0dd40b75182e30c589d9f63e)
1 /*	$NetBSD: bwi.c,v 1.13 2010/01/19 22:06:24 pooka 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.13 2010/01/19 22:06:24 pooka 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 
64 #include <machine/bus.h>
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_ops->bpf_attach(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_ops->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 			if (ifp->if_bpf != NULL)
7446 				bpf_ops->bpf_mtap(ifp->if_bpf, m);
7447 			m = ieee80211_encap(ic, m, ni);
7448 			if (m == NULL) {
7449 				ifp->if_oerrors++;
7450 				ieee80211_free_node(ni);
7451 				continue;
7452 			}
7453 		}
7454 		if (ic->ic_rawbpf != NULL)
7455 			bpf_ops->bpf_mtap(ic->ic_rawbpf, m);
7456 
7457 		wh = mtod(m, struct ieee80211_frame *);
7458 		/* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */
7459 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
7460 			if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
7461 				ifp->if_oerrors++;
7462 				m_freem(m);
7463 				ieee80211_free_node(ni);
7464 				continue;
7465 			}
7466 		}
7467 		wh = NULL;	/* [TRC: XXX Huh?] */
7468 
7469 		if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) {
7470 			/* 'm' is freed in bwi_encap() if we reach here */
7471 			ifp->if_oerrors++;
7472 			if (ni != NULL)
7473 				ieee80211_free_node(ni);
7474 			continue;
7475 		}
7476 
7477 		trans = 1;
7478 		tbd->tbd_used++;
7479 		idx = (idx + 1) % BWI_TX_NDESC;
7480 
7481 		if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
7482 			ifp->if_flags |= IFF_OACTIVE;
7483 			break;
7484 		}
7485 	}
7486 	tbd->tbd_idx = idx;
7487 
7488 	if (trans)
7489 		sc->sc_tx_timer = 5;
7490 	ifp->if_timer = 1;
7491 }
7492 
7493 static void
7494 bwi_watchdog(struct ifnet *ifp)
7495 {
7496 	struct bwi_softc *sc = ifp->if_softc;
7497 
7498 	ifp->if_timer = 0;
7499 
7500 	if ((ifp->if_flags & IFF_RUNNING) == 0 ||
7501 	    !device_is_active(sc->sc_dev))
7502 		return;
7503 
7504 	if (sc->sc_tx_timer) {
7505 		if (--sc->sc_tx_timer == 0) {
7506 			aprint_error_dev(sc->sc_dev, "device timeout\n");
7507 			ifp->if_oerrors++;
7508 			/* TODO */
7509 			/* [TRC: XXX TODO what?  Stop the device?
7510 			   Bring it down?  iwi(4) does this.] */
7511 		} else
7512 			ifp->if_timer = 1;
7513 	}
7514 
7515 	ieee80211_watchdog(&sc->sc_ic);
7516 }
7517 
7518 static void
7519 bwi_stop(struct ifnet *ifp, int state_chg)
7520 {
7521 	struct bwi_softc *sc = ifp->if_softc;
7522 	struct ieee80211com *ic = &sc->sc_ic;
7523 	struct bwi_mac *mac;
7524 	int i, error, pwr_off = 0;
7525 
7526 	DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
7527 
7528 	if (state_chg)
7529 		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
7530 	else
7531 		bwi_newstate_begin(sc, IEEE80211_S_INIT);
7532 
7533 	if (ifp->if_flags & IFF_RUNNING) {
7534 		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7535 		mac = (struct bwi_mac *)sc->sc_cur_regwin;
7536 
7537 		bwi_disable_intrs(sc, BWI_ALL_INTRS);
7538 		CSR_READ_4(sc, BWI_MAC_INTR_MASK);
7539 		bwi_mac_stop(mac);
7540 	}
7541 
7542 	for (i = 0; i < sc->sc_nmac; ++i) {
7543 		struct bwi_regwin *old_rw;
7544 
7545 		mac = &sc->sc_mac[i];
7546 		if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
7547 			continue;
7548 
7549 		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
7550 		if (error)
7551 			continue;
7552 
7553 		bwi_mac_shutdown(mac);
7554 		pwr_off = 1;
7555 
7556 		bwi_regwin_switch(sc, old_rw, NULL);
7557 	}
7558 
7559 	if (pwr_off)
7560 		bwi_bbp_power_off(sc);
7561 
7562 	sc->sc_tx_timer = 0;
7563 	ifp->if_timer = 0;
7564 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
7565 
7566 	/* power off cardbus socket */
7567 	if (sc->sc_disable)
7568 		(sc->sc_disable)(sc);
7569 
7570 	return;
7571 }
7572 
7573 static void
7574 bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
7575 {
7576 	callout_stop(&sc->sc_scan_ch);
7577 	callout_stop(&sc->sc_calib_ch);
7578 
7579 	bwi_led_newstate(sc, nstate);
7580 
7581 	if (nstate == IEEE80211_S_INIT)
7582 		sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
7583 }
7584 
7585 static int
7586 bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7587 {
7588 	struct bwi_softc *sc = ic->ic_ifp->if_softc;
7589 	struct ieee80211_node *ni;
7590 	int error;
7591 
7592 	/* [TRC: XXX amrr] */
7593 	callout_stop(&sc->sc_amrr_ch);
7594 
7595 	bwi_newstate_begin(sc, nstate);
7596 
7597 	if (nstate == IEEE80211_S_INIT)
7598 		goto back;
7599 
7600 	/* [TRC: XXX What channel do we set this to? */
7601 	error = bwi_set_chan(sc, ic->ic_curchan);
7602 	if (error) {
7603 		aprint_error_dev(sc->sc_dev, "can't set channel to %u\n",
7604 		    ieee80211_chan2ieee(ic, ic->ic_curchan));
7605 		return (error);
7606 	}
7607 
7608 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7609 		/* Nothing to do */
7610 	} else if (nstate == IEEE80211_S_RUN) {
7611 		struct bwi_mac *mac;
7612 
7613 		ni = ic->ic_bss;
7614 
7615 		bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
7616 
7617 		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7618 		mac = (struct bwi_mac *)sc->sc_cur_regwin;
7619 
7620 		/* Initial TX power calibration */
7621 		bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
7622 #ifdef notyet
7623 		sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
7624 #else
7625 		sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
7626 #endif
7627 		/* [TRC: XXX amrr] */
7628 		if (ic->ic_opmode == IEEE80211_M_STA) {
7629 			/* fake a join to init the tx rate */
7630 			bwi_newassoc(ni, 1);
7631 		}
7632 
7633 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7634 			/* start automatic rate control timer */
7635 			if (ic->ic_fixed_rate == -1)
7636 				callout_schedule(&sc->sc_amrr_ch, hz / 2);
7637 		}
7638 	} else
7639 		bwi_set_bssid(sc, bwi_zero_addr);
7640 
7641 back:
7642 	error = (sc->sc_newstate)(ic, nstate, arg);
7643 
7644 	if (nstate == IEEE80211_S_SCAN) {
7645 		callout_schedule(&sc->sc_scan_ch,
7646 		    (sc->sc_dwell_time * hz) / 1000);
7647 	} else if (nstate == IEEE80211_S_RUN) {
7648 		/* XXX 15 seconds */
7649 		callout_schedule(&sc->sc_calib_ch, hz);
7650 	}
7651 
7652 	return (error);
7653 }
7654 
7655 static int
7656 bwi_media_change(struct ifnet *ifp)
7657 {
7658 	int error;
7659 
7660 	error = ieee80211_media_change(ifp);
7661 	if (error != ENETRESET)
7662 		return (error);
7663 
7664 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
7665 		bwi_init(ifp);
7666 
7667 	return (0);
7668 }
7669 
7670 /* [TRC: XXX amrr] */
7671 static void
7672 bwi_iter_func(void *arg, struct ieee80211_node *ni)
7673 {
7674 	struct bwi_softc *sc = arg;
7675 	struct bwi_node *bn = (struct bwi_node *)ni;
7676 
7677 	ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
7678 }
7679 
7680 static void
7681 bwi_amrr_timeout(void *arg)
7682 {
7683 	struct bwi_softc *sc = arg;
7684 	struct ieee80211com *ic = &sc->sc_ic;
7685 
7686 	if (ic->ic_opmode == IEEE80211_M_STA)
7687 		bwi_iter_func(sc, ic->ic_bss);
7688 	else
7689 		/* [TRC: XXX I'm making a wild guess about what to
7690 		   supply for the node table.] */
7691 		ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc);
7692 
7693 	callout_schedule(&sc->sc_amrr_ch, hz / 2);
7694 }
7695 
7696 static void
7697 bwi_newassoc(struct ieee80211_node *ni, int isnew)
7698 {
7699 	struct ieee80211com *ic = ni->ni_ic;
7700 	struct bwi_softc *sc = ic->ic_ifp->if_softc;
7701 	int i;
7702 
7703 	DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__);
7704 
7705 	ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
7706 
7707 	/* set rate to some reasonable initial value */
7708 	for (i = ni->ni_rates.rs_nrates - 1;
7709 	    i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
7710 	    i--);
7711 
7712 	ni->ni_txrate = i;
7713 }
7714 
7715 static struct ieee80211_node *
7716 bwi_node_alloc(struct ieee80211_node_table *nt)
7717 {
7718 	struct bwi_node *bn;
7719 
7720 	bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
7721 
7722 	return ((struct ieee80211_node *)bn);
7723 }
7724 /* [TRC: XXX amrr end] */
7725 
7726 static int
7727 bwi_dma_alloc(struct bwi_softc *sc)
7728 {
7729 	int error, i, has_txstats;
7730 	/* [TRC: XXX DragonFlyBSD adjusts the low address for different
7731 	   bus spaces.  Should we?] */
7732 	bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
7733 	uint32_t txrx_ctrl_step = 0;
7734 
7735 	has_txstats = 0;
7736 	for (i = 0; i < sc->sc_nmac; ++i) {
7737 		if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
7738 			has_txstats = 1;
7739 			break;
7740 		}
7741 	}
7742 
7743 	switch (sc->sc_bus_space) {
7744 	case BWI_BUS_SPACE_30BIT:
7745 	case BWI_BUS_SPACE_32BIT:
7746 		desc_sz = sizeof(struct bwi_desc32);
7747 		txrx_ctrl_step = 0x20;
7748 
7749 		sc->sc_init_tx_ring = bwi_init_tx_ring32;
7750 		sc->sc_free_tx_ring = bwi_free_tx_ring32;
7751 		sc->sc_init_rx_ring = bwi_init_rx_ring32;
7752 		sc->sc_free_rx_ring = bwi_free_rx_ring32;
7753 		sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
7754 		sc->sc_setup_txdesc = bwi_setup_tx_desc32;
7755 		sc->sc_rxeof = bwi_rxeof32;
7756 		sc->sc_start_tx = bwi_start_tx32;
7757 		if (has_txstats) {
7758 			sc->sc_init_txstats = bwi_init_txstats32;
7759 			sc->sc_free_txstats = bwi_free_txstats32;
7760 			sc->sc_txeof_status = bwi_txeof_status32;
7761 		}
7762 		break;
7763 
7764 	case BWI_BUS_SPACE_64BIT:
7765 		desc_sz = sizeof(struct bwi_desc64);
7766 		txrx_ctrl_step = 0x40;
7767 
7768 		sc->sc_init_tx_ring = bwi_init_tx_ring64;
7769 		sc->sc_free_tx_ring = bwi_free_tx_ring64;
7770 		sc->sc_init_rx_ring = bwi_init_rx_ring64;
7771 		sc->sc_free_rx_ring = bwi_free_rx_ring64;
7772 		sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
7773 		sc->sc_setup_txdesc = bwi_setup_tx_desc64;
7774 		sc->sc_rxeof = bwi_rxeof64;
7775 		sc->sc_start_tx = bwi_start_tx64;
7776 		if (has_txstats) {
7777 			sc->sc_init_txstats = bwi_init_txstats64;
7778 			sc->sc_free_txstats = bwi_free_txstats64;
7779 			sc->sc_txeof_status = bwi_txeof_status64;
7780 		}
7781 		break;
7782 	}
7783 
7784 	KASSERT(desc_sz != 0);
7785 	KASSERT(txrx_ctrl_step != 0);
7786 
7787 	tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
7788 	rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
7789 
7790 	/* [TRC: XXX Using OpenBSD's code, which is rather different
7791 	   from DragonFlyBSD's.] */
7792 #define TXRX_CTRL(idx)	(BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
7793 	/*
7794 	 * Create TX ring DMA stuffs
7795 	 */
7796 	for (i = 0; i < BWI_TX_NRING; ++i) {
7797 		error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1,
7798 		    tx_ring_sz, 0, BUS_DMA_NOWAIT,
7799 		    &sc->sc_tx_rdata[i].rdata_dmap);
7800 		if (error) {
7801 			aprint_error_dev(sc->sc_dev,
7802 			    "%dth TX ring DMA create failed\n", i);
7803 			return (error);
7804 		}
7805 		error = bwi_dma_ring_alloc(sc,
7806 		    &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
7807 		if (error) {
7808 			aprint_error_dev(sc->sc_dev,
7809 			    "%dth TX ring DMA alloc failed\n", i);
7810 			return (error);
7811 		}
7812 	}
7813 
7814 	/*
7815 	 * Create RX ring DMA stuffs
7816 	 */
7817 	error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1,
7818 	    rx_ring_sz, 0, BUS_DMA_NOWAIT,
7819 	    &sc->sc_rx_rdata.rdata_dmap);
7820 	if (error) {
7821 		aprint_error_dev(sc->sc_dev, "RX ring DMA create failed\n");
7822 		return (error);
7823 	}
7824 
7825 	error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
7826 	    rx_ring_sz, TXRX_CTRL(0));
7827 	if (error) {
7828 		aprint_error_dev(sc->sc_dev, "RX ring DMA alloc failed\n");
7829 		return (error);
7830 	}
7831 
7832 	if (has_txstats) {
7833 		error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
7834 		if (error) {
7835 			aprint_error_dev(sc->sc_dev,
7836 			    "TX stats DMA alloc failed\n");
7837 			return (error);
7838 		}
7839 	}
7840 #undef TXRX_CTRL
7841 
7842 	return (bwi_dma_mbuf_create(sc));
7843 }
7844 
7845 static void
7846 bwi_dma_free(struct bwi_softc *sc)
7847 {
7848 	int i;
7849 
7850 	for (i = 0; i < BWI_TX_NRING; ++i)
7851 		bwi_ring_data_free(&sc->sc_tx_rdata[i], sc);
7852 
7853 	bwi_ring_data_free(&sc->sc_rx_rdata, sc);
7854 	bwi_dma_txstats_free(sc);
7855 	bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
7856 }
7857 
7858 static void
7859 bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc)
7860 {
7861 	if (rd->rdata_desc != NULL) {
7862 		bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
7863 		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1);
7864 	}
7865 }
7866 
7867 static int
7868 bwi_dma_ring_alloc(struct bwi_softc *sc,
7869     struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
7870 {
7871 	int error, nsegs;
7872 
7873 	error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0,
7874 	    &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7875 	if (error) {
7876 		aprint_error_dev(sc->sc_dev, "can't allocate DMA mem\n");
7877 		return (error);
7878 	}
7879 
7880 	error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs,
7881 	    size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT);
7882 	if (error) {
7883 		aprint_error_dev(sc->sc_dev, "can't map DMA mem\n");
7884 		return (error);
7885 	}
7886 
7887 	error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
7888 	    size, NULL, BUS_DMA_WAITOK);
7889 	if (error) {
7890 		aprint_error_dev(sc->sc_dev, "can't load DMA mem\n");
7891 		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs);
7892 		rd->rdata_desc = NULL;
7893 		return (error);
7894 	}
7895 
7896 	rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
7897 	rd->rdata_txrx_ctrl = txrx_ctrl;
7898 
7899 	return (0);
7900 }
7901 
7902 static int
7903 bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
7904     bus_size_t desc_sz)
7905 {
7906 	struct bwi_txstats_data *st;
7907 	bus_size_t dma_size;
7908 	int error, nsegs;
7909 
7910 	st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
7911 	sc->sc_txstats = st;
7912 
7913 	/*
7914 	 * Create TX stats descriptor DMA stuffs
7915 	 */
7916 	dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
7917 
7918 	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7919 	    BUS_DMA_NOWAIT, &st->stats_ring_dmap);
7920 	if (error) {
7921 		aprint_error_dev(sc->sc_dev,
7922 		    "can't create txstats ring DMA mem\n");
7923 		return (error);
7924 	}
7925 
7926 	/*
7927 	 * Create TX stats descriptor DMA stuffs
7928 	 */
7929 	dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
7930 
7931 	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7932 	    BUS_DMA_NOWAIT, &st->stats_ring_dmap);
7933 	if (error) {
7934 		aprint_error_dev(sc->sc_dev,
7935 		    "can't create txstats ring DMA mem\n");
7936 		return (error);
7937 	}
7938 
7939 	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
7940 	     &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7941 	if (error) {
7942 		aprint_error_dev(sc->sc_dev,
7943 		    "can't allocate txstats ring DMA mem\n");
7944 		return (error);
7945 	}
7946 
7947 	error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
7948 	    dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT);
7949 	if (error) {
7950 		aprint_error_dev(sc->sc_dev,
7951 		    "can't map txstats ring DMA mem\n");
7952 		return (error);
7953 	}
7954 
7955 	error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
7956 	    st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
7957 	if (error) {
7958 		aprint_error_dev(sc->sc_dev,
7959 		    "can't load txstats ring DMA mem\n");
7960 		bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
7961 		return (error);
7962 	}
7963 
7964 	memset(st->stats_ring, 0, dma_size);
7965 	st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
7966 
7967 	/*
7968 	 * Create TX stats DMA stuffs
7969 	 */
7970 	dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
7971 	    BWI_ALIGN);
7972 
7973 	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7974 	    BUS_DMA_NOWAIT, &st->stats_dmap);
7975 	if (error) {
7976 		aprint_error_dev(sc->sc_dev,
7977 		    "can't create txstats ring DMA mem\n");
7978 		return (error);
7979 	}
7980 
7981 	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
7982 	    &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7983 	if (error) {
7984 		aprint_error_dev(sc->sc_dev,
7985 		    "can't allocate txstats DMA mem\n");
7986 		return (error);
7987 	}
7988 
7989 	error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
7990 	    dma_size, (void **)&st->stats, BUS_DMA_NOWAIT);
7991 	if (error) {
7992 		aprint_error_dev(sc->sc_dev, "can't map txstats DMA mem\n");
7993 		return (error);
7994 	}
7995 
7996 	error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
7997 	    dma_size, NULL, BUS_DMA_WAITOK);
7998 	if (error) {
7999 		aprint_error_dev(sc->sc_dev, "can't load txstats DMA mem\n");
8000 		bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
8001 		return (error);
8002 	}
8003 
8004 	memset(st->stats, 0, dma_size);
8005 	st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
8006 	st->stats_ctrl_base = ctrl_base;
8007 
8008 	return (0);
8009 }
8010 
8011 static void
8012 bwi_dma_txstats_free(struct bwi_softc *sc)
8013 {
8014 	struct bwi_txstats_data *st;
8015 
8016 	if (sc->sc_txstats == NULL)
8017 		return;
8018 	st = sc->sc_txstats;
8019 
8020 	bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
8021 	bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
8022 
8023 	bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
8024 	bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
8025 
8026 	free(st, M_DEVBUF);
8027 }
8028 
8029 static int
8030 bwi_dma_mbuf_create(struct bwi_softc *sc)
8031 {
8032 	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8033 	int i, j, k, ntx, error;
8034 
8035 	ntx = 0;
8036 
8037 	/*
8038 	 * Create TX mbuf DMA map
8039 	 */
8040 	for (i = 0; i < BWI_TX_NRING; ++i) {
8041 		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8042 
8043 		for (j = 0; j < BWI_TX_NDESC; ++j) {
8044 			error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
8045 			    0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
8046 			if (error) {
8047 				aprint_error_dev(sc->sc_dev,
8048 				    "can't create %dth tbd, %dth DMA map\n",
8049 				    i, j);
8050 				ntx = i;
8051 				for (k = 0; k < j; ++k) {
8052 					bus_dmamap_destroy(sc->sc_dmat,
8053 					    tbd->tbd_buf[k].tb_dmap);
8054 				}
8055 				goto fail;
8056 			}
8057 		}
8058 	}
8059 	ntx = BWI_TX_NRING;
8060 
8061 	/*
8062 	 * Create RX mbuf DMA map and a spare DMA map
8063 	 */
8064 	error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8065 	    BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
8066 	if (error) {
8067 		aprint_error_dev(sc->sc_dev,
8068 		    "can't create spare RX buf DMA map\n");
8069 		goto fail;
8070 	}
8071 
8072 	for (j = 0; j < BWI_RX_NDESC; ++j) {
8073 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8074 		    BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
8075 		if (error) {
8076 			aprint_error_dev(sc->sc_dev,
8077 			    "can't create %dth RX buf DMA map\n", j);
8078 
8079 			for (k = 0; k < j; ++k) {
8080 				bus_dmamap_destroy(sc->sc_dmat,
8081 				    rbd->rbd_buf[j].rb_dmap);
8082 			}
8083 			bus_dmamap_destroy(sc->sc_dmat,
8084 			    rbd->rbd_tmp_dmap);
8085 			goto fail;
8086 		}
8087 	}
8088 
8089 	return (0);
8090 fail:
8091 	bwi_dma_mbuf_destroy(sc, ntx, 0);
8092 
8093 	return (error);
8094 }
8095 
8096 static void
8097 bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
8098 {
8099 	int i, j;
8100 
8101 	for (i = 0; i < ntx; ++i) {
8102 		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8103 
8104 		for (j = 0; j < BWI_TX_NDESC; ++j) {
8105 			struct bwi_txbuf *tb = &tbd->tbd_buf[j];
8106 
8107 			if (tb->tb_mbuf != NULL) {
8108 				bus_dmamap_unload(sc->sc_dmat,
8109 				    tb->tb_dmap);
8110 				m_freem(tb->tb_mbuf);
8111 			}
8112 			if (tb->tb_ni != NULL)
8113 				ieee80211_free_node(tb->tb_ni);
8114 			bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
8115 		}
8116 	}
8117 
8118 	if (nrx) {
8119 		struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8120 
8121 		bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
8122 		for (j = 0; j < BWI_RX_NDESC; ++j) {
8123 			struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
8124 
8125 			if (rb->rb_mbuf != NULL) {
8126 				bus_dmamap_unload(sc->sc_dmat,
8127 						  rb->rb_dmap);
8128 				m_freem(rb->rb_mbuf);
8129 			}
8130 			bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
8131 		}
8132 	}
8133 }
8134 
8135 static void
8136 bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
8137 {
8138 	CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
8139 }
8140 
8141 static void
8142 bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
8143 {
8144 	CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
8145 }
8146 
8147 static int
8148 bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
8149 {
8150 	struct bwi_ring_data *rd;
8151 	struct bwi_txbuf_data *tbd;
8152 	uint32_t val, addr_hi, addr_lo;
8153 
8154 	KASSERT(ring_idx < BWI_TX_NRING);
8155 	rd = &sc->sc_tx_rdata[ring_idx];
8156 	tbd = &sc->sc_tx_bdata[ring_idx];
8157 
8158 	tbd->tbd_idx = 0;
8159 	tbd->tbd_used = 0;
8160 
8161 	memset(rd->rdata_desc, 0, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
8162 	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8163 	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8164 
8165 	addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8166 	addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8167 
8168 	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8169 	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8170 	    BWI_TXRX32_RINGINFO_FUNC_MASK);
8171 	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
8172 
8173 	val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8174 	      BWI_TXRX32_CTRL_ENABLE;
8175 	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
8176 
8177 	return (0);
8178 }
8179 
8180 static void
8181 bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
8182     bus_addr_t paddr, int hdr_size, int ndesc)
8183 {
8184 	uint32_t val, addr_hi, addr_lo;
8185 
8186 	addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8187 	addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8188 
8189 	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8190 	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8191 	      		BWI_TXRX32_RINGINFO_FUNC_MASK);
8192 	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
8193 
8194 	val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
8195 	    __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8196 	    BWI_TXRX32_CTRL_ENABLE;
8197 	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
8198 
8199 	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8200 	    (ndesc - 1) * sizeof(struct bwi_desc32));
8201 }
8202 
8203 static int
8204 bwi_init_rx_ring32(struct bwi_softc *sc)
8205 {
8206 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8207 	int i, error;
8208 
8209 	sc->sc_rx_bdata.rbd_idx = 0;
8210 
8211 	for (i = 0; i < BWI_RX_NDESC; ++i) {
8212 		error = bwi_newbuf(sc, i, 1);
8213 		if (error) {
8214 			aprint_error_dev(sc->sc_dev,
8215 			    "can't allocate %dth RX buffer\n", i);
8216 			return (error);
8217 		}
8218 	}
8219 	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8220 	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8221 
8222 	bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
8223 	    sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
8224 	return (0);
8225 }
8226 
8227 static int
8228 bwi_init_txstats32(struct bwi_softc *sc)
8229 {
8230 	struct bwi_txstats_data *st = sc->sc_txstats;
8231 	bus_addr_t stats_paddr;
8232 	int i;
8233 
8234 	memset(st->stats, 0, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
8235 	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8236 	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8237 
8238 	st->stats_idx = 0;
8239 
8240 	stats_paddr = st->stats_paddr;
8241 	for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
8242 		bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
8243 				 stats_paddr, sizeof(struct bwi_txstats), 0);
8244 		stats_paddr += sizeof(struct bwi_txstats);
8245 	}
8246 	bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
8247 	    st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8248 
8249 	bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
8250 	    st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
8251 
8252 	return (0);
8253 }
8254 
8255 static void
8256 bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8257     int buf_len)
8258 {
8259 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8260 
8261 	KASSERT(buf_idx < BWI_RX_NDESC);
8262 	bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
8263 	    paddr, buf_len, 0);
8264 }
8265 
8266 static void
8267 bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
8268     int buf_idx, bus_addr_t paddr, int buf_len)
8269 {
8270 	KASSERT(buf_idx < BWI_TX_NDESC);
8271 	bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
8272 	    paddr, buf_len, 1);
8273 }
8274 static int
8275 bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
8276 {
8277 	/* TODO: 64 */
8278 	return (EOPNOTSUPP);
8279 }
8280 
8281 static int
8282 bwi_init_rx_ring64(struct bwi_softc *sc)
8283 {
8284 	/* TODO: 64 */
8285 	return (EOPNOTSUPP);
8286 }
8287 
8288 static int
8289 bwi_init_txstats64(struct bwi_softc *sc)
8290 {
8291 	/* TODO: 64 */
8292 	return (EOPNOTSUPP);
8293 }
8294 
8295 static void
8296 bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8297     int buf_len)
8298 {
8299 	/* TODO: 64 */
8300 }
8301 
8302 static void
8303 bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
8304     int buf_idx, bus_addr_t paddr, int buf_len)
8305 {
8306 	/* TODO: 64 */
8307 }
8308 
8309 static int
8310 bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
8311 {
8312 	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8313 	struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
8314 	struct bwi_rxbuf_hdr *hdr;
8315 	bus_dmamap_t map;
8316 	bus_addr_t paddr;
8317 	struct mbuf *m;
8318 	int error;
8319 
8320 	KASSERT(buf_idx < BWI_RX_NDESC);
8321 
8322 	MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
8323 	if (m == NULL)
8324 		return (ENOBUFS);
8325 	MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
8326 	if (m == NULL) {
8327 		error = ENOBUFS;
8328 
8329 		/*
8330 		 * If the NIC is up and running, we need to:
8331 		 * - Clear RX buffer's header.
8332 		 * - Restore RX descriptor settings.
8333 		 */
8334 		if (init)
8335 			return error;
8336 		else
8337 			goto back;
8338 	}
8339 	m->m_len = m->m_pkthdr.len = MCLBYTES;
8340 
8341 	/*
8342 	 * Try to load RX buf into temporary DMA map
8343 	 */
8344 	error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
8345 	    init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
8346 	if (error) {
8347 		m_freem(m);
8348 
8349 		/*
8350 		 * See the comment above
8351 		 */
8352 		if (init)
8353 			return error;
8354 		else
8355 			goto back;
8356 	}
8357 
8358 	if (!init)
8359 		bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
8360 	rxbuf->rb_mbuf = m;
8361 
8362 	/*
8363 	 * Swap RX buf's DMA map with the loaded temporary one
8364 	 */
8365 	map = rxbuf->rb_dmap;
8366 	rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
8367 	rbd->rbd_tmp_dmap = map;
8368 	paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
8369 	rxbuf->rb_paddr = paddr;
8370 
8371 back:
8372 	/*
8373 	 * Clear RX buf header
8374 	 */
8375 	hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
8376 	memset(hdr, 0, sizeof(*hdr));
8377 	bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
8378 	    rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8379 
8380 	/*
8381 	 * Setup RX buf descriptor
8382 	 */
8383 	(sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr,
8384 	    rxbuf->rb_mbuf->m_len - sizeof(*hdr));
8385 	return error;
8386 }
8387 
8388 static void
8389 bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
8390     const uint8_t *addr)
8391 {
8392 	int i;
8393 
8394 	CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
8395 	    BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
8396 
8397 	for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
8398 		uint16_t addr_val;
8399 
8400 		addr_val = (uint16_t)addr[i * 2] |
8401 		    (((uint16_t)addr[(i * 2) + 1]) << 8);
8402 		CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
8403 	}
8404 }
8405 
8406 static int
8407 bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c)
8408 {
8409 	struct ieee80211com *ic = &sc->sc_ic;
8410 	struct bwi_mac *mac;
8411 	/* uint16_t flags; */ /* [TRC: XXX See below.] */
8412 	uint chan;
8413 
8414 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8415 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8416 
8417 	chan = ieee80211_chan2ieee(ic, c);
8418 
8419 	bwi_rf_set_chan(mac, chan, 0);
8420 
8421 	/* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency
8422 	   and flags here.  OpenBSD does not, and appears to do so
8423 	   later (in bwi_rxeof and bwi_encap).] */
8424 
8425 	return (0);
8426 }
8427 
8428 static void
8429 bwi_next_scan(void *xsc)
8430 {
8431 	struct bwi_softc *sc = xsc;
8432 	struct ieee80211com *ic = &sc->sc_ic;
8433 	int s;
8434 
8435 	s = splnet();
8436 
8437 	if (ic->ic_state == IEEE80211_S_SCAN)
8438 		ieee80211_next_scan(ic);
8439 
8440 	splx(s);
8441 }
8442 
8443 static int
8444 bwi_rxeof(struct bwi_softc *sc, int end_idx)
8445 {
8446 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8447 	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8448 	struct ieee80211com *ic = &sc->sc_ic;
8449 	struct ifnet *ifp = &sc->sc_if;
8450 	int idx, rx_data = 0;
8451 
8452 	idx = rbd->rbd_idx;
8453 	while (idx != end_idx) {
8454 		struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
8455 		struct bwi_rxbuf_hdr *hdr;
8456 		struct ieee80211_frame_min *wh;
8457 		struct ieee80211_node *ni;
8458 		struct mbuf *m;
8459 		const void *plcp;
8460 		uint16_t flags2;
8461 		int buflen, wh_ofs, hdr_extra, rssi, type, rate;
8462 
8463 		m = rb->rb_mbuf;
8464 		bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
8465 		    rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8466 
8467 		if (bwi_newbuf(sc, idx, 0)) {
8468 			ifp->if_ierrors++;
8469 			goto next;
8470 		}
8471 
8472 		hdr = mtod(m, struct bwi_rxbuf_hdr *);
8473 		flags2 = le16toh(hdr->rxh_flags2);
8474 
8475 		hdr_extra = 0;
8476 		if (flags2 & BWI_RXH_F2_TYPE2FRAME)
8477 			hdr_extra = 2;
8478 		wh_ofs = hdr_extra + 6; /* XXX magic number */
8479 
8480 		buflen = le16toh(hdr->rxh_buflen);
8481 		if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
8482 			aprint_error_dev(sc->sc_dev, "short frame %d,"
8483 			    " hdr_extra %d\n", buflen, hdr_extra);
8484 			ifp->if_ierrors++;
8485 			m_freem(m);
8486 			goto next;
8487 		}
8488 
8489 		plcp = ((const uint8_t *)(hdr + 1) + hdr_extra);
8490 		rssi = bwi_calc_rssi(sc, hdr);
8491 
8492 		m->m_pkthdr.rcvif = ifp;
8493 		m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
8494 		m_adj(m, sizeof(*hdr) + wh_ofs);
8495 
8496 		if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
8497 			rate = bwi_ofdm_plcp2rate(plcp);
8498 		else
8499 			rate = bwi_ds_plcp2rate(plcp);
8500 
8501 		/* RX radio tap */
8502 		if (sc->sc_drvbpf != NULL) {
8503 			struct mbuf mb;
8504 			struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
8505 
8506 			tap->wr_tsf = hdr->rxh_tsf;
8507 			tap->wr_flags = 0;
8508 			tap->wr_rate = rate;
8509 			tap->wr_chan_freq =
8510 			    htole16(ic->ic_bss->ni_chan->ic_freq);
8511 			tap->wr_chan_flags =
8512 			    htole16(ic->ic_bss->ni_chan->ic_flags);
8513 			tap->wr_antsignal = rssi;
8514 			tap->wr_antnoise = BWI_NOISE_FLOOR;
8515 
8516 			mb.m_data = (void *)tap;
8517 			mb.m_len = sc->sc_rxtap_len;
8518 			mb.m_next = m;
8519 			mb.m_nextpkt = NULL;
8520 			mb.m_type = 0;
8521 			mb.m_flags = 0;
8522 			bpf_ops->bpf_mtap(sc->sc_drvbpf, &mb);
8523 		}
8524 
8525 		m_adj(m, -IEEE80211_CRC_LEN);
8526 
8527 		wh = mtod(m, struct ieee80211_frame_min *);
8528 		ni = ieee80211_find_rxnode(ic, wh);
8529 		type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
8530 
8531 		ieee80211_input(ic, m, ni, hdr->rxh_rssi,
8532 		    le16toh(hdr->rxh_tsf));
8533 
8534 		ieee80211_free_node(ni);
8535 
8536 		if (type == IEEE80211_FC0_TYPE_DATA) {
8537 			rx_data = 1;
8538 			sc->sc_rx_rate = rate;
8539 		}
8540 next:
8541 		idx = (idx + 1) % BWI_RX_NDESC;
8542 	}
8543 
8544 	rbd->rbd_idx = idx;
8545 	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8546 	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8547 
8548 	return (rx_data);
8549 }
8550 
8551 static int
8552 bwi_rxeof32(struct bwi_softc *sc)
8553 {
8554 	uint32_t val, rx_ctrl;
8555 	int end_idx, rx_data;
8556 
8557 	rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
8558 
8559 	val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8560 	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
8561 	    sizeof(struct bwi_desc32);
8562 
8563 	rx_data = bwi_rxeof(sc, end_idx);
8564 
8565 	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
8566 	    end_idx * sizeof(struct bwi_desc32));
8567 
8568 	return (rx_data);
8569 }
8570 
8571 static int
8572 bwi_rxeof64(struct bwi_softc *sc)
8573 {
8574 	/* TODO: 64 */
8575 	return (0);
8576 }
8577 
8578 static void
8579 bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
8580 {
8581 	int i;
8582 
8583 	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
8584 
8585 #define NRETRY 10
8586 	for (i = 0; i < NRETRY; ++i) {
8587 		uint32_t status;
8588 
8589 		status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
8590 		if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
8591 		    BWI_RX32_STATUS_STATE_DISABLED)
8592 			break;
8593 
8594 		DELAY(1000);
8595 	}
8596 	if (i == NRETRY)
8597 		aprint_error_dev(sc->sc_dev, "reset rx ring timedout\n");
8598 #undef NRETRY
8599 
8600 	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
8601 }
8602 
8603 static void
8604 bwi_free_txstats32(struct bwi_softc *sc)
8605 {
8606 	bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
8607 }
8608 
8609 static void
8610 bwi_free_rx_ring32(struct bwi_softc *sc)
8611 {
8612 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8613 	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8614 	int i;
8615 
8616 	bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
8617 
8618 	for (i = 0; i < BWI_RX_NDESC; ++i) {
8619 		struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
8620 
8621 		if (rb->rb_mbuf != NULL) {
8622 			bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
8623 			m_freem(rb->rb_mbuf);
8624 			rb->rb_mbuf = NULL;
8625 		}
8626 	}
8627 }
8628 
8629 static void
8630 bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
8631 {
8632 	struct bwi_ring_data *rd;
8633 	struct bwi_txbuf_data *tbd;
8634 	uint32_t state, val;
8635 	int i;
8636 
8637 	KASSERT(ring_idx < BWI_TX_NRING);
8638 	rd = &sc->sc_tx_rdata[ring_idx];
8639 	tbd = &sc->sc_tx_bdata[ring_idx];
8640 
8641 #define NRETRY 10
8642 	for (i = 0; i < NRETRY; ++i) {
8643 		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8644 		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8645 		if (state == BWI_TX32_STATUS_STATE_DISABLED ||
8646 		    state == BWI_TX32_STATUS_STATE_IDLE ||
8647 		    state == BWI_TX32_STATUS_STATE_STOPPED)
8648 			break;
8649 
8650 		DELAY(1000);
8651 	}
8652 	if (i == NRETRY)
8653 		aprint_error_dev(sc->sc_dev,
8654 		    "wait for TX ring(%d) stable timed out\n", ring_idx);
8655 
8656 	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
8657 	for (i = 0; i < NRETRY; ++i) {
8658 		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
8659 		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
8660 		if (state == BWI_TX32_STATUS_STATE_DISABLED)
8661 			break;
8662 
8663 		DELAY(1000);
8664 	}
8665 	if (i == NRETRY)
8666 		aprint_error_dev(sc->sc_dev, "reset TX ring (%d) timed out\n",
8667 		    ring_idx);
8668 #undef NRETRY
8669 
8670 	DELAY(1000);
8671 
8672 	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
8673 
8674 	for (i = 0; i < BWI_TX_NDESC; ++i) {
8675 		struct bwi_txbuf *tb = &tbd->tbd_buf[i];
8676 
8677 		if (tb->tb_mbuf != NULL) {
8678 			bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
8679 			m_freem(tb->tb_mbuf);
8680 			tb->tb_mbuf = NULL;
8681 		}
8682 		if (tb->tb_ni != NULL) {
8683 			ieee80211_free_node(tb->tb_ni);
8684 			tb->tb_ni = NULL;
8685 		}
8686 	}
8687 }
8688 
8689 static void
8690 bwi_free_txstats64(struct bwi_softc *sc)
8691 {
8692 	/* TODO: 64 */
8693 }
8694 
8695 static void
8696 bwi_free_rx_ring64(struct bwi_softc *sc)
8697 {
8698 	/* TODO: 64 */
8699 }
8700 
8701 static void
8702 bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
8703 {
8704 	/* TODO: 64 */
8705 }
8706 
8707 /* XXX does not belong here */
8708 /* [TRC: Begin pilferage from OpenBSD.] */
8709 
8710 /*
8711  * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa.
8712  */
8713 uint8_t
8714 bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode)
8715 {
8716 	rate &= IEEE80211_RATE_VAL;
8717 
8718 	if (mode == IEEE80211_MODE_11B) {
8719 		/* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */
8720 		switch (rate) {
8721 		case 2:		return 10;
8722 		case 4:		return 20;
8723 		case 11:	return 55;
8724 		case 22:	return 110;
8725 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8726 		case 44:	return 220;
8727 		}
8728 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
8729 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
8730 		switch (rate) {
8731 		case 12:	return 0x0b;
8732 		case 18:	return 0x0f;
8733 		case 24:	return 0x0a;
8734 		case 36:	return 0x0e;
8735 		case 48:	return 0x09;
8736 		case 72:	return 0x0d;
8737 		case 96:	return 0x08;
8738 		case 108:	return 0x0c;
8739 		}
8740         } else
8741 		panic("Unexpected mode %u", mode);
8742 
8743 	return 0;
8744 }
8745 
8746 static uint8_t
8747 bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode)
8748 {
8749 	if (mode == IEEE80211_MODE_11B) {
8750 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8751 		switch (plcp) {
8752 		case 10:	return 2;
8753 		case 20:	return 4;
8754 		case 55:	return 11;
8755 		case 110:	return 22;
8756 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
8757 		case 220:	return 44;
8758 		}
8759 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
8760 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
8761 		switch (plcp) {
8762 		case 0x0b:	return 12;
8763 		case 0x0f:	return 18;
8764 		case 0x0a:	return 24;
8765 		case 0x0e:	return 36;
8766 		case 0x09:	return 48;
8767 		case 0x0d:	return 72;
8768 		case 0x08:	return 96;
8769 		case 0x0c:	return 108;
8770 		}
8771 	} else
8772 		panic("Unexpected mode %u", mode);
8773 
8774 	return 0;
8775 }
8776 /* [TRC: End pilferage from OpenBSD.] */
8777 
8778 static enum bwi_ieee80211_modtype
8779 bwi_ieee80211_rate2modtype(uint8_t rate)
8780 {
8781 	rate &= IEEE80211_RATE_VAL;
8782 
8783 	if (rate == 44)
8784 		return (IEEE80211_MODTYPE_PBCC);
8785 	else if (rate == 22 || rate < 12)
8786 		return (IEEE80211_MODTYPE_DS);
8787 	else
8788 		return (IEEE80211_MODTYPE_OFDM);
8789 }
8790 
8791 static uint8_t
8792 bwi_ofdm_plcp2rate(const uint32_t *plcp0)
8793 {
8794 	uint32_t plcp;
8795 	uint8_t plcp_rate;
8796 
8797 	plcp = le32toh(*plcp0);
8798 	plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK);
8799 
8800 	return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G));
8801 }
8802 
8803 static uint8_t
8804 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr)
8805 {
8806 	return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B));
8807 }
8808 
8809 static void
8810 bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
8811 {
8812 	uint32_t plcp;
8813 
8814 	plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G),
8815 	    IEEE80211_OFDM_PLCP_RATE_MASK) |
8816 	    __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
8817 	*plcp0 = htole32(plcp);
8818 }
8819 
8820 static void
8821 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
8822     uint8_t rate)
8823 {
8824 	int len, service, pkt_bitlen;
8825 
8826 	pkt_bitlen = pkt_len * NBBY;
8827 	len = howmany(pkt_bitlen * 2, rate);
8828 
8829 	service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
8830 	if (rate == (11 * 2)) {
8831 		int pkt_bitlen1;
8832 
8833 		/*
8834 		 * PLCP service field needs to be adjusted,
8835 		 * if TX rate is 11Mbytes/s
8836 		 */
8837 		pkt_bitlen1 = len * 11;
8838 		if (pkt_bitlen1 - pkt_bitlen >= NBBY)
8839 			service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
8840 	}
8841 
8842 	plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B);
8843 	plcp->i_service = service;
8844 	plcp->i_length = htole16(len);
8845 	/* NOTE: do NOT touch i_crc */
8846 }
8847 
8848 static void
8849 bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
8850 {
8851 	enum bwi_ieee80211_modtype modtype;
8852 
8853 	/*
8854 	 * Assume caller has zeroed 'plcp'
8855 	 */
8856 
8857 	modtype = bwi_ieee80211_rate2modtype(rate);
8858 	if (modtype == IEEE80211_MODTYPE_OFDM)
8859 		bwi_ofdm_plcp_header(plcp, pkt_len, rate);
8860 	else if (modtype == IEEE80211_MODTYPE_DS)
8861 		bwi_ds_plcp_header(plcp, pkt_len, rate);
8862 	else
8863 		panic("unsupport modulation type %u\n", modtype);
8864 }
8865 
8866 static uint8_t
8867 bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate)
8868 {
8869 	const struct ieee80211_rateset *rs = &ni->ni_rates;
8870 	uint8_t ack_rate = 0;
8871 	enum bwi_ieee80211_modtype modtype;
8872 	int i;
8873 
8874 	rate &= IEEE80211_RATE_VAL;
8875 
8876 	modtype = bwi_ieee80211_rate2modtype(rate);
8877 
8878 	for (i = 0; i < rs->rs_nrates; ++i) {
8879 		uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
8880 
8881 		if (rate1 > rate) {
8882 			if (ack_rate != 0)
8883 				return (ack_rate);
8884 			else
8885 				break;
8886 		}
8887 
8888 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
8889 		    bwi_ieee80211_rate2modtype(rate1) == modtype)
8890 			ack_rate = rate1;
8891 	}
8892 
8893 	switch (rate) {
8894 	/* CCK */
8895 	case 2:
8896 	case 4:
8897 	case 11:
8898 	case 22:
8899 		ack_rate = rate;
8900 		break;
8901 	/* PBCC */
8902 	case 44:
8903 		ack_rate = 22;
8904 		break;
8905 
8906 	/* OFDM */
8907 	case 12:
8908 	case 18:
8909 		ack_rate = 12;
8910 		break;
8911 	case 24:
8912 	case 36:
8913 		ack_rate = 24;
8914 		break;
8915 	case 48:
8916 	case 72:
8917 	case 96:
8918 	case 108:
8919 		ack_rate = 48;
8920 		break;
8921 	default:
8922 		panic("unsupported rate %d\n", rate);
8923 	}
8924 	return (ack_rate);
8925 }
8926 
8927 /* [TRC: XXX does not belong here] */
8928 
8929 #define IEEE80211_OFDM_TXTIME(kbps, frmlen)	\
8930 	(IEEE80211_OFDM_PREAMBLE_TIME +		\
8931 	 IEEE80211_OFDM_SIGNAL_TIME +		\
8932 	(IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
8933 
8934 #define IEEE80211_OFDM_SYM_TIME			4
8935 #define IEEE80211_OFDM_PREAMBLE_TIME		16
8936 #define IEEE80211_OFDM_SIGNAL_EXT_TIME		6
8937 #define IEEE80211_OFDM_SIGNAL_TIME		4
8938 
8939 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS	16
8940 #define IEEE80211_OFDM_TAIL_NBITS		6
8941 
8942 #define IEEE80211_OFDM_NBITS(frmlen)		\
8943 	(IEEE80211_OFDM_PLCP_SERVICE_NBITS +	\
8944 	 ((frmlen) * NBBY) +			\
8945 	 IEEE80211_OFDM_TAIL_NBITS)
8946 
8947 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps)	\
8948 	(((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
8949 
8950 #define IEEE80211_OFDM_NSYMS(kbps, frmlen)	\
8951 	howmany(IEEE80211_OFDM_NBITS((frmlen)),	\
8952 	IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
8953 
8954 #define IEEE80211_CCK_TXTIME(kbps, frmlen)	\
8955 	(((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
8956 
8957 #define IEEE80211_CCK_PREAMBLE_LEN		144
8958 #define IEEE80211_CCK_PLCP_HDR_TIME		48
8959 #define IEEE80211_CCK_SHPREAMBLE_LEN		72
8960 #define IEEE80211_CCK_SHPLCP_HDR_TIME		24
8961 
8962 #define IEEE80211_CCK_NBITS(frmlen)		((frmlen) * NBBY)
8963 
8964 static uint16_t
8965 bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni,
8966     uint len, uint8_t rs_rate, uint32_t flags)
8967 {
8968 	enum bwi_ieee80211_modtype modtype;
8969 	uint16_t txtime;
8970 	int rate;
8971 
8972 	rs_rate &= IEEE80211_RATE_VAL;
8973 
8974 	rate = rs_rate * 500;	/* ieee80211 rate -> kbps */
8975 
8976 	modtype = bwi_ieee80211_rate2modtype(rs_rate);
8977 	if (modtype == IEEE80211_MODTYPE_OFDM) {
8978 		/*
8979 		 * IEEE Std 802.11a-1999, page 37, equation (29)
8980 		 * IEEE Std 802.11g-2003, page 44, equation (42)
8981 		 */
8982 		txtime = IEEE80211_OFDM_TXTIME(rate, len);
8983 		if (ic->ic_curmode == IEEE80211_MODE_11G)
8984 			txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
8985 	} else {
8986 		/*
8987 		 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
8988 		 * IEEE Std 802.11g-2003, page 45, equation (43)
8989 		 */
8990 		if (modtype == IEEE80211_MODTYPE_PBCC)
8991 			++len;
8992 		txtime = IEEE80211_CCK_TXTIME(rate, len);
8993 
8994 		/*
8995 		 * Short preamble is not applicable for DS 1Mbits/s
8996 		 */
8997 		if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
8998 			txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
8999 				  IEEE80211_CCK_SHPLCP_HDR_TIME;
9000 		} else {
9001 			txtime += IEEE80211_CCK_PREAMBLE_LEN +
9002 				  IEEE80211_CCK_PLCP_HDR_TIME;
9003 		}
9004 	}
9005 	return (txtime);
9006 }
9007 
9008 static int
9009 bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
9010     struct ieee80211_node **nip, int mgt_pkt)
9011 {
9012 	struct ieee80211com *ic = &sc->sc_ic;
9013 	struct ieee80211_node *ni = *nip;
9014 	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
9015 	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
9016 	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
9017 	struct bwi_mac *mac;
9018 	struct bwi_txbuf_hdr *hdr;
9019 	struct ieee80211_frame *wh;
9020 	uint8_t rate;		/* [TRC: XXX Use a fallback rate?] */
9021 	uint32_t mac_ctrl;
9022 	uint16_t phy_ctrl;
9023 	bus_addr_t paddr;
9024 	int pkt_len, error, mcast_pkt = 0;
9025 #if 0
9026 	const uint8_t *p;
9027 	int i;
9028 #endif
9029 
9030 	KASSERT(ni != NULL);
9031 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9032 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9033 
9034 	wh = mtod(m, struct ieee80211_frame *);
9035 
9036 	/* Get 802.11 frame len before prepending TX header */
9037 	pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
9038 
9039 	/*
9040 	 * Find TX rate
9041 	 */
9042 	memset(tb->tb_rate_idx, 0, sizeof(tb->tb_rate_idx));
9043 	if (!mgt_pkt) {
9044 		if (ic->ic_fixed_rate != -1) {
9045 			rate = ic->ic_sup_rates[ic->ic_curmode].
9046 			    rs_rates[ic->ic_fixed_rate];
9047 			/* [TRC: XXX Set fallback rate.] */
9048 		} else {
9049 			/* AMRR rate control */
9050 			/* [TRC: XXX amrr] */
9051 			/* rate = ni->ni_rates.rs_rates[ni->ni_txrate]; */
9052 			rate = (1 * 2);
9053 			/* [TRC: XXX Set fallback rate.] */
9054 		}
9055 	} else {
9056 		/* Fixed at 1Mbits/s for mgt frames */
9057 		/* [TRC: XXX Set fallback rate.] */
9058 		rate = (1 * 2);
9059 	}
9060 
9061 	rate &= IEEE80211_RATE_VAL;
9062 
9063 	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
9064 		/* [TRC: XXX Set fallback rate.] */
9065 		rate = ic->ic_mcast_rate;
9066 		mcast_pkt = 1;
9067 	}
9068 
9069 	/* [TRC: XXX Check fallback rate.] */
9070 	if (rate == 0) {
9071 		aprint_error_dev(sc->sc_dev, "invalid rate %u", rate);
9072 		/* [TRC: In the margin of the following line,
9073 		   DragonFlyBSD writes `Force 1Mbits/s', whereas
9074 		   OpenBSD writes `Force 1Mbytes/s'.] */
9075 		rate = (1 * 2);
9076 		/* [TRC: XXX Set fallback rate.] */
9077 	}
9078 	sc->sc_tx_rate = rate;
9079 
9080 	/* TX radio tap */
9081 	if (sc->sc_drvbpf != NULL) {
9082 		struct mbuf mb;
9083 		struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
9084 
9085 		tap->wt_flags = 0;
9086 		tap->wt_rate = rate;
9087 		tap->wt_chan_freq =
9088 		    htole16(ic->ic_bss->ni_chan->ic_freq);
9089 		tap->wt_chan_flags =
9090 		    htole16(ic->ic_bss->ni_chan->ic_flags);
9091 
9092 		mb.m_data = (void *)tap;
9093 		mb.m_len = sc->sc_txtap_len;
9094 		mb.m_next = m;
9095 		mb.m_nextpkt = NULL;
9096 		mb.m_type = 0;
9097 		mb.m_flags = 0;
9098 		bpf_ops->bpf_mtap(sc->sc_drvbpf, &mb);
9099 	}
9100 
9101 	/*
9102 	 * Setup the embedded TX header
9103 	 */
9104 	M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
9105 	if (m == NULL) {
9106 		aprint_error_dev(sc->sc_dev, "prepend TX header failed\n");
9107 		return (ENOBUFS);
9108 	}
9109 	hdr = mtod(m, struct bwi_txbuf_hdr *);
9110 
9111 	memset(hdr, 0, sizeof(*hdr));
9112 
9113 	memcpy(hdr->txh_fc, wh->i_fc, sizeof(hdr->txh_fc));
9114 	memcpy(hdr->txh_addr1, wh->i_addr1, sizeof(hdr->txh_addr1));
9115 
9116 	if (!mcast_pkt) {
9117 		uint16_t dur;
9118 		uint8_t ack_rate;
9119 
9120 		/* [TRC: XXX Set fallback rate.] */
9121 		ack_rate = bwi_ieee80211_ack_rate(ni, rate);
9122 		dur = bwi_ieee80211_txtime(ic, ni,
9123 		    sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
9124 		    ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE);
9125 
9126 		hdr->txh_fb_duration = htole16(dur);
9127 	}
9128 
9129 	hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
9130 	    __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
9131 
9132 	bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
9133 	/* [TRC: XXX Use fallback rate.] */
9134 	bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate);
9135 
9136 	phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
9137 	    BWI_TXH_PHY_C_ANTMODE_MASK);
9138 	if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9139 		phy_ctrl |= BWI_TXH_PHY_C_OFDM;
9140 	else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
9141 		phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
9142 
9143 	mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
9144 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
9145 		mac_ctrl |= BWI_TXH_MAC_C_ACK;
9146 	if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9147 		mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
9148 
9149 	hdr->txh_mac_ctrl = htole32(mac_ctrl);
9150 	hdr->txh_phy_ctrl = htole16(phy_ctrl);
9151 
9152 	/* Catch any further usage */
9153 	hdr = NULL;
9154 	wh = NULL;
9155 
9156 	/* DMA load */
9157 	error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9158 	    BUS_DMA_NOWAIT);
9159 	if (error && error != EFBIG) {
9160 		aprint_error_dev(sc->sc_dev, "can't load TX buffer (1) %d\n",
9161 		    error);
9162 		goto back;
9163 	}
9164 
9165 	if (error) {	/* error == EFBIG */
9166 		struct mbuf *m_new;
9167 
9168 		error = 0;
9169 
9170 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
9171 		if (m_new == NULL) {
9172 			m_freem(m);
9173 			error = ENOBUFS;
9174 			aprint_error_dev(sc->sc_dev,
9175 			    "can't defrag TX buffer (1)\n");
9176 			goto back;
9177 		}
9178 
9179 		M_COPY_PKTHDR(m_new, m);
9180 		if (m->m_pkthdr.len > MHLEN) {
9181 			MCLGET(m_new, M_DONTWAIT);
9182 			if (!(m_new->m_flags & M_EXT)) {
9183 				m_freem(m);
9184 				m_freem(m_new);
9185 				error = ENOBUFS;
9186 			}
9187 		}
9188 
9189 		if (error) {
9190 			aprint_error_dev(sc->sc_dev,
9191 			    "can't defrag TX buffer (2)\n");
9192 			goto back;
9193 		}
9194 
9195 		m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *));
9196 		m_freem(m);
9197 		m_new->m_len = m_new->m_pkthdr.len;
9198 		m = m_new;
9199 
9200 		error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9201 		    BUS_DMA_NOWAIT);
9202 		if (error) {
9203 			aprint_error_dev(sc->sc_dev,
9204 			    "can't load TX buffer (2) %d\n", error);
9205 			goto back;
9206 		}
9207 	}
9208 	error = 0;
9209 
9210 	bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
9211 	    tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9212 
9213 	if (mgt_pkt || mcast_pkt) {
9214 		/* Don't involve mcast/mgt packets into TX rate control */
9215 		ieee80211_free_node(ni);
9216 		*nip = ni = NULL;
9217 	}
9218 
9219 	tb->tb_mbuf = m;
9220 	tb->tb_ni = ni;
9221 
9222 #if 0
9223 	p = mtod(m, const uint8_t *);
9224 	for (i = 0; i < m->m_pkthdr.len; ++i) {
9225 		if (i % 8 == 0) {
9226 			if (i != 0)
9227 				aprint_debug("\n");
9228 			aprint_debug_dev(sc->sc_dev, "");
9229 		}
9230 		aprint_debug(" %02x", p[i]);
9231 	}
9232 	aprint_debug("\n");
9233 #endif
9234 
9235 	DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n",
9236 	    idx, pkt_len, m->m_pkthdr.len);
9237 
9238 	/* Setup TX descriptor */
9239 	paddr = tb->tb_dmap->dm_segs[0].ds_addr;
9240 	(sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len);
9241 	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
9242 	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9243 
9244 	/* Kick start */
9245 	(sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx);
9246 
9247 back:
9248 	if (error)
9249 		m_freem(m);
9250 	return (error);
9251 }
9252 
9253 static void
9254 bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9255 {
9256 	idx = (idx + 1) % BWI_TX_NDESC;
9257 	CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
9258 	    idx * sizeof(struct bwi_desc32));
9259 }
9260 
9261 static void
9262 bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9263 {
9264 	/* TODO: 64 */
9265 }
9266 
9267 static void
9268 bwi_txeof_status32(struct bwi_softc *sc)
9269 {
9270 	struct ifnet *ifp = &sc->sc_if;
9271 	uint32_t val, ctrl_base;
9272 	int end_idx;
9273 
9274 	ctrl_base = sc->sc_txstats->stats_ctrl_base;
9275 
9276 	val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
9277 	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
9278 	    sizeof(struct bwi_desc32);
9279 
9280 	bwi_txeof_status(sc, end_idx);
9281 
9282 	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
9283 	    end_idx * sizeof(struct bwi_desc32));
9284 
9285 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
9286 		ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */
9287 }
9288 
9289 static void
9290 bwi_txeof_status64(struct bwi_softc *sc)
9291 {
9292 	/* TODO: 64 */
9293 }
9294 
9295 static void
9296 _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
9297 {
9298 	struct ifnet *ifp = &sc->sc_if;
9299 	struct bwi_txbuf_data *tbd;
9300 	struct bwi_txbuf *tb;
9301 	int ring_idx, buf_idx;
9302 
9303 	if (tx_id == 0) {
9304 		/* [TRC: XXX What is the severity of this message?] */
9305 		aprint_normal_dev(sc->sc_dev, "zero tx id\n");
9306 		return;
9307 	}
9308 
9309 	ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
9310 	buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
9311 
9312 	KASSERT(ring_idx == BWI_TX_DATA_RING);
9313 	KASSERT(buf_idx < BWI_TX_NDESC);
9314 	tbd = &sc->sc_tx_bdata[ring_idx];
9315 	KASSERT(tbd->tbd_used > 0);
9316 	tbd->tbd_used--;
9317 
9318 	tb = &tbd->tbd_buf[buf_idx];
9319 
9320 	bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
9321 	m_freem(tb->tb_mbuf);
9322 	tb->tb_mbuf = NULL;
9323 
9324 	if (tb->tb_ni != NULL) {
9325 		ieee80211_free_node(tb->tb_ni);
9326 		tb->tb_ni = NULL;
9327 	}
9328 
9329 	if (tbd->tbd_used == 0)
9330 		sc->sc_tx_timer = 0;
9331 
9332 	ifp->if_flags &= ~IFF_OACTIVE;
9333 }
9334 
9335 static void
9336 bwi_txeof_status(struct bwi_softc *sc, int end_idx)
9337 {
9338 	struct bwi_txstats_data *st = sc->sc_txstats;
9339 	int idx;
9340 
9341 	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
9342 	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
9343 
9344 	idx = st->stats_idx;
9345 	while (idx != end_idx) {
9346 		/* [TRC: XXX Filter this out if it is not pending; see
9347 		   DragonFlyBSD's revision 1.5. */
9348 		/* [TRC: XXX be16toh is wrong, probably due to the
9349 		   build environment] */
9350 		_bwi_txeof(sc, be16toh(st->stats[idx].txs_id));
9351 		idx = (idx + 1) % BWI_TXSTATS_NDESC;
9352 	}
9353 	st->stats_idx = idx;
9354 }
9355 
9356 static void
9357 bwi_txeof(struct bwi_softc *sc)
9358 {
9359 	struct ifnet *ifp = &sc->sc_if;
9360 
9361 	for (;;) {
9362 		uint32_t tx_status0, tx_status1;
9363 		uint16_t tx_id, tx_info;
9364 
9365 		tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
9366 		if (tx_status0 == 0)
9367 			break;
9368 		tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1);
9369 
9370 		tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
9371 		tx_info = BWI_TXSTATUS_0_INFO(tx_status0);
9372 
9373 		if (tx_info & 0x30) /* XXX */
9374 			continue;
9375 
9376 		_bwi_txeof(sc, le16toh(tx_id));
9377 
9378 		ifp->if_opackets++;
9379 	}
9380 
9381 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
9382 		ifp->if_start(ifp);
9383 }
9384 
9385 static int
9386 bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
9387 {
9388 	bwi_power_on(sc, 1);
9389 
9390 	return (bwi_set_clock_mode(sc, clk_mode));
9391 }
9392 
9393 static void
9394 bwi_bbp_power_off(struct bwi_softc *sc)
9395 {
9396 	bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
9397 	bwi_power_off(sc, 1);
9398 }
9399 
9400 static int
9401 bwi_get_pwron_delay(struct bwi_softc *sc)
9402 {
9403 	struct bwi_regwin *com, *old;
9404 	struct bwi_clock_freq freq;
9405 	uint32_t val;
9406 	int error;
9407 
9408 	com = &sc->sc_com_regwin;
9409 	KASSERT(BWI_REGWIN_EXIST(com));
9410 
9411 	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
9412 		return (0);
9413 
9414 	error = bwi_regwin_switch(sc, com, &old);
9415 	if (error)
9416 		return (error);
9417 
9418 	bwi_get_clock_freq(sc, &freq);
9419 
9420 	val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
9421 	sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
9422 	DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay);
9423 
9424 	return (bwi_regwin_switch(sc, old, NULL));
9425 }
9426 
9427 static int
9428 bwi_bus_attach(struct bwi_softc *sc)
9429 {
9430 	struct bwi_regwin *bus, *old;
9431 	int error;
9432 
9433 	bus = &sc->sc_bus_regwin;
9434 
9435 	error = bwi_regwin_switch(sc, bus, &old);
9436 	if (error)
9437 		return (error);
9438 
9439 	if (!bwi_regwin_is_enabled(sc, bus))
9440 		bwi_regwin_enable(sc, bus, 0);
9441 
9442 	/* Disable interripts */
9443 	CSR_WRITE_4(sc, BWI_INTRVEC, 0);
9444 
9445 	return (bwi_regwin_switch(sc, old, NULL));
9446 }
9447 
9448 static const char *
9449 bwi_regwin_name(const struct bwi_regwin *rw)
9450 {
9451 	switch (rw->rw_type) {
9452 	case BWI_REGWIN_T_COM:
9453 		return ("COM");
9454 	case BWI_REGWIN_T_BUSPCI:
9455 		return ("PCI");
9456 	case BWI_REGWIN_T_MAC:
9457 		return ("MAC");
9458 	case BWI_REGWIN_T_BUSPCIE:
9459 		return ("PCIE");
9460 	}
9461 	panic("unknown regwin type 0x%04x\n", rw->rw_type);
9462 
9463 	return (NULL);
9464 }
9465 
9466 static uint32_t
9467 bwi_regwin_disable_bits(struct bwi_softc *sc)
9468 {
9469 	uint32_t busrev;
9470 
9471 	/* XXX cache this */
9472 	busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
9473 	DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC,
9474 	    "bus rev %u\n", busrev);
9475 
9476 	if (busrev == BWI_BUSREV_0)
9477 		return (BWI_STATE_LO_DISABLE1);
9478 	else if (busrev == BWI_BUSREV_1)
9479 		return (BWI_STATE_LO_DISABLE2);
9480 	else
9481 		return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2);
9482 }
9483 
9484 static int
9485 bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
9486 {
9487 	uint32_t val, disable_bits;
9488 
9489 	disable_bits = bwi_regwin_disable_bits(sc);
9490 	val = CSR_READ_4(sc, BWI_STATE_LO);
9491 
9492 	if ((val & (BWI_STATE_LO_CLOCK |
9493 		    BWI_STATE_LO_RESET |
9494 		    disable_bits)) == BWI_STATE_LO_CLOCK) {
9495 		DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n",
9496 		    bwi_regwin_name(rw));
9497 		return (1);
9498 	} else {
9499 		DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n",
9500 		    bwi_regwin_name(rw));
9501 		return (0);
9502 	}
9503 }
9504 
9505 static void
9506 bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9507 {
9508 	uint32_t state_lo, disable_bits;
9509 	int i;
9510 
9511 	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9512 
9513 	/*
9514 	 * If current regwin is in 'reset' state, it was already disabled.
9515 	 */
9516 	if (state_lo & BWI_STATE_LO_RESET) {
9517 		DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT,
9518 		    "%s was already disabled\n", bwi_regwin_name(rw));
9519 		return;
9520 	}
9521 
9522 	disable_bits = bwi_regwin_disable_bits(sc);
9523 
9524 	/*
9525 	 * Disable normal clock
9526 	 */
9527 	state_lo = BWI_STATE_LO_CLOCK | disable_bits;
9528 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9529 
9530 	/*
9531 	 * Wait until normal clock is disabled
9532 	 */
9533 #define NRETRY	1000
9534 	for (i = 0; i < NRETRY; ++i) {
9535 		state_lo = CSR_READ_4(sc, BWI_STATE_LO);
9536 		if (state_lo & disable_bits)
9537 			break;
9538 		DELAY(10);
9539 	}
9540 	if (i == NRETRY) {
9541 		aprint_error_dev(sc->sc_dev, "%s disable clock timeout\n",
9542 		    bwi_regwin_name(rw));
9543 	}
9544 
9545 	for (i = 0; i < NRETRY; ++i) {
9546 		uint32_t state_hi;
9547 
9548 		state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9549 		if ((state_hi & BWI_STATE_HI_BUSY) == 0)
9550 			break;
9551 		DELAY(10);
9552 	}
9553 	if (i == NRETRY) {
9554 		aprint_error_dev(sc->sc_dev, "%s wait BUSY unset timeout\n",
9555 		    bwi_regwin_name(rw));
9556 	}
9557 #undef NRETRY
9558 
9559 	/*
9560 	 * Reset and disable regwin with gated clock
9561 	 */
9562 	state_lo = BWI_STATE_LO_RESET | disable_bits |
9563 	    BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
9564 	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9565 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9566 
9567 	/* Flush pending bus write */
9568 	CSR_READ_4(sc, BWI_STATE_LO);
9569 	DELAY(1);
9570 
9571 	/* Reset and disable regwin */
9572 	state_lo = BWI_STATE_LO_RESET | disable_bits |
9573 		   __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9574 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9575 
9576 	/* Flush pending bus write */
9577 	CSR_READ_4(sc, BWI_STATE_LO);
9578 	DELAY(1);
9579 }
9580 
9581 static void
9582 bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9583 {
9584 	uint32_t state_lo, state_hi, imstate;
9585 
9586 	bwi_regwin_disable(sc, rw, flags);
9587 
9588 	/* Reset regwin with gated clock */
9589 	state_lo = BWI_STATE_LO_RESET |
9590 	    BWI_STATE_LO_CLOCK |
9591 	    BWI_STATE_LO_GATED_CLOCK |
9592 	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9593 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9594 
9595 	/* Flush pending bus write */
9596 	CSR_READ_4(sc, BWI_STATE_LO);
9597 	DELAY(1);
9598 
9599 	state_hi = CSR_READ_4(sc, BWI_STATE_HI);
9600 	if (state_hi & BWI_STATE_HI_SERROR)
9601 		CSR_WRITE_4(sc, BWI_STATE_HI, 0);
9602 
9603 	imstate = CSR_READ_4(sc, BWI_IMSTATE);
9604 	if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
9605 		imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
9606 		CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
9607 	}
9608 
9609 	/* Enable regwin with gated clock */
9610 	state_lo = BWI_STATE_LO_CLOCK |
9611 	    BWI_STATE_LO_GATED_CLOCK |
9612 	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9613 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9614 
9615 	/* Flush pending bus write */
9616 	CSR_READ_4(sc, BWI_STATE_LO);
9617 	DELAY(1);
9618 
9619 	/* Enable regwin with normal clock */
9620 	state_lo = BWI_STATE_LO_CLOCK |
9621 	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
9622 	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
9623 
9624 	/* Flush pending bus write */
9625 	CSR_READ_4(sc, BWI_STATE_LO);
9626 	DELAY(1);
9627 }
9628 
9629 static void
9630 bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
9631 {
9632 	struct ieee80211com *ic = &sc->sc_ic;
9633 	struct bwi_mac *mac;
9634 	struct bwi_myaddr_bssid buf;
9635 	const uint8_t *p;
9636 	uint32_t val;
9637 	int n, i;
9638 
9639 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9640 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9641 
9642 	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
9643 
9644 	memcpy(buf.myaddr, ic->ic_myaddr, sizeof(buf.myaddr));
9645 	memcpy(buf.bssid, bssid, sizeof(buf.bssid));
9646 
9647 	n = sizeof(buf) / sizeof(val);
9648 	p = (const uint8_t *)&buf;
9649 	for (i = 0; i < n; ++i) {
9650 		int j;
9651 
9652 		val = 0;
9653 		for (j = 0; j < sizeof(val); ++j)
9654 			val |= ((uint32_t)(*p++)) << (j * 8);
9655 
9656 		TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
9657 	}
9658 }
9659 
9660 static void
9661 bwi_updateslot(struct ifnet *ifp)
9662 {
9663 	struct bwi_softc *sc = ifp->if_softc;
9664 	struct ieee80211com *ic = &sc->sc_ic;
9665 	struct bwi_mac *mac;
9666 
9667 	if ((ifp->if_flags & IFF_RUNNING) == 0)
9668 		return;
9669 
9670 	DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
9671 
9672 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9673 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9674 
9675 	bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
9676 }
9677 
9678 static void
9679 bwi_calibrate(void *xsc)
9680 {
9681 	struct bwi_softc *sc = xsc;
9682 	struct ieee80211com *ic = &sc->sc_ic;
9683 	int s;
9684 
9685 	s = splnet();
9686 
9687 	if (ic->ic_state == IEEE80211_S_RUN) {
9688 		struct bwi_mac *mac;
9689 
9690 		KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9691 		mac = (struct bwi_mac *)sc->sc_cur_regwin;
9692 
9693 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
9694 			bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
9695 			sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
9696 		}
9697 
9698 		/* XXX 15 seconds */
9699 		callout_schedule(&sc->sc_calib_ch, hz * 15);
9700 	}
9701 
9702 	splx(s);
9703 }
9704 
9705 static int
9706 bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
9707 {
9708 	struct bwi_mac *mac;
9709 
9710 	KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9711 	mac = (struct bwi_mac *)sc->sc_cur_regwin;
9712 
9713 	return (bwi_rf_calc_rssi(mac, hdr));
9714 }
9715 
9716 bool
9717 bwi_suspend(device_t dv, pmf_qual_t qual)
9718 {
9719 	struct bwi_softc *sc = device_private(dv);
9720 
9721 	bwi_power_off(sc, 0);
9722 
9723 	return true;
9724 }
9725 
9726 bool
9727 bwi_resume(device_t dv, pmf_qual_t qual)
9728 {
9729 	struct bwi_softc *sc = device_private(dv);
9730 
9731 	bwi_power_on(sc, 1);
9732 
9733 	return true;
9734 }
9735