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