xref: /dragonfly/sys/dev/netif/bwn/bwn/if_bwn.c (revision f2c43266)
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD: head/sys/dev/bwn/if_bwn.c 260444 2014-01-08 08:06:56Z kevlo $");
32 
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36 
37 #include <opt_wlan.h>
38 #include <opt_bwn.h>
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/module.h>
43 #include <sys/kernel.h>
44 #include <sys/endian.h>
45 #include <sys/errno.h>
46 #include <sys/firmware.h>
47 #include <sys/bus_resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52 
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/ifq_var.h>
62 
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcireg.h>
65 #include <dev/netif/bwn/siba/siba_ids.h>
66 #include <dev/netif/bwn/siba/sibareg.h>
67 #include <dev/netif/bwn/siba/sibavar.h>
68 
69 #include <netproto/802_11/ieee80211_var.h>
70 #include <netproto/802_11/ieee80211_radiotap.h>
71 #include <netproto/802_11/ieee80211_regdomain.h>
72 #include <netproto/802_11/ieee80211_phy.h>
73 #include <netproto/802_11/ieee80211_ratectl.h>
74 
75 #include "if_bwnreg.h"
76 #include "if_bwnvar.h"
77 
78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
79     "Broadcom driver parameters");
80 
81 /*
82  * Tunable & sysctl variables.
83  */
84 
85 #ifdef BWN_DEBUG
86 static	int bwn_debug = 0;
87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
88     "Broadcom debugging printfs");
89 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
90 enum {
91 	BWN_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
92 	BWN_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
93 	BWN_DEBUG_STATE		= 0x00000004,	/* 802.11 state transitions */
94 	BWN_DEBUG_TXPOW		= 0x00000008,	/* tx power processing */
95 	BWN_DEBUG_RESET		= 0x00000010,	/* reset processing */
96 	BWN_DEBUG_OPS		= 0x00000020,	/* bwn_ops processing */
97 	BWN_DEBUG_BEACON	= 0x00000040,	/* beacon handling */
98 	BWN_DEBUG_WATCHDOG	= 0x00000080,	/* watchdog timeout */
99 	BWN_DEBUG_INTR		= 0x00000100,	/* ISR */
100 	BWN_DEBUG_CALIBRATE	= 0x00000200,	/* periodic calibration */
101 	BWN_DEBUG_NODE		= 0x00000400,	/* node management */
102 	BWN_DEBUG_LED		= 0x00000800,	/* led management */
103 	BWN_DEBUG_CMD		= 0x00001000,	/* cmd submission */
104 	BWN_DEBUG_LO		= 0x00002000,	/* LO */
105 	BWN_DEBUG_FW		= 0x00004000,	/* firmware */
106 	BWN_DEBUG_WME		= 0x00008000,	/* WME */
107 	BWN_DEBUG_RF		= 0x00010000,	/* RF */
108 	BWN_DEBUG_FATAL		= 0x80000000,	/* fatal errors */
109 	BWN_DEBUG_ANY		= 0xffffffff
110 };
111 #define	DPRINTF(sc, m, fmt, ...) do {			\
112 	if (sc->sc_debug & (m))				\
113 		kprintf(fmt, __VA_ARGS__);		\
114 } while (0)
115 #else
116 #define	DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
117 #endif
118 
119 static int	bwn_bfp = 0;		/* use "Bad Frames Preemption" */
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
121     "uses Bad Frames Preemption");
122 static int	bwn_bluetooth = 1;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
124     "turns on Bluetooth Coexistence");
125 static int	bwn_hwpctl = 0;
126 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
127     "uses H/W power control");
128 static int      bwn_msi_enable = 1;
129 TUNABLE_INT("hw.bwn.msi.enable", &bwn_msi_enable);
130 static int	bwn_usedma = 1;
131 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
132     "uses DMA");
133 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
134 static int	bwn_wme = 1;
135 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
136     "uses WME support");
137 
138 static int	bwn_attach_pre(struct bwn_softc *);
139 static int	bwn_attach_post(struct bwn_softc *);
140 static void	bwn_sprom_bugfixes(device_t);
141 static void	bwn_init(void *);
142 static int	bwn_init_locked(struct bwn_softc *);
143 static int	bwn_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
144 static void	bwn_start(struct ifnet *, struct ifaltq_subque *);
145 static int	bwn_attach_core(struct bwn_mac *);
146 static void	bwn_reset_core(struct bwn_mac *, uint32_t);
147 static int	bwn_phy_getinfo(struct bwn_mac *, int);
148 static int	bwn_chiptest(struct bwn_mac *);
149 static int	bwn_setup_channels(struct bwn_mac *, int, int);
150 static int	bwn_phy_g_attach(struct bwn_mac *);
151 static void	bwn_phy_g_detach(struct bwn_mac *);
152 static void	bwn_phy_g_init_pre(struct bwn_mac *);
153 static int	bwn_phy_g_prepare_hw(struct bwn_mac *);
154 static int	bwn_phy_g_init(struct bwn_mac *);
155 static void	bwn_phy_g_exit(struct bwn_mac *);
156 static uint16_t	bwn_phy_g_read(struct bwn_mac *, uint16_t);
157 static void	bwn_phy_g_write(struct bwn_mac *, uint16_t,
158 		    uint16_t);
159 static uint16_t	bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
160 static void	bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
161 		    uint16_t);
162 static int	bwn_phy_g_hwpctl(struct bwn_mac *);
163 static void	bwn_phy_g_rf_onoff(struct bwn_mac *, int);
164 static int	bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
165 static uint32_t	bwn_phy_g_get_default_chan(struct bwn_mac *);
166 static void	bwn_phy_g_set_antenna(struct bwn_mac *, int);
167 static int	bwn_phy_g_im(struct bwn_mac *, int);
168 static int	bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
169 static void	bwn_phy_g_set_txpwr(struct bwn_mac *);
170 static void	bwn_phy_g_task_15s(struct bwn_mac *);
171 static void	bwn_phy_g_task_60s(struct bwn_mac *);
172 static uint16_t	bwn_phy_g_txctl(struct bwn_mac *);
173 static void	bwn_phy_switch_analog(struct bwn_mac *, int);
174 static uint16_t	bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
175 static void	bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
176 		    uint16_t);
177 static uint32_t	bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
178 static void	bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
179 		    uint32_t);
180 static void	bwn_shm_ctlword(struct bwn_mac *, uint16_t,
181 		    uint16_t);
182 static void	bwn_addchannels(struct ieee80211_channel [], int, int *,
183 		    const struct bwn_channelinfo *, int);
184 static int	bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
185 		    const struct ieee80211_bpf_params *);
186 static void	bwn_updateslot(struct ieee80211com *);
187 static void	bwn_update_promisc(struct ieee80211com *);
188 static void	bwn_wme_init(struct bwn_mac *);
189 static int	bwn_wme_update(struct ieee80211com *);
190 static void	bwn_wme_clear(struct bwn_softc *);
191 static void	bwn_wme_load(struct bwn_mac *);
192 static void	bwn_wme_loadparams(struct bwn_mac *,
193 		    const struct wmeParams *, uint16_t);
194 static void	bwn_scan_start(struct ieee80211com *);
195 static void	bwn_scan_end(struct ieee80211com *);
196 static void	bwn_set_channel(struct ieee80211com *);
197 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
198 		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
199 		    const uint8_t [IEEE80211_ADDR_LEN],
200 		    const uint8_t [IEEE80211_ADDR_LEN]);
201 static void	bwn_vap_delete(struct ieee80211vap *);
202 static void	bwn_stop(struct bwn_softc *, int);
203 static void	bwn_stop_locked(struct bwn_softc *, int);
204 static int	bwn_core_init(struct bwn_mac *);
205 static void	bwn_core_start(struct bwn_mac *);
206 static void	bwn_core_exit(struct bwn_mac *);
207 static void	bwn_bt_disable(struct bwn_mac *);
208 static int	bwn_chip_init(struct bwn_mac *);
209 static uint64_t	bwn_hf_read(struct bwn_mac *);
210 static void	bwn_hf_write(struct bwn_mac *, uint64_t);
211 static void	bwn_set_txretry(struct bwn_mac *, int, int);
212 static void	bwn_rate_init(struct bwn_mac *);
213 static void	bwn_set_phytxctl(struct bwn_mac *);
214 static void	bwn_spu_setdelay(struct bwn_mac *, int);
215 static void	bwn_bt_enable(struct bwn_mac *);
216 static void	bwn_set_macaddr(struct bwn_mac *);
217 static void	bwn_crypt_init(struct bwn_mac *);
218 static void	bwn_chip_exit(struct bwn_mac *);
219 static int	bwn_fw_fillinfo(struct bwn_mac *);
220 static int	bwn_fw_loaducode(struct bwn_mac *);
221 static int	bwn_gpio_init(struct bwn_mac *);
222 static int	bwn_fw_loadinitvals(struct bwn_mac *);
223 static int	bwn_phy_init(struct bwn_mac *);
224 static void	bwn_set_txantenna(struct bwn_mac *, int);
225 static void	bwn_set_opmode(struct bwn_mac *);
226 static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
227 static uint8_t	bwn_plcp_getcck(const uint8_t);
228 static uint8_t	bwn_plcp_getofdm(const uint8_t);
229 static void	bwn_pio_init(struct bwn_mac *);
230 static uint16_t	bwn_pio_idx2base(struct bwn_mac *, int);
231 static void	bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
232 		    int);
233 static void	bwn_pio_setupqueue_rx(struct bwn_mac *,
234 		    struct bwn_pio_rxqueue *, int);
235 static void	bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
236 static uint16_t	bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
237 		    uint16_t);
238 static void	bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
239 static int	bwn_pio_rx(struct bwn_pio_rxqueue *);
240 static uint8_t	bwn_pio_rxeof(struct bwn_pio_rxqueue *);
241 static void	bwn_pio_handle_txeof(struct bwn_mac *,
242 		    const struct bwn_txstatus *);
243 static uint16_t	bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
244 static uint32_t	bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
245 static void	bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
246 		    uint16_t);
247 static void	bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
248 		    uint32_t);
249 static int	bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
250 		    struct mbuf *);
251 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
252 static uint32_t	bwn_pio_write_multi_4(struct bwn_mac *,
253 		    struct bwn_pio_txqueue *, uint32_t, const void *, int);
254 static void	bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
255 		    uint16_t, uint32_t);
256 static uint16_t	bwn_pio_write_multi_2(struct bwn_mac *,
257 		    struct bwn_pio_txqueue *, uint16_t, const void *, int);
258 static uint16_t	bwn_pio_write_mbuf_2(struct bwn_mac *,
259 		    struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
260 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
261 		    uint16_t, struct bwn_pio_txpkt **);
262 static void	bwn_dma_init(struct bwn_mac *);
263 static void	bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
264 static int	bwn_dma_mask2type(uint64_t);
265 static uint64_t	bwn_dma_mask(struct bwn_mac *);
266 static uint16_t	bwn_dma_base(int, int);
267 static void	bwn_dma_ringfree(struct bwn_dma_ring **);
268 static void	bwn_dma_32_getdesc(struct bwn_dma_ring *,
269 		    int, struct bwn_dmadesc_generic **,
270 		    struct bwn_dmadesc_meta **);
271 static void	bwn_dma_32_setdesc(struct bwn_dma_ring *,
272 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
273 		    int, int);
274 static void	bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
275 static void	bwn_dma_32_suspend(struct bwn_dma_ring *);
276 static void	bwn_dma_32_resume(struct bwn_dma_ring *);
277 static int	bwn_dma_32_get_curslot(struct bwn_dma_ring *);
278 static void	bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
279 static void	bwn_dma_64_getdesc(struct bwn_dma_ring *,
280 		    int, struct bwn_dmadesc_generic **,
281 		    struct bwn_dmadesc_meta **);
282 static void	bwn_dma_64_setdesc(struct bwn_dma_ring *,
283 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
284 		    int, int);
285 static void	bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
286 static void	bwn_dma_64_suspend(struct bwn_dma_ring *);
287 static void	bwn_dma_64_resume(struct bwn_dma_ring *);
288 static int	bwn_dma_64_get_curslot(struct bwn_dma_ring *);
289 static void	bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
290 static int	bwn_dma_allocringmemory(struct bwn_dma_ring *);
291 static void	bwn_dma_setup(struct bwn_dma_ring *);
292 static void	bwn_dma_free_ringmemory(struct bwn_dma_ring *);
293 static void	bwn_dma_cleanup(struct bwn_dma_ring *);
294 static void	bwn_dma_free_descbufs(struct bwn_dma_ring *);
295 static int	bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
296 static void	bwn_dma_rx_handle_overflow(struct bwn_dma_ring *);
297 static void	bwn_dma_rx(struct bwn_dma_ring *);
298 static int	bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
299 static void	bwn_dma_free_descbuf(struct bwn_dma_ring *,
300 		    struct bwn_dmadesc_meta *);
301 static void	bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
302 static int	bwn_dma_gettype(struct bwn_mac *);
303 static void	bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
304 static int	bwn_dma_freeslot(struct bwn_dma_ring *);
305 static int	bwn_dma_nextslot(struct bwn_dma_ring *, int);
306 static void	bwn_dma_rxeof(struct bwn_dma_ring *, int *);
307 static int	bwn_dma_newbuf(struct bwn_dma_ring *,
308 		    struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
309 		    int);
310 static void	bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
311 		    bus_size_t, int);
312 static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
313 static void	bwn_dma_handle_txeof(struct bwn_mac *,
314 		    const struct bwn_txstatus *);
315 static int	bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
316 		    struct mbuf *);
317 static int	bwn_dma_getslot(struct bwn_dma_ring *);
318 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
319 		    uint8_t);
320 static int	bwn_dma_attach(struct bwn_mac *);
321 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
322 		    int, int, int);
323 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
324 		    const struct bwn_txstatus *, uint16_t, int *);
325 static void	bwn_dma_free(struct bwn_mac *);
326 static void	bwn_phy_g_init_sub(struct bwn_mac *);
327 static uint8_t	bwn_has_hwpctl(struct bwn_mac *);
328 static void	bwn_phy_init_b5(struct bwn_mac *);
329 static void	bwn_phy_init_b6(struct bwn_mac *);
330 static void	bwn_phy_init_a(struct bwn_mac *);
331 static void	bwn_loopback_calcgain(struct bwn_mac *);
332 static uint16_t	bwn_rf_init_bcm2050(struct bwn_mac *);
333 static void	bwn_lo_g_init(struct bwn_mac *);
334 static void	bwn_lo_g_adjust(struct bwn_mac *);
335 static void	bwn_lo_get_powervector(struct bwn_mac *);
336 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
337 		    const struct bwn_bbatt *, const struct bwn_rfatt *);
338 static void	bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
339 static void	bwn_phy_hwpctl_init(struct bwn_mac *);
340 static void	bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
341 static void	bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
342 		    const struct bwn_bbatt *, const struct bwn_rfatt *,
343 		    uint8_t);
344 static void	bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
345 static uint16_t	bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
346 static void	bwn_spu_workaround(struct bwn_mac *, uint8_t);
347 static void	bwn_wa_init(struct bwn_mac *);
348 static void	bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
349 		    uint16_t);
350 static void	bwn_dummy_transmission(struct bwn_mac *, int, int);
351 static void	bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
352 		    uint32_t);
353 static void	bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
354 		    uint16_t);
355 static void	bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
356 static void	bwn_mac_suspend(struct bwn_mac *);
357 static void	bwn_mac_enable(struct bwn_mac *);
358 static void	bwn_psctl(struct bwn_mac *, uint32_t);
359 static int16_t	bwn_nrssi_read(struct bwn_mac *, uint16_t);
360 static void	bwn_nrssi_offset(struct bwn_mac *);
361 static void	bwn_nrssi_threshold(struct bwn_mac *);
362 static void	bwn_nrssi_slope_11g(struct bwn_mac *);
363 static void	bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
364 		    int16_t);
365 static void	bwn_set_original_gains(struct bwn_mac *);
366 static void	bwn_hwpctl_early_init(struct bwn_mac *);
367 static void	bwn_hwpctl_init_gphy(struct bwn_mac *);
368 static uint16_t	bwn_phy_g_chan2freq(uint8_t);
369 static int	bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
370 static int	bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
371 		    const char *, struct bwn_fwfile *);
372 static void	bwn_release_firmware(struct bwn_mac *);
373 static void	bwn_do_release_fw(struct bwn_fwfile *);
374 static uint16_t	bwn_fwcaps_read(struct bwn_mac *);
375 static int	bwn_fwinitvals_write(struct bwn_mac *,
376 		    const struct bwn_fwinitvals *, size_t, size_t);
377 static int	bwn_switch_channel(struct bwn_mac *, int);
378 static uint16_t	bwn_ant2phy(int);
379 static void	bwn_mac_write_bssid(struct bwn_mac *);
380 static void	bwn_mac_setfilter(struct bwn_mac *, uint16_t,
381 		    const uint8_t *);
382 static void	bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
383 		    const uint8_t *, size_t, const uint8_t *);
384 static void	bwn_key_macwrite(struct bwn_mac *, uint8_t,
385 		    const uint8_t *);
386 static void	bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
387 		    const uint8_t *);
388 static void	bwn_phy_exit(struct bwn_mac *);
389 static void	bwn_core_stop(struct bwn_mac *);
390 static int	bwn_switch_band(struct bwn_softc *,
391 		    struct ieee80211_channel *);
392 static void	bwn_phy_reset(struct bwn_mac *);
393 static int	bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
394 static void	bwn_set_pretbtt(struct bwn_mac *);
395 static void	bwn_intr(void *);
396 static void	bwn_intrtask(void *, int);
397 static void	bwn_restart(struct bwn_mac *, const char *);
398 static void	bwn_intr_ucode_debug(struct bwn_mac *);
399 static void	bwn_intr_tbtt_indication(struct bwn_mac *);
400 static void	bwn_intr_atim_end(struct bwn_mac *);
401 static void	bwn_intr_beacon(struct bwn_mac *);
402 static void	bwn_intr_pmq(struct bwn_mac *);
403 static void	bwn_intr_noise(struct bwn_mac *);
404 static void	bwn_intr_txeof(struct bwn_mac *);
405 static void	bwn_hwreset(void *, int);
406 static void	bwn_handle_fwpanic(struct bwn_mac *);
407 static void	bwn_load_beacon0(struct bwn_mac *);
408 static void	bwn_load_beacon1(struct bwn_mac *);
409 static uint32_t	bwn_jssi_read(struct bwn_mac *);
410 static void	bwn_noise_gensample(struct bwn_mac *);
411 static void	bwn_handle_txeof(struct bwn_mac *,
412 		    const struct bwn_txstatus *);
413 static void	bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
414 static void	bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
415 static void	bwn_start_locked(struct ifnet *);
416 static int	bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
417 		    struct mbuf *);
418 static int	bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
419 static int	bwn_set_txhdr(struct bwn_mac *,
420 		    struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
421 		    uint16_t);
422 static void	bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
423 		    const uint8_t);
424 static uint8_t	bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
425 static uint8_t	bwn_get_fbrate(uint8_t);
426 static int	bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
427 static void	bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
428 static void	bwn_phy_lock(struct bwn_mac *);
429 static void	bwn_phy_unlock(struct bwn_mac *);
430 static void	bwn_rf_lock(struct bwn_mac *);
431 static void	bwn_rf_unlock(struct bwn_mac *);
432 static void	bwn_txpwr(void *, int);
433 static void	bwn_tasks(void *);
434 static void	bwn_task_15s(struct bwn_mac *);
435 static void	bwn_task_30s(struct bwn_mac *);
436 static void	bwn_task_60s(struct bwn_mac *);
437 static int	bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
438 		    uint8_t);
439 static int	bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
440 static void	bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
441 		    const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
442 		    int, int);
443 static void	bwn_tsf_read(struct bwn_mac *, uint64_t *);
444 static void	bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
445 static void	bwn_set_slot_time(struct bwn_mac *, uint16_t);
446 static void	bwn_watchdog(void *);
447 static void	bwn_dma_stop(struct bwn_mac *);
448 static void	bwn_pio_stop(struct bwn_mac *);
449 static void	bwn_dma_ringstop(struct bwn_dma_ring **);
450 static void	bwn_led_attach(struct bwn_mac *);
451 static void	bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
452 static void	bwn_led_event(struct bwn_mac *, int);
453 static void	bwn_led_blink_start(struct bwn_mac *, int, int);
454 static void	bwn_led_blink_next(void *);
455 static void	bwn_led_blink_end(void *);
456 static void	bwn_rfswitch(void *);
457 static void	bwn_rf_turnon(struct bwn_mac *);
458 static void	bwn_rf_turnoff(struct bwn_mac *);
459 static void	bwn_phy_lp_init_pre(struct bwn_mac *);
460 static int	bwn_phy_lp_init(struct bwn_mac *);
461 static uint16_t	bwn_phy_lp_read(struct bwn_mac *, uint16_t);
462 static void	bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void	bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
464 		    uint16_t);
465 static uint16_t	bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
466 static void	bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
467 static void	bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
468 static int	bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
469 static uint32_t	bwn_phy_lp_get_default_chan(struct bwn_mac *);
470 static void	bwn_phy_lp_set_antenna(struct bwn_mac *, int);
471 static void	bwn_phy_lp_task_60s(struct bwn_mac *);
472 static void	bwn_phy_lp_readsprom(struct bwn_mac *);
473 static void	bwn_phy_lp_bbinit(struct bwn_mac *);
474 static void	bwn_phy_lp_txpctl_init(struct bwn_mac *);
475 static void	bwn_phy_lp_calib(struct bwn_mac *);
476 static void	bwn_phy_lp_switch_analog(struct bwn_mac *, int);
477 static int	bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
478 static int	bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
479 static void	bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
480 static void	bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
481 static void	bwn_phy_lp_digflt_save(struct bwn_mac *);
482 static void	bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
483 static void	bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
484 static void	bwn_phy_lp_bugfix(struct bwn_mac *);
485 static void	bwn_phy_lp_digflt_restore(struct bwn_mac *);
486 static void	bwn_phy_lp_tblinit(struct bwn_mac *);
487 static void	bwn_phy_lp_bbinit_r2(struct bwn_mac *);
488 static void	bwn_phy_lp_bbinit_r01(struct bwn_mac *);
489 static void	bwn_phy_lp_b2062_init(struct bwn_mac *);
490 static void	bwn_phy_lp_b2063_init(struct bwn_mac *);
491 static void	bwn_phy_lp_rxcal_r2(struct bwn_mac *);
492 static void	bwn_phy_lp_rccal_r12(struct bwn_mac *);
493 static void	bwn_phy_lp_set_rccap(struct bwn_mac *);
494 static uint32_t	bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
495 static void	bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
496 static void	bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
497 static void	bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
498 		    const void *);
499 static void	bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
500 static struct bwn_txgain
501 		bwn_phy_lp_get_txgain(struct bwn_mac *);
502 static uint8_t	bwn_phy_lp_get_bbmult(struct bwn_mac *);
503 static void	bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
504 static void	bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
505 static void	bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
506 static void	bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
507 static void	bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
508 static int	bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
509 static void	bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
510 static void	bwn_phy_lp_tblinit_r01(struct bwn_mac *);
511 static void	bwn_phy_lp_tblinit_r2(struct bwn_mac *);
512 static void	bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
513 static void	bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
514 static void	bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
515 static void	bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
516 static int	bwn_phy_lp_loopback(struct bwn_mac *);
517 static void	bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
518 static void	bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
519 		    int);
520 static uint8_t	bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
521 		    struct bwn_phy_lp_iq_est *);
522 static void	bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
523 static uint32_t	bwn_tab_read(struct bwn_mac *, uint32_t);
524 static void	bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
525 static void	bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
526 static void	bwn_phy_lp_set_txgain_override(struct bwn_mac *);
527 static uint16_t	bwn_phy_lp_get_pa_gain(struct bwn_mac *);
528 static uint8_t	bwn_nbits(int32_t);
529 static void	bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
530 		    struct bwn_txgain_entry *);
531 static void	bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
532 		    struct bwn_txgain_entry);
533 static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
534 		    struct bwn_txgain_entry);
535 static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
536 		    struct bwn_txgain_entry);
537 static void	bwn_sysctl_node(struct bwn_softc *);
538 
539 static const struct bwn_channelinfo bwn_chantable_bg = {
540 	.channels = {
541 		{ 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
542 		{ 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
543 		{ 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
544 		{ 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
545 		{ 2472, 13, 30 }, { 2484, 14, 30 } },
546 	.nchannels = 14
547 };
548 
549 static const struct bwn_channelinfo bwn_chantable_a = {
550 	.channels = {
551 		{ 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
552 		{ 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
553 		{ 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
554 		{ 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
555 		{ 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
556 		{ 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
557 		{ 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
558 		{ 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
559 		{ 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
560 		{ 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
561 		{ 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
562 		{ 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
563 		{ 6080, 216, 30 } },
564 	.nchannels = 37
565 };
566 
567 static const struct bwn_channelinfo bwn_chantable_n = {
568 	.channels = {
569 		{ 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
570 		{ 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
571 		{ 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
572 		{ 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
573 		{ 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
574 		{ 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
575 		{ 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
576 		{ 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
577 		{ 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
578 		{ 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
579 		{ 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
580 		{ 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
581 		{ 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
582 		{ 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
583 		{ 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
584 		{ 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
585 		{ 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
586 		{ 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
587 		{ 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
588 		{ 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
589 		{ 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
590 		{ 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
591 		{ 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
592 		{ 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
593 		{ 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
594 		{ 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
595 		{ 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
596 		{ 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
597 		{ 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
598 		{ 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
599 		{ 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
600 		{ 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
601 		{ 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
602 		{ 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
603 		{ 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
604 		{ 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
605 		{ 6130, 226, 30 }, { 6140, 228, 30 } },
606 	.nchannels = 110
607 };
608 
609 static const uint8_t bwn_b2063_chantable_data[33][12] = {
610 	{ 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
611 	{ 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
612 	{ 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
613 	{ 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
614 	{ 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
615 	{ 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
616 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
617 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
618 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
619 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
620 	{ 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
621 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
622 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
623 	{ 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
624 	{ 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
625 	{ 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
626 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
627 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
628 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
629 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
630 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
631 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
632 	{ 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
633 	{ 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
634 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
635 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
636 	{ 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
637 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
638 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
639 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
640 	{ 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
641 	{ 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
642 	{ 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
643 };
644 
645 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
646 	{ 1, 2412, bwn_b2063_chantable_data[0] },
647 	{ 2, 2417, bwn_b2063_chantable_data[0] },
648 	{ 3, 2422, bwn_b2063_chantable_data[0] },
649 	{ 4, 2427, bwn_b2063_chantable_data[1] },
650 	{ 5, 2432, bwn_b2063_chantable_data[1] },
651 	{ 6, 2437, bwn_b2063_chantable_data[1] },
652 	{ 7, 2442, bwn_b2063_chantable_data[1] },
653 	{ 8, 2447, bwn_b2063_chantable_data[1] },
654 	{ 9, 2452, bwn_b2063_chantable_data[2] },
655 	{ 10, 2457, bwn_b2063_chantable_data[2] },
656 	{ 11, 2462, bwn_b2063_chantable_data[3] },
657 	{ 12, 2467, bwn_b2063_chantable_data[3] },
658 	{ 13, 2472, bwn_b2063_chantable_data[3] },
659 	{ 14, 2484, bwn_b2063_chantable_data[4] },
660 	{ 34, 5170, bwn_b2063_chantable_data[5] },
661 	{ 36, 5180, bwn_b2063_chantable_data[6] },
662 	{ 38, 5190, bwn_b2063_chantable_data[7] },
663 	{ 40, 5200, bwn_b2063_chantable_data[8] },
664 	{ 42, 5210, bwn_b2063_chantable_data[9] },
665 	{ 44, 5220, bwn_b2063_chantable_data[10] },
666 	{ 46, 5230, bwn_b2063_chantable_data[11] },
667 	{ 48, 5240, bwn_b2063_chantable_data[12] },
668 	{ 52, 5260, bwn_b2063_chantable_data[13] },
669 	{ 56, 5280, bwn_b2063_chantable_data[14] },
670 	{ 60, 5300, bwn_b2063_chantable_data[14] },
671 	{ 64, 5320, bwn_b2063_chantable_data[15] },
672 	{ 100, 5500, bwn_b2063_chantable_data[16] },
673 	{ 104, 5520, bwn_b2063_chantable_data[17] },
674 	{ 108, 5540, bwn_b2063_chantable_data[18] },
675 	{ 112, 5560, bwn_b2063_chantable_data[19] },
676 	{ 116, 5580, bwn_b2063_chantable_data[20] },
677 	{ 120, 5600, bwn_b2063_chantable_data[21] },
678 	{ 124, 5620, bwn_b2063_chantable_data[21] },
679 	{ 128, 5640, bwn_b2063_chantable_data[22] },
680 	{ 132, 5660, bwn_b2063_chantable_data[22] },
681 	{ 136, 5680, bwn_b2063_chantable_data[22] },
682 	{ 140, 5700, bwn_b2063_chantable_data[23] },
683 	{ 149, 5745, bwn_b2063_chantable_data[23] },
684 	{ 153, 5765, bwn_b2063_chantable_data[23] },
685 	{ 157, 5785, bwn_b2063_chantable_data[23] },
686 	{ 161, 5805, bwn_b2063_chantable_data[23] },
687 	{ 165, 5825, bwn_b2063_chantable_data[23] },
688 	{ 184, 4920, bwn_b2063_chantable_data[24] },
689 	{ 188, 4940, bwn_b2063_chantable_data[25] },
690 	{ 192, 4960, bwn_b2063_chantable_data[26] },
691 	{ 196, 4980, bwn_b2063_chantable_data[27] },
692 	{ 200, 5000, bwn_b2063_chantable_data[28] },
693 	{ 204, 5020, bwn_b2063_chantable_data[29] },
694 	{ 208, 5040, bwn_b2063_chantable_data[30] },
695 	{ 212, 5060, bwn_b2063_chantable_data[31] },
696 	{ 216, 5080, bwn_b2063_chantable_data[32] }
697 };
698 
699 static const uint8_t bwn_b2062_chantable_data[22][12] = {
700 	{ 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
701 	{ 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
702 	{ 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
703 	{ 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
704 	{ 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
705 	{ 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
706 	{ 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707 	{ 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708 	{ 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 	{ 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
710 	{ 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
711 	{ 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
712 	{ 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
713 	{ 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
714 	{ 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
715 	{ 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
716 	{ 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
717 	{ 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
718 	{ 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719 	{ 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720 	{ 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
721 	{ 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
722 };
723 
724 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
725 	{ 1, 2412, bwn_b2062_chantable_data[0] },
726 	{ 2, 2417, bwn_b2062_chantable_data[0] },
727 	{ 3, 2422, bwn_b2062_chantable_data[0] },
728 	{ 4, 2427, bwn_b2062_chantable_data[0] },
729 	{ 5, 2432, bwn_b2062_chantable_data[0] },
730 	{ 6, 2437, bwn_b2062_chantable_data[0] },
731 	{ 7, 2442, bwn_b2062_chantable_data[0] },
732 	{ 8, 2447, bwn_b2062_chantable_data[0] },
733 	{ 9, 2452, bwn_b2062_chantable_data[0] },
734 	{ 10, 2457, bwn_b2062_chantable_data[0] },
735 	{ 11, 2462, bwn_b2062_chantable_data[0] },
736 	{ 12, 2467, bwn_b2062_chantable_data[0] },
737 	{ 13, 2472, bwn_b2062_chantable_data[0] },
738 	{ 14, 2484, bwn_b2062_chantable_data[0] },
739 	{ 34, 5170, bwn_b2062_chantable_data[1] },
740 	{ 38, 5190, bwn_b2062_chantable_data[2] },
741 	{ 42, 5210, bwn_b2062_chantable_data[2] },
742 	{ 46, 5230, bwn_b2062_chantable_data[3] },
743 	{ 36, 5180, bwn_b2062_chantable_data[4] },
744 	{ 40, 5200, bwn_b2062_chantable_data[5] },
745 	{ 44, 5220, bwn_b2062_chantable_data[6] },
746 	{ 48, 5240, bwn_b2062_chantable_data[3] },
747 	{ 52, 5260, bwn_b2062_chantable_data[3] },
748 	{ 56, 5280, bwn_b2062_chantable_data[3] },
749 	{ 60, 5300, bwn_b2062_chantable_data[7] },
750 	{ 64, 5320, bwn_b2062_chantable_data[8] },
751 	{ 100, 5500, bwn_b2062_chantable_data[9] },
752 	{ 104, 5520, bwn_b2062_chantable_data[10] },
753 	{ 108, 5540, bwn_b2062_chantable_data[10] },
754 	{ 112, 5560, bwn_b2062_chantable_data[10] },
755 	{ 116, 5580, bwn_b2062_chantable_data[11] },
756 	{ 120, 5600, bwn_b2062_chantable_data[12] },
757 	{ 124, 5620, bwn_b2062_chantable_data[12] },
758 	{ 128, 5640, bwn_b2062_chantable_data[12] },
759 	{ 132, 5660, bwn_b2062_chantable_data[12] },
760 	{ 136, 5680, bwn_b2062_chantable_data[12] },
761 	{ 140, 5700, bwn_b2062_chantable_data[12] },
762 	{ 149, 5745, bwn_b2062_chantable_data[12] },
763 	{ 153, 5765, bwn_b2062_chantable_data[12] },
764 	{ 157, 5785, bwn_b2062_chantable_data[12] },
765 	{ 161, 5805, bwn_b2062_chantable_data[12] },
766 	{ 165, 5825, bwn_b2062_chantable_data[12] },
767 	{ 184, 4920, bwn_b2062_chantable_data[13] },
768 	{ 188, 4940, bwn_b2062_chantable_data[14] },
769 	{ 192, 4960, bwn_b2062_chantable_data[15] },
770 	{ 196, 4980, bwn_b2062_chantable_data[16] },
771 	{ 200, 5000, bwn_b2062_chantable_data[17] },
772 	{ 204, 5020, bwn_b2062_chantable_data[18] },
773 	{ 208, 5040, bwn_b2062_chantable_data[19] },
774 	{ 212, 5060, bwn_b2062_chantable_data[20] },
775 	{ 216, 5080, bwn_b2062_chantable_data[21] }
776 };
777 
778 /* for LP PHY */
779 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
780 	{  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
781 	{  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
782 	{  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
783 	{ 13, -66, 13 }, { 14, -66, 13 },
784 };
785 
786 /* for LP PHY */
787 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
788 	{   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
789 	{   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
790 	{   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
791 	{  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
792 	{  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
793 	{  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
794 	{  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
795 	{ 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
796 	{ 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
797 	{ 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
798 	{ 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
799 	{ 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
800 	{ 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
801 };
802 
803 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
804 
805 static const uint8_t bwn_tab_sigsq_tbl[] = {
806 	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
807 	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
808 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
809 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
810 	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
811 	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
812 };
813 
814 static const uint8_t bwn_tab_pllfrac_tbl[] = {
815 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
816 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
817 };
818 
819 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
820 	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
821 	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
822 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
823 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
824 	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
825 	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
826 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
827 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
830 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
831 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
832 };
833 
834 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
835 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
836 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
837 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
838 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
839 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
840 
841 #define	VENDOR_LED_ACT(vendor)				\
842 {							\
843 	.vid = PCI_VENDOR_##vendor,			\
844 	.led_act = { BWN_VENDOR_LED_ACT_##vendor }	\
845 }
846 
847 static const struct {
848 	uint16_t	vid;
849 	uint8_t		led_act[BWN_LED_MAX];
850 } bwn_vendor_led_act[] = {
851 	VENDOR_LED_ACT(COMPAQ),
852 	VENDOR_LED_ACT(ASUSTEK)
853 };
854 
855 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
856 	{ BWN_VENDOR_LED_ACT_DEFAULT };
857 
858 #undef VENDOR_LED_ACT
859 
860 static const struct {
861 	int		on_dur;
862 	int		off_dur;
863 } bwn_led_duration[109] = {
864 	[0]	= { 400, 100 },
865 	[2]	= { 150, 75 },
866 	[4]	= { 90, 45 },
867 	[11]	= { 66, 34 },
868 	[12]	= { 53, 26 },
869 	[18]	= { 42, 21 },
870 	[22]	= { 35, 17 },
871 	[24]	= { 32, 16 },
872 	[36]	= { 21, 10 },
873 	[48]	= { 16, 8 },
874 	[72]	= { 11, 5 },
875 	[96]	= { 9, 4 },
876 	[108]	= { 7, 3 }
877 };
878 
879 static const uint16_t bwn_wme_shm_offsets[] = {
880 	[0] = BWN_WME_BESTEFFORT,
881 	[1] = BWN_WME_BACKGROUND,
882 	[2] = BWN_WME_VOICE,
883 	[3] = BWN_WME_VIDEO,
884 };
885 
886 static const struct siba_devid bwn_devs[] = {
887 	SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
888 	SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
889 	SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
890 	SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
891 	SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
892 	SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
893 	SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
894 	SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
895 	SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
896 };
897 
898 static int
899 bwn_probe(device_t dev)
900 {
901 	int i;
902 
903 	wlan_serialize_enter();
904 
905 	for (i = 0; i < NELEM(bwn_devs); i++) {
906 		if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
907 		    siba_get_device(dev) == bwn_devs[i].sd_device &&
908 		    siba_get_revid(dev) == bwn_devs[i].sd_rev) {
909 			wlan_serialize_exit();
910 			return (BUS_PROBE_DEFAULT);
911 		}
912 	}
913 	wlan_serialize_exit();
914 	return (ENXIO);
915 }
916 
917 static int
918 bwn_attach(device_t dev)
919 {
920 	struct bwn_mac *mac;
921 	struct bwn_softc *sc = device_get_softc(dev);
922 	int error;
923 	u_int irq_flags;
924 
925 	wlan_serialize_enter();
926 
927 	sc->sc_dev = dev;
928 #ifdef BWN_DEBUG
929 	sc->sc_debug = bwn_debug;
930 #endif
931 
932 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933 		error = bwn_attach_pre(sc);
934 		if (error != 0) {
935 			wlan_serialize_exit();
936 			return (error);
937 		}
938 		bwn_sprom_bugfixes(dev);
939 		sc->sc_flags |= BWN_FLAG_ATTACHED;
940 	}
941 
942 	if (!TAILQ_EMPTY(&sc->sc_maclist)) {
943 		if (siba_get_pci_device(dev) != 0x4313 &&
944 		    siba_get_pci_device(dev) != 0x431a &&
945 		    siba_get_pci_device(dev) != 0x4321) {
946 			device_printf(sc->sc_dev,
947 			    "skip 802.11 cores\n");
948 			wlan_serialize_exit();
949 			return (ENODEV);
950 		}
951 	}
952 
953 	mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF,
954 	    M_INTWAIT | M_ZERO);
955 	mac->mac_sc = sc;
956 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
957 	if (bwn_bfp != 0)
958 		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
959 
960 	TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
961 	TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
962 	TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
963 
964 	error = bwn_attach_core(mac);
965 	if (error)
966 		goto fail0;
967 	bwn_led_attach(mac);
968 
969 	device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
970 	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
971 	    siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
972 	    mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
973 	    mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
974 	    mac->mac_phy.rf_rev);
975 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
976 		device_printf(sc->sc_dev, "DMA (%d bits)\n",
977 		    mac->mac_method.dma.dmatype);
978 	else
979 		device_printf(sc->sc_dev, "PIO\n");
980 
981 	/* Allocate IRQ resource. */
982 	sc->bwn_irq_rid = 0;
983 	sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable,
984 	    &sc->bwn_irq_rid, &irq_flags);
985 	if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
986 	    &sc->bwn_irq_rid, irq_flags)) == NULL) {
987 		device_printf(sc->sc_dev, "Cannot allocate interrupt\n");
988 		error = EINVAL;
989 		goto fail1;
990 	}
991 	if ((error = bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE,
992 		bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) != 0) {
993 		device_printf(sc->sc_dev, "Cannot set up interrupt\n");
994 		goto fail1;
995 	}
996 
997 	TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
998 
999 	/*
1000 	 * calls attach-post routine
1001 	 */
1002 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1003 		bwn_attach_post(sc);
1004 
1005 	wlan_serialize_exit();
1006 	return (0);
1007 fail1:
1008 	if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1009 		pci_release_msi(dev);
1010 fail0:
1011 	kfree(mac, M_DEVBUF);
1012 	wlan_serialize_exit();
1013 	return (error);
1014 }
1015 
1016 static int
1017 bwn_is_valid_ether_addr(uint8_t *addr)
1018 {
1019 	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1020 
1021 	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1022 		return (FALSE);
1023 
1024 	return (TRUE);
1025 }
1026 
1027 static int
1028 bwn_attach_post(struct bwn_softc *sc)
1029 {
1030 	struct ieee80211com *ic;
1031 	struct ifnet *ifp = sc->sc_ifp;
1032 
1033 	ic = ifp->if_l2com;
1034 	ic->ic_ifp = ifp;
1035 	ic->ic_softc = sc;
1036 	ic->ic_name = device_get_nameunit(sc->sc_dev);
1037 	/* XXX not right but it's not used anywhere important */
1038 	ic->ic_phytype = IEEE80211_T_OFDM;
1039 	ic->ic_opmode = IEEE80211_M_STA;
1040 	ic->ic_caps =
1041 		  IEEE80211_C_STA		/* station mode supported */
1042 		| IEEE80211_C_MONITOR		/* monitor mode */
1043 		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
1044 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
1045 		| IEEE80211_C_SHSLOT		/* short slot time supported */
1046 		| IEEE80211_C_WME		/* WME/WMM supported */
1047 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
1048 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
1049 		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
1050 		;
1051 
1052 	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;	/* s/w bmiss */
1053 
1054 	/* call MI attach routine. */
1055 	ieee80211_ifattach(ic,
1056 	    bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1057 	    siba_sprom_get_mac_80211a(sc->sc_dev) :
1058 	    siba_sprom_get_mac_80211bg(sc->sc_dev));
1059 
1060 	ic->ic_headroom = sizeof(struct bwn_txhdr);
1061 
1062 	/* override default methods */
1063 	ic->ic_raw_xmit = bwn_raw_xmit;
1064 	ic->ic_updateslot = bwn_updateslot;
1065 	ic->ic_update_promisc = bwn_update_promisc;
1066 	ic->ic_wme.wme_update = bwn_wme_update;
1067 
1068 	ic->ic_scan_start = bwn_scan_start;
1069 	ic->ic_scan_end = bwn_scan_end;
1070 	ic->ic_set_channel = bwn_set_channel;
1071 
1072 	ic->ic_vap_create = bwn_vap_create;
1073 	ic->ic_vap_delete = bwn_vap_delete;
1074 
1075 	ieee80211_radiotap_attach(ic,
1076 	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1077 	    BWN_TX_RADIOTAP_PRESENT,
1078 	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1079 	    BWN_RX_RADIOTAP_PRESENT);
1080 
1081 	bwn_sysctl_node(sc);
1082 
1083 	if (bootverbose)
1084 		ieee80211_announce(ic);
1085 	return (0);
1086 }
1087 
1088 static void
1089 bwn_phy_detach(struct bwn_mac *mac)
1090 {
1091 
1092 	if (mac->mac_phy.detach != NULL)
1093 		mac->mac_phy.detach(mac);
1094 }
1095 
1096 static int
1097 bwn_detach(device_t dev)
1098 {
1099 	struct bwn_softc *sc = device_get_softc(dev);
1100 	struct bwn_mac *mac = sc->sc_curmac;
1101 	struct ifnet *ifp = sc->sc_ifp;
1102 	struct ieee80211com *ic = ifp->if_l2com;
1103 
1104 	wlan_serialize_enter();
1105 
1106 	sc->sc_flags |= BWN_FLAG_INVALID;
1107 
1108 	if (device_is_attached(sc->sc_dev)) {
1109 		bwn_stop(sc, 1);
1110 		bwn_dma_free(mac);
1111 		callout_stop_sync(&sc->sc_led_blink_ch);
1112 		callout_stop_sync(&sc->sc_rfswitch_ch);
1113 		callout_stop_sync(&sc->sc_task_ch);
1114 		callout_stop_sync(&sc->sc_watchdog_ch);
1115 		bwn_phy_detach(mac);
1116 		if (ifp != NULL) {
1117 			wlan_serialize_exit();
1118 			ieee80211_draintask(ic, &mac->mac_hwreset);
1119 			ieee80211_draintask(ic, &mac->mac_txpower);
1120 			wlan_serialize_enter();
1121 			ieee80211_ifdetach(ic);
1122 			if_free(ifp);
1123 		}
1124 	}
1125 	wlan_serialize_exit();
1126 	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1127 	taskqueue_free(sc->sc_tq);
1128 	wlan_serialize_enter();
1129 
1130 	if (sc->bwn_intr)
1131 		bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr);
1132 	if (sc->bwn_irq != NULL)
1133 		bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid,
1134 		    sc->bwn_irq);
1135 
1136 	if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1137 		pci_release_msi(dev);
1138 
1139 	wlan_serialize_exit();
1140 	return (0);
1141 }
1142 
1143 static int
1144 bwn_attach_pre(struct bwn_softc *sc)
1145 {
1146 	struct ifnet *ifp;
1147 	int error = 0;
1148 
1149 	TAILQ_INIT(&sc->sc_maclist);
1150 	callout_init(&sc->sc_rfswitch_ch);
1151 	callout_init(&sc->sc_task_ch);
1152 	callout_init(&sc->sc_watchdog_ch);
1153 
1154 	sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK,
1155 		taskqueue_thread_enqueue, &sc->sc_tq);
1156 	taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
1157 		"%s taskq", device_get_nameunit(sc->sc_dev));
1158 
1159 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1160 	if (ifp == NULL) {
1161 		device_printf(sc->sc_dev, "can not if_alloc()\n");
1162 		error = ENOSPC;
1163 		goto fail;
1164 	}
1165 
1166 	/* set these up early for if_printf use */
1167 	if_initname(ifp, device_get_name(sc->sc_dev),
1168 	    device_get_unit(sc->sc_dev));
1169 
1170 	ifp->if_softc = sc;
1171 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1172 	ifp->if_init = bwn_init;
1173 	ifp->if_ioctl = bwn_ioctl;
1174 	ifp->if_start = bwn_start;
1175 	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
1176 
1177 	return (0);
1178 
1179 fail:
1180 	return (error);
1181 }
1182 
1183 static void
1184 bwn_sprom_bugfixes(device_t dev)
1185 {
1186 #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
1187 	((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&		\
1188 	 (siba_get_pci_device(dev) == _device) &&			\
1189 	 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&	\
1190 	 (siba_get_pci_subdevice(dev) == _subdevice))
1191 
1192 	if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1193 	    siba_get_pci_subdevice(dev) == 0x4e &&
1194 	    siba_get_pci_revid(dev) > 0x40)
1195 		siba_sprom_set_bf_lo(dev,
1196 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1197 	if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1198 	    siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1199 		siba_sprom_set_bf_lo(dev,
1200 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1201 	if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1202 		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1203 		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1204 		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1205 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1206 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1207 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1208 		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1209 			siba_sprom_set_bf_lo(dev,
1210 			    siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1211 	}
1212 #undef	BWN_ISDEV
1213 }
1214 
1215 static int
1216 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
1217 	  struct ucred *cr __unused)
1218 {
1219 #define IS_RUNNING(ifp) \
1220         ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1221 	struct bwn_softc *sc = ifp->if_softc;
1222 	struct ieee80211com *ic = ifp->if_l2com;
1223 	struct ifreq *ifr = (struct ifreq *)data;
1224 	int error = 0;
1225 
1226 	switch (cmd) {
1227 	case SIOCSIFFLAGS:
1228 		if (IS_RUNNING(ifp)) {
1229 			bwn_update_promisc(ic);
1230 		} else if (ifp->if_flags & IFF_UP) {
1231 			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1232 				bwn_init(sc);
1233 			}
1234 		} else
1235 			bwn_stop(sc, 1);
1236 		break;
1237 	case SIOCGIFMEDIA:
1238 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1239 		break;
1240 	case SIOCGIFADDR:
1241 		error = ether_ioctl(ifp, cmd, data);
1242 		break;
1243 	default:
1244 		error = EINVAL;
1245 		break;
1246 	}
1247 	return (error);
1248 }
1249 
1250 static void
1251 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1252 {
1253 	wlan_assert_serialized();
1254 	bwn_start_locked(ifp);
1255 }
1256 
1257 static void
1258 bwn_start_locked(struct ifnet *ifp)
1259 {
1260 	struct bwn_softc *sc = ifp->if_softc;
1261 	struct bwn_mac *mac = sc->sc_curmac;
1262 	struct ieee80211_frame *wh;
1263 	struct ieee80211_node *ni;
1264 	struct ieee80211_key *k;
1265 	struct mbuf *m;
1266 
1267 	wlan_assert_serialized();
1268 
1269 	if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL ||
1270 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
1271 		return;
1272 
1273 	for (;;) {
1274 		m = ifq_dequeue(&ifp->if_snd);	/* XXX: LOCK */
1275 		if (m == NULL)
1276 			break;
1277 
1278 		if (bwn_tx_isfull(sc, m))
1279 			break;
1280 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1281 		if (ni == NULL) {
1282 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
1283 			m_freem(m);
1284 			ifp->if_oerrors++;
1285 			continue;
1286 		}
1287 		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1288 		wh = mtod(m, struct ieee80211_frame *);
1289 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1290 			k = ieee80211_crypto_encap(ni, m);
1291 			if (k == NULL) {
1292 				ieee80211_free_node(ni);
1293 				m_freem(m);
1294 				ifp->if_oerrors++;
1295 				continue;
1296 			}
1297 		}
1298 		wh = NULL;	/* Catch any invalid use */
1299 
1300 		if (bwn_tx_start(sc, ni, m) != 0) {
1301 			if (ni != NULL)
1302 				ieee80211_free_node(ni);
1303 			ifp->if_oerrors++;
1304 			continue;
1305 		}
1306 
1307 		sc->sc_watchdog_timer = 5;
1308 	}
1309 }
1310 
1311 static int
1312 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1313 {
1314 	struct bwn_dma_ring *dr;
1315 	struct bwn_mac *mac = sc->sc_curmac;
1316 	struct bwn_pio_txqueue *tq;
1317 	struct ifnet *ifp = sc->sc_ifp;
1318 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1319 
1320 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1321 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1322 		if (dr->dr_stop == 1 ||
1323 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1324 			dr->dr_stop = 1;
1325 			goto full;
1326 		}
1327 	} else {
1328 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1329 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1330 		    pktlen > (tq->tq_size - tq->tq_used)) {
1331 			tq->tq_stop = 1;
1332 			goto full;
1333 		}
1334 	}
1335 	return (0);
1336 full:
1337 	ifq_prepend(&ifp->if_snd, m);
1338 	ifq_set_oactive(&ifp->if_snd);
1339 	return (1);
1340 }
1341 
1342 static int
1343 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1344 {
1345 	struct bwn_mac *mac = sc->sc_curmac;
1346 	int error;
1347 
1348 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1349 		m_freem(m);
1350 		return (ENXIO);
1351 	}
1352 
1353 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1354 	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1355 	if (error) {
1356 		m_freem(m);
1357 		return (error);
1358 	}
1359 	return (0);
1360 }
1361 
1362 static int
1363 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1364 {
1365 	struct bwn_pio_txpkt *tp;
1366 	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1367 	struct bwn_softc *sc = mac->mac_sc;
1368 	struct bwn_txhdr txhdr;
1369 	struct mbuf *m_new;
1370 	uint32_t ctl32;
1371 	int error;
1372 	uint16_t ctl16;
1373 
1374 	/* XXX TODO send packets after DTIM */
1375 
1376 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1377 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1378 	tp->tp_ni = ni;
1379 	tp->tp_m = m;
1380 
1381 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1382 	if (error) {
1383 		device_printf(sc->sc_dev, "tx fail\n");
1384 		return (error);
1385 	}
1386 
1387 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1388 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1389 	tq->tq_free--;
1390 
1391 	if (siba_get_revid(sc->sc_dev) >= 8) {
1392 		/*
1393 		 * XXX please removes m_defrag(9)
1394 		 */
1395 		m_new = m_defrag(m, M_NOWAIT);
1396 		if (m_new == NULL) {
1397 			device_printf(sc->sc_dev,
1398 			    "%s: can't defrag TX buffer\n",
1399 			    __func__);
1400 			return (ENOBUFS);
1401 		}
1402 		if (m_new->m_next != NULL)
1403 			device_printf(sc->sc_dev,
1404 			    "TODO: fragmented packets for PIO\n");
1405 		tp->tp_m = m_new;
1406 
1407 		/* send HEADER */
1408 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1409 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1410 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1411 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1412 		/* send BODY */
1413 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1414 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1415 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1416 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1417 	} else {
1418 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1419 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1420 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1421 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1422 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1423 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1424 		    ctl16 | BWN_PIO_TXCTL_EOF);
1425 	}
1426 
1427 	return (0);
1428 }
1429 
1430 static struct bwn_pio_txqueue *
1431 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1432 {
1433 
1434 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1435 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1436 
1437 	switch (prio) {
1438 	case 0:
1439 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1440 	case 1:
1441 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1442 	case 2:
1443 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1444 	case 3:
1445 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1446 	}
1447 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1448 	return (NULL);
1449 }
1450 
1451 static int
1452 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1453 {
1454 #define	BWN_GET_TXHDRCACHE(slot)					\
1455 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)])
1456 	struct bwn_dma *dma = &mac->mac_method.dma;
1457 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1458 	struct bwn_dmadesc_generic *desc;
1459 	struct bwn_dmadesc_meta *mt;
1460 	struct bwn_softc *sc = mac->mac_sc;
1461 	struct ifnet *ifp = sc->sc_ifp;
1462 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1463 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1464 
1465 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1466 
1467 	/* XXX send after DTIM */
1468 
1469 	slot = bwn_dma_getslot(dr);
1470 	dr->getdesc(dr, slot, &desc, &mt);
1471 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1472 	    ("%s:%d: fail", __func__, __LINE__));
1473 
1474 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1475 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1476 	    BWN_DMA_COOKIE(dr, slot));
1477 	if (error)
1478 		goto fail;
1479 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1480 	    BUS_DMASYNC_PREWRITE);
1481 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1482 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1483 	    BUS_DMASYNC_PREWRITE);
1484 
1485 	slot = bwn_dma_getslot(dr);
1486 	dr->getdesc(dr, slot, &desc, &mt);
1487 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1488 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1489 	mt->mt_m = m;
1490 	mt->mt_ni = ni;
1491 
1492 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1493 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1494 	if (error && error != EFBIG) {
1495 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1496 		    __func__, error);
1497 		goto fail;
1498 	}
1499 	if (error) {    /* error == EFBIG */
1500 		struct mbuf *m_new;
1501 
1502 		m_new = m_defrag(m, M_NOWAIT);
1503 		if (m_new == NULL) {
1504 			if_printf(ifp, "%s: can't defrag TX buffer\n",
1505 			    __func__);
1506 			error = ENOBUFS;
1507 			goto fail;
1508 		} else {
1509 			m = m_new;
1510 		}
1511 
1512 		mt->mt_m = m;
1513 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1514 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1515 		if (error) {
1516 			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1517 			    __func__, error);
1518 			goto fail;
1519 		}
1520 	}
1521 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1522 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1523 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1524 	    BUS_DMASYNC_PREWRITE);
1525 
1526 	/* XXX send after DTIM */
1527 
1528 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1529 	return (0);
1530 fail:
1531 	dr->dr_curslot = backup[0];
1532 	dr->dr_usedslot = backup[1];
1533 	return (error);
1534 #undef BWN_GET_TXHDRCACHE
1535 }
1536 
1537 static void
1538 bwn_watchdog(void *arg)
1539 {
1540 	struct bwn_softc *sc = arg;
1541 	struct ifnet *ifp = sc->sc_ifp;
1542 
1543 	wlan_serialize_enter();
1544 
1545 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1546 		if_printf(ifp, "device timeout\n");
1547 		ifp->if_oerrors++;
1548 	}
1549 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
1550 	wlan_serialize_exit();
1551 }
1552 
1553 static int
1554 bwn_attach_core(struct bwn_mac *mac)
1555 {
1556 	struct bwn_softc *sc = mac->mac_sc;
1557 	int error, have_bg = 0, have_a = 0;
1558 	uint32_t high;
1559 
1560 	KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1561 	    ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1562 
1563 	siba_powerup(sc->sc_dev, 0);
1564 
1565 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1566 	bwn_reset_core(mac,
1567 	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1568 	error = bwn_phy_getinfo(mac, high);
1569 	if (error)
1570 		goto fail;
1571 
1572 	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1573 	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1574 	if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1575 	    siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1576 	    siba_get_pci_device(sc->sc_dev) != 0x4324) {
1577 		have_a = have_bg = 0;
1578 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1579 			have_a = 1;
1580 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1581 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1582 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1583 			have_bg = 1;
1584 		else
1585 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1586 			    mac->mac_phy.type));
1587 	}
1588 	/* XXX turns off PHY A because it's not supported */
1589 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1590 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1591 		have_a = 0;
1592 		have_bg = 1;
1593 	}
1594 
1595 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1596 		mac->mac_phy.attach = bwn_phy_g_attach;
1597 		mac->mac_phy.detach = bwn_phy_g_detach;
1598 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1599 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1600 		mac->mac_phy.init = bwn_phy_g_init;
1601 		mac->mac_phy.exit = bwn_phy_g_exit;
1602 		mac->mac_phy.phy_read = bwn_phy_g_read;
1603 		mac->mac_phy.phy_write = bwn_phy_g_write;
1604 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1605 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1606 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1607 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1608 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1609 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1610 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1611 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1612 		mac->mac_phy.set_im = bwn_phy_g_im;
1613 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1614 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1615 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1616 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1617 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1618 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1619 		mac->mac_phy.init = bwn_phy_lp_init;
1620 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1621 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1622 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1623 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1624 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1625 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1626 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1627 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1628 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1629 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1630 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1631 	} else {
1632 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1633 		    mac->mac_phy.type);
1634 		error = ENXIO;
1635 		goto fail;
1636 	}
1637 
1638 	mac->mac_phy.gmode = have_bg;
1639 	if (mac->mac_phy.attach != NULL) {
1640 		error = mac->mac_phy.attach(mac);
1641 		if (error) {
1642 			device_printf(sc->sc_dev, "failed\n");
1643 			goto fail;
1644 		}
1645 	}
1646 
1647 	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1648 
1649 	error = bwn_chiptest(mac);
1650 	if (error)
1651 		goto fail;
1652 	error = bwn_setup_channels(mac, have_bg, have_a);
1653 	if (error) {
1654 		device_printf(sc->sc_dev, "failed to setup channels\n");
1655 		goto fail;
1656 	}
1657 
1658 	if (sc->sc_curmac == NULL)
1659 		sc->sc_curmac = mac;
1660 
1661 	wlan_assert_serialized();
1662 	wlan_serialize_exit();
1663 	error = bwn_dma_attach(mac);
1664 	wlan_serialize_enter();
1665 	if (error != 0) {
1666 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1667 		goto fail;
1668 	}
1669 
1670 	mac->mac_phy.switch_analog(mac, 0);
1671 
1672 	siba_dev_down(sc->sc_dev, 0);
1673 fail:
1674 	siba_powerdown(sc->sc_dev);
1675 	return (error);
1676 }
1677 
1678 static void
1679 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1680 {
1681 	struct bwn_softc *sc = mac->mac_sc;
1682 	uint32_t low, ctl;
1683 
1684 	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1685 
1686 	siba_dev_up(sc->sc_dev, flags);
1687 	DELAY(2000);
1688 
1689 	low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1690 	    ~BWN_TGSLOW_PHYRESET;
1691 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1692 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1693 	DELAY(1000);
1694 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1695 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1696 	DELAY(1000);
1697 
1698 	if (mac->mac_phy.switch_analog != NULL)
1699 		mac->mac_phy.switch_analog(mac, 1);
1700 
1701 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1702 	if (flags & BWN_TGSLOW_SUPPORT_G)
1703 		ctl |= BWN_MACCTL_GMODE;
1704 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1705 }
1706 
1707 static int
1708 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1709 {
1710 	struct bwn_phy *phy = &mac->mac_phy;
1711 	struct bwn_softc *sc = mac->mac_sc;
1712 	uint32_t tmp;
1713 
1714 	/* PHY */
1715 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1716 	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1717 	phy->rf_on = 1;
1718 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1719 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1720 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1721 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1722 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1723 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1724 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1725 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1726 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1727 		goto unsupphy;
1728 
1729 	/* RADIO */
1730 	if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1731 		if (siba_get_chiprev(sc->sc_dev) == 0)
1732 			tmp = 0x3205017f;
1733 		else if (siba_get_chiprev(sc->sc_dev) == 1)
1734 			tmp = 0x4205017f;
1735 		else
1736 			tmp = 0x5205017f;
1737 	} else {
1738 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1739 		tmp = BWN_READ_2(mac, BWN_RFDATALO);
1740 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1741 		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1742 	}
1743 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1744 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1745 	phy->rf_manuf = (tmp & 0x00000fff);
1746 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1747 		goto unsupradio;
1748 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1749 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1750 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1751 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1752 	    (phy->type == BWN_PHYTYPE_N &&
1753 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1754 	    (phy->type == BWN_PHYTYPE_LP &&
1755 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1756 		goto unsupradio;
1757 
1758 	return (0);
1759 unsupphy:
1760 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1761 	    "analog %#x)\n",
1762 	    phy->type, phy->rev, phy->analog);
1763 	return (ENXIO);
1764 unsupradio:
1765 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1766 	    "rev %#x)\n",
1767 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1768 	return (ENXIO);
1769 }
1770 
1771 static int
1772 bwn_chiptest(struct bwn_mac *mac)
1773 {
1774 #define	TESTVAL0	0x55aaaa55
1775 #define	TESTVAL1	0xaa5555aa
1776 	struct bwn_softc *sc = mac->mac_sc;
1777 	uint32_t v, backup;
1778 
1779 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1780 
1781 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1782 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1783 		goto error;
1784 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1785 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1786 		goto error;
1787 
1788 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1789 
1790 	if ((siba_get_revid(sc->sc_dev) >= 3) &&
1791 	    (siba_get_revid(sc->sc_dev) <= 10)) {
1792 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1793 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1794 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1795 			goto error;
1796 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1797 			goto error;
1798 	}
1799 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1800 
1801 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1802 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1803 		goto error;
1804 
1805 	return (0);
1806 error:
1807 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1808 	return (ENODEV);
1809 }
1810 
1811 #define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1812 #define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1813 
1814 static int
1815 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1816 {
1817 	struct bwn_softc *sc = mac->mac_sc;
1818 	struct ifnet *ifp = sc->sc_ifp;
1819 	struct ieee80211com *ic = ifp->if_l2com;
1820 
1821 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1822 	ic->ic_nchans = 0;
1823 
1824 	if (have_bg)
1825 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1826 		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1827 	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1828 		if (have_a)
1829 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1830 			    &ic->ic_nchans, &bwn_chantable_n,
1831 			    IEEE80211_CHAN_HTA);
1832 	} else {
1833 		if (have_a)
1834 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1835 			    &ic->ic_nchans, &bwn_chantable_a,
1836 			    IEEE80211_CHAN_A);
1837 	}
1838 
1839 	mac->mac_phy.supports_2ghz = have_bg;
1840 	mac->mac_phy.supports_5ghz = have_a;
1841 
1842 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1843 }
1844 
1845 static uint32_t
1846 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1847 {
1848 	uint32_t ret;
1849 
1850 	if (way == BWN_SHARED) {
1851 		KASSERT((offset & 0x0001) == 0,
1852 		    ("%s:%d warn", __func__, __LINE__));
1853 		if (offset & 0x0003) {
1854 			bwn_shm_ctlword(mac, way, offset >> 2);
1855 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1856 			ret <<= 16;
1857 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1858 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1859 			goto out;
1860 		}
1861 		offset >>= 2;
1862 	}
1863 	bwn_shm_ctlword(mac, way, offset);
1864 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1865 out:
1866 	return (ret);
1867 }
1868 
1869 static uint16_t
1870 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1871 {
1872 	uint16_t ret;
1873 
1874 	if (way == BWN_SHARED) {
1875 		KASSERT((offset & 0x0001) == 0,
1876 		    ("%s:%d warn", __func__, __LINE__));
1877 		if (offset & 0x0003) {
1878 			bwn_shm_ctlword(mac, way, offset >> 2);
1879 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1880 			goto out;
1881 		}
1882 		offset >>= 2;
1883 	}
1884 	bwn_shm_ctlword(mac, way, offset);
1885 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1886 out:
1887 
1888 	return (ret);
1889 }
1890 
1891 static void
1892 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1893     uint16_t offset)
1894 {
1895 	uint32_t control;
1896 
1897 	control = way;
1898 	control <<= 16;
1899 	control |= offset;
1900 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1901 }
1902 
1903 static void
1904 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1905     uint32_t value)
1906 {
1907 	if (way == BWN_SHARED) {
1908 		KASSERT((offset & 0x0001) == 0,
1909 		    ("%s:%d warn", __func__, __LINE__));
1910 		if (offset & 0x0003) {
1911 			bwn_shm_ctlword(mac, way, offset >> 2);
1912 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1913 				    (value >> 16) & 0xffff);
1914 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1915 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1916 			return;
1917 		}
1918 		offset >>= 2;
1919 	}
1920 	bwn_shm_ctlword(mac, way, offset);
1921 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1922 }
1923 
1924 static void
1925 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1926     uint16_t value)
1927 {
1928 	if (way == BWN_SHARED) {
1929 		KASSERT((offset & 0x0001) == 0,
1930 		    ("%s:%d warn", __func__, __LINE__));
1931 		if (offset & 0x0003) {
1932 			bwn_shm_ctlword(mac, way, offset >> 2);
1933 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1934 			return;
1935 		}
1936 		offset >>= 2;
1937 	}
1938 	bwn_shm_ctlword(mac, way, offset);
1939 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1940 }
1941 
1942 static void
1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1944     int txpow)
1945 {
1946 
1947 	c->ic_freq = freq;
1948 	c->ic_flags = flags;
1949 	c->ic_ieee = ieee;
1950 	c->ic_minpower = 0;
1951 	c->ic_maxpower = 2 * txpow;
1952 	c->ic_maxregpower = txpow;
1953 }
1954 
1955 static void
1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1957     const struct bwn_channelinfo *ci, int flags)
1958 {
1959 	struct ieee80211_channel *c;
1960 	int i;
1961 
1962 	c = &chans[*nchans];
1963 
1964 	for (i = 0; i < ci->nchannels; i++) {
1965 		const struct bwn_channel *hc;
1966 
1967 		hc = &ci->channels[i];
1968 		if (*nchans >= maxchans)
1969 			break;
1970 		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1971 		c++, (*nchans)++;
1972 		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1973 			/* g channel have a separate b-only entry */
1974 			if (*nchans >= maxchans)
1975 				break;
1976 			c[0] = c[-1];
1977 			c[-1].ic_flags = IEEE80211_CHAN_B;
1978 			c++, (*nchans)++;
1979 		}
1980 		if (flags == IEEE80211_CHAN_HTG) {
1981 			/* HT g channel have a separate g-only entry */
1982 			if (*nchans >= maxchans)
1983 				break;
1984 			c[-1].ic_flags = IEEE80211_CHAN_G;
1985 			c[0] = c[-1];
1986 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1987 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
1988 			c++, (*nchans)++;
1989 		}
1990 		if (flags == IEEE80211_CHAN_HTA) {
1991 			/* HT a channel have a separate a-only entry */
1992 			if (*nchans >= maxchans)
1993 				break;
1994 			c[-1].ic_flags = IEEE80211_CHAN_A;
1995 			c[0] = c[-1];
1996 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1997 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
1998 			c++, (*nchans)++;
1999 		}
2000 	}
2001 }
2002 
2003 static int
2004 bwn_phy_g_attach(struct bwn_mac *mac)
2005 {
2006 	struct bwn_softc *sc = mac->mac_sc;
2007 	struct bwn_phy *phy = &mac->mac_phy;
2008 	struct bwn_phy_g *pg = &phy->phy_g;
2009 	unsigned int i;
2010 	int16_t pab0, pab1, pab2;
2011 	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2012 	int8_t bg;
2013 
2014 	bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2015 	pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2016 	pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2017 	pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2018 
2019 	if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2020 		device_printf(sc->sc_dev, "not supported anymore\n");
2021 
2022 	pg->pg_flags = 0;
2023 	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2024 	    pab2 == -1) {
2025 		pg->pg_idletssi = 52;
2026 		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2027 		return (0);
2028 	}
2029 
2030 	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2031 	pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO);
2032 	for (i = 0; i < 64; i++) {
2033 		int32_t m1, m2, f, q, delta;
2034 		int8_t j = 0;
2035 
2036 		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2037 		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2038 		f = 256;
2039 
2040 		do {
2041 			if (j > 15) {
2042 				device_printf(sc->sc_dev,
2043 				    "failed to generate tssi2dBm\n");
2044 				kfree(pg->pg_tssi2dbm, M_DEVBUF);
2045 				return (ENOMEM);
2046 			}
2047 			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2048 			    f, 2048);
2049 			delta = abs(q - f);
2050 			f = q;
2051 			j++;
2052 		} while (delta >= 2);
2053 
2054 		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2055 		    128);
2056 	}
2057 
2058 	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2059 	return (0);
2060 }
2061 
2062 static void
2063 bwn_phy_g_detach(struct bwn_mac *mac)
2064 {
2065 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2066 
2067 	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2068 		kfree(pg->pg_tssi2dbm, M_DEVBUF);
2069 		pg->pg_tssi2dbm = NULL;
2070 	}
2071 	pg->pg_flags = 0;
2072 }
2073 
2074 static void
2075 bwn_phy_g_init_pre(struct bwn_mac *mac)
2076 {
2077 	struct bwn_phy *phy = &mac->mac_phy;
2078 	struct bwn_phy_g *pg = &phy->phy_g;
2079 	void *tssi2dbm;
2080 	int idletssi;
2081 	unsigned int i;
2082 
2083 	tssi2dbm = pg->pg_tssi2dbm;
2084 	idletssi = pg->pg_idletssi;
2085 
2086 	memset(pg, 0, sizeof(*pg));
2087 
2088 	pg->pg_tssi2dbm = tssi2dbm;
2089 	pg->pg_idletssi = idletssi;
2090 
2091 	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2092 
2093 	for (i = 0; i < N(pg->pg_nrssi); i++)
2094 		pg->pg_nrssi[i] = -1000;
2095 	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2096 		pg->pg_nrssi_lt[i] = i;
2097 	pg->pg_lofcal = 0xffff;
2098 	pg->pg_initval = 0xffff;
2099 	pg->pg_immode = BWN_IMMODE_NONE;
2100 	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2101 	pg->pg_avgtssi = 0xff;
2102 
2103 	pg->pg_loctl.tx_bias = 0xff;
2104 	TAILQ_INIT(&pg->pg_loctl.calib_list);
2105 }
2106 
2107 static int
2108 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2109 {
2110 	struct bwn_phy *phy = &mac->mac_phy;
2111 	struct bwn_phy_g *pg = &phy->phy_g;
2112 	struct bwn_softc *sc = mac->mac_sc;
2113 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2114 	static const struct bwn_rfatt rfatt0[] = {
2115 		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
2116 		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2117 		{ 3, 1 }, { 4, 1 }
2118 	};
2119 	static const struct bwn_rfatt rfatt1[] = {
2120 		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2121 		{ 14, 1 }
2122 	};
2123 	static const struct bwn_rfatt rfatt2[] = {
2124 		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2125 		{ 9, 1 }
2126 	};
2127 	static const struct bwn_bbatt bbatt_0[] = {
2128 		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2129 	};
2130 
2131 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2132 
2133 	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2134 		pg->pg_bbatt.att = 0;
2135 	else
2136 		pg->pg_bbatt.att = 2;
2137 
2138 	/* prepare Radio Attenuation */
2139 	pg->pg_rfatt.padmix = 0;
2140 
2141 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2142 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2143 		if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2144 			pg->pg_rfatt.att = 2;
2145 			goto done;
2146 		} else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2147 			pg->pg_rfatt.att = 3;
2148 			goto done;
2149 		}
2150 	}
2151 
2152 	if (phy->type == BWN_PHYTYPE_A) {
2153 		pg->pg_rfatt.att = 0x60;
2154 		goto done;
2155 	}
2156 
2157 	switch (phy->rf_ver) {
2158 	case 0x2050:
2159 		switch (phy->rf_rev) {
2160 		case 0:
2161 			pg->pg_rfatt.att = 5;
2162 			goto done;
2163 		case 1:
2164 			if (phy->type == BWN_PHYTYPE_G) {
2165 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2166 				    SIBA_BOARDVENDOR_BCM &&
2167 				    siba_get_pci_subdevice(sc->sc_dev) ==
2168 				    SIBA_BOARD_BCM4309G &&
2169 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2170 					pg->pg_rfatt.att = 3;
2171 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2172 				    SIBA_BOARDVENDOR_BCM &&
2173 				    siba_get_pci_subdevice(sc->sc_dev) ==
2174 				    SIBA_BOARD_BU4306)
2175 					pg->pg_rfatt.att = 3;
2176 				else
2177 					pg->pg_rfatt.att = 1;
2178 			} else {
2179 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2180 				    SIBA_BOARDVENDOR_BCM &&
2181 				    siba_get_pci_subdevice(sc->sc_dev) ==
2182 				    SIBA_BOARD_BCM4309G &&
2183 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2184 					pg->pg_rfatt.att = 7;
2185 				else
2186 					pg->pg_rfatt.att = 6;
2187 			}
2188 			goto done;
2189 		case 2:
2190 			if (phy->type == BWN_PHYTYPE_G) {
2191 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2192 				    SIBA_BOARDVENDOR_BCM &&
2193 				    siba_get_pci_subdevice(sc->sc_dev) ==
2194 				    SIBA_BOARD_BCM4309G &&
2195 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2196 					pg->pg_rfatt.att = 3;
2197 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2198 				    SIBA_BOARDVENDOR_BCM &&
2199 				    siba_get_pci_subdevice(sc->sc_dev) ==
2200 				    SIBA_BOARD_BU4306)
2201 					pg->pg_rfatt.att = 5;
2202 				else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2203 					pg->pg_rfatt.att = 4;
2204 				else
2205 					pg->pg_rfatt.att = 3;
2206 			} else
2207 				pg->pg_rfatt.att = 6;
2208 			goto done;
2209 		case 3:
2210 			pg->pg_rfatt.att = 5;
2211 			goto done;
2212 		case 4:
2213 		case 5:
2214 			pg->pg_rfatt.att = 1;
2215 			goto done;
2216 		case 6:
2217 		case 7:
2218 			pg->pg_rfatt.att = 5;
2219 			goto done;
2220 		case 8:
2221 			pg->pg_rfatt.att = 0xa;
2222 			pg->pg_rfatt.padmix = 1;
2223 			goto done;
2224 		case 9:
2225 		default:
2226 			pg->pg_rfatt.att = 5;
2227 			goto done;
2228 		}
2229 		break;
2230 	case 0x2053:
2231 		switch (phy->rf_rev) {
2232 		case 1:
2233 			pg->pg_rfatt.att = 6;
2234 			goto done;
2235 		}
2236 		break;
2237 	}
2238 	pg->pg_rfatt.att = 5;
2239 done:
2240 	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2241 
2242 	if (!bwn_has_hwpctl(mac)) {
2243 		lo->rfatt.array = rfatt0;
2244 		lo->rfatt.len = N(rfatt0);
2245 		lo->rfatt.min = 0;
2246 		lo->rfatt.max = 9;
2247 		goto genbbatt;
2248 	}
2249 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2250 		lo->rfatt.array = rfatt1;
2251 		lo->rfatt.len = N(rfatt1);
2252 		lo->rfatt.min = 0;
2253 		lo->rfatt.max = 14;
2254 		goto genbbatt;
2255 	}
2256 	lo->rfatt.array = rfatt2;
2257 	lo->rfatt.len = N(rfatt2);
2258 	lo->rfatt.min = 0;
2259 	lo->rfatt.max = 9;
2260 genbbatt:
2261 	lo->bbatt.array = bbatt_0;
2262 	lo->bbatt.len = N(bbatt_0);
2263 	lo->bbatt.min = 0;
2264 	lo->bbatt.max = 8;
2265 
2266 	BWN_READ_4(mac, BWN_MACCTL);
2267 	if (phy->rev == 1) {
2268 		phy->gmode = 0;
2269 		bwn_reset_core(mac, 0);
2270 		bwn_phy_g_init_sub(mac);
2271 		phy->gmode = 1;
2272 		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2273 	}
2274 	return (0);
2275 }
2276 
2277 static uint16_t
2278 bwn_phy_g_txctl(struct bwn_mac *mac)
2279 {
2280 	struct bwn_phy *phy = &mac->mac_phy;
2281 
2282 	if (phy->rf_ver != 0x2050)
2283 		return (0);
2284 	if (phy->rf_rev == 1)
2285 		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2286 	if (phy->rf_rev < 6)
2287 		return (BWN_TXCTL_PA2DB);
2288 	if (phy->rf_rev == 8)
2289 		return (BWN_TXCTL_TXMIX);
2290 	return (0);
2291 }
2292 
2293 static int
2294 bwn_phy_g_init(struct bwn_mac *mac)
2295 {
2296 
2297 	bwn_phy_g_init_sub(mac);
2298 	return (0);
2299 }
2300 
2301 static void
2302 bwn_phy_g_exit(struct bwn_mac *mac)
2303 {
2304 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2305 	struct bwn_lo_calib *cal, *tmp;
2306 
2307 	if (lo == NULL)
2308 		return;
2309 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2310 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2311 		kfree(cal, M_DEVBUF);
2312 	}
2313 }
2314 
2315 static uint16_t
2316 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2317 {
2318 
2319 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2320 	return (BWN_READ_2(mac, BWN_PHYDATA));
2321 }
2322 
2323 static void
2324 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2325 {
2326 
2327 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2328 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
2329 }
2330 
2331 static uint16_t
2332 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2333 {
2334 
2335 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2336 	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2337 	return (BWN_READ_2(mac, BWN_RFDATALO));
2338 }
2339 
2340 static void
2341 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2342 {
2343 
2344 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2345 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
2346 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
2347 }
2348 
2349 static int
2350 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2351 {
2352 
2353 	return (mac->mac_phy.rev >= 6);
2354 }
2355 
2356 static void
2357 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2358 {
2359 	struct bwn_phy *phy = &mac->mac_phy;
2360 	struct bwn_phy_g *pg = &phy->phy_g;
2361 	unsigned int channel;
2362 	uint16_t rfover, rfoverval;
2363 
2364 	if (on) {
2365 		if (phy->rf_on)
2366 			return;
2367 
2368 		BWN_PHY_WRITE(mac, 0x15, 0x8000);
2369 		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2370 		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2371 		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2372 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2373 			    pg->pg_radioctx_over);
2374 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2375 			    pg->pg_radioctx_overval);
2376 			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2377 		}
2378 		channel = phy->chan;
2379 		bwn_phy_g_switch_chan(mac, 6, 1);
2380 		bwn_phy_g_switch_chan(mac, channel, 0);
2381 		return;
2382 	}
2383 
2384 	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2385 	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2386 	pg->pg_radioctx_over = rfover;
2387 	pg->pg_radioctx_overval = rfoverval;
2388 	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2389 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2390 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2391 }
2392 
2393 static int
2394 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2395 {
2396 
2397 	if ((newchan < 1) || (newchan > 14))
2398 		return (EINVAL);
2399 	bwn_phy_g_switch_chan(mac, newchan, 0);
2400 
2401 	return (0);
2402 }
2403 
2404 static uint32_t
2405 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2406 {
2407 
2408 	return (1);
2409 }
2410 
2411 static void
2412 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2413 {
2414 	struct bwn_phy *phy = &mac->mac_phy;
2415 	uint64_t hf;
2416 	int autodiv = 0;
2417 	uint16_t tmp;
2418 
2419 	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2420 		autodiv = 1;
2421 
2422 	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2423 	bwn_hf_write(mac, hf);
2424 
2425 	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2426 	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2427 	    ((autodiv ? BWN_ANTAUTO1 : antenna)
2428 		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
2429 
2430 	if (autodiv) {
2431 		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2432 		if (antenna == BWN_ANTAUTO1)
2433 			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2434 		else
2435 			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2436 		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2437 	}
2438 	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2439 	if (autodiv)
2440 		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2441 	else
2442 		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2443 	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2444 	if (phy->rev >= 2) {
2445 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2446 		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2447 		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2448 		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2449 		    0x15);
2450 		if (phy->rev == 2)
2451 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2452 		else
2453 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2454 			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2455 			    8);
2456 	}
2457 	if (phy->rev >= 6)
2458 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2459 
2460 	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2461 	bwn_hf_write(mac, hf);
2462 }
2463 
2464 static int
2465 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2466 {
2467 	struct bwn_phy *phy = &mac->mac_phy;
2468 	struct bwn_phy_g *pg = &phy->phy_g;
2469 
2470 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2471 	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2472 
2473 	if (phy->rev == 0 || !phy->gmode)
2474 		return (ENODEV);
2475 
2476 	pg->pg_aci_wlan_automatic = 0;
2477 	return (0);
2478 }
2479 
2480 static int
2481 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2482 {
2483 	struct bwn_phy *phy = &mac->mac_phy;
2484 	struct bwn_phy_g *pg = &phy->phy_g;
2485 	struct bwn_softc *sc = mac->mac_sc;
2486 	unsigned int tssi;
2487 	int cck, ofdm;
2488 	int power;
2489 	int rfatt, bbatt;
2490 	unsigned int max;
2491 
2492 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2493 
2494 	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2495 	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2496 	if (cck < 0 && ofdm < 0) {
2497 		if (ignore_tssi == 0)
2498 			return (BWN_TXPWR_RES_DONE);
2499 		cck = 0;
2500 		ofdm = 0;
2501 	}
2502 	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2503 	if (pg->pg_avgtssi != 0xff)
2504 		tssi = (tssi + pg->pg_avgtssi) / 2;
2505 	pg->pg_avgtssi = tssi;
2506 	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2507 
2508 	max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2509 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2510 		max -= 3;
2511 	if (max >= 120) {
2512 		device_printf(sc->sc_dev, "invalid max TX-power value\n");
2513 		max = 80;
2514 		siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2515 	}
2516 
2517 	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2518 	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2519 	     tssi, 0x00), 0x3f)]);
2520 	if (power == 0)
2521 		return (BWN_TXPWR_RES_DONE);
2522 
2523 	rfatt = -((power + 7) / 8);
2524 	bbatt = (-(power / 2)) - (4 * rfatt);
2525 	if ((rfatt == 0) && (bbatt == 0))
2526 		return (BWN_TXPWR_RES_DONE);
2527 	pg->pg_bbatt_delta = bbatt;
2528 	pg->pg_rfatt_delta = rfatt;
2529 	return (BWN_TXPWR_RES_NEED_ADJUST);
2530 }
2531 
2532 static void
2533 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2534 {
2535 	struct bwn_phy *phy = &mac->mac_phy;
2536 	struct bwn_phy_g *pg = &phy->phy_g;
2537 	struct bwn_softc *sc = mac->mac_sc;
2538 	int rfatt, bbatt;
2539 	uint8_t txctl;
2540 
2541 	bwn_mac_suspend(mac);
2542 
2543 	bbatt = pg->pg_bbatt.att;
2544 	bbatt += pg->pg_bbatt_delta;
2545 	rfatt = pg->pg_rfatt.att;
2546 	rfatt += pg->pg_rfatt_delta;
2547 
2548 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2549 	txctl = pg->pg_txctl;
2550 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2551 		if (rfatt <= 1) {
2552 			if (txctl == 0) {
2553 				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2554 				rfatt += 2;
2555 				bbatt += 2;
2556 			} else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2557 			    BWN_BFL_PACTRL) {
2558 				bbatt += 4 * (rfatt - 2);
2559 				rfatt = 2;
2560 			}
2561 		} else if (rfatt > 4 && txctl) {
2562 			txctl = 0;
2563 			if (bbatt < 3) {
2564 				rfatt -= 3;
2565 				bbatt += 2;
2566 			} else {
2567 				rfatt -= 2;
2568 				bbatt -= 2;
2569 			}
2570 		}
2571 	}
2572 	pg->pg_txctl = txctl;
2573 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2574 	pg->pg_rfatt.att = rfatt;
2575 	pg->pg_bbatt.att = bbatt;
2576 
2577 	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2578 
2579 	bwn_phy_lock(mac);
2580 	bwn_rf_lock(mac);
2581 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2582 	    pg->pg_txctl);
2583 	bwn_rf_unlock(mac);
2584 	bwn_phy_unlock(mac);
2585 
2586 	bwn_mac_enable(mac);
2587 }
2588 
2589 static void
2590 bwn_phy_g_task_15s(struct bwn_mac *mac)
2591 {
2592 	struct bwn_phy *phy = &mac->mac_phy;
2593 	struct bwn_phy_g *pg = &phy->phy_g;
2594 	struct bwn_softc *sc = mac->mac_sc;
2595 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2596 	unsigned long expire, now;
2597 	struct bwn_lo_calib *cal, *tmp;
2598 	uint8_t expired = 0;
2599 
2600 	bwn_mac_suspend(mac);
2601 
2602 	if (lo == NULL)
2603 		goto fail;
2604 
2605 	BWN_GETTIME(now);
2606 	if (bwn_has_hwpctl(mac)) {
2607 		expire = now - BWN_LO_PWRVEC_EXPIRE;
2608 		if (time_before(lo->pwr_vec_read_time, expire)) {
2609 			bwn_lo_get_powervector(mac);
2610 			bwn_phy_g_dc_lookup_init(mac, 0);
2611 		}
2612 		goto fail;
2613 	}
2614 
2615 	expire = now - BWN_LO_CALIB_EXPIRE;
2616 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2617 		if (!time_before(cal->calib_time, expire))
2618 			continue;
2619 		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2620 		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2621 			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2622 			expired = 1;
2623 		}
2624 
2625 		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2626 		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2627 		    cal->ctl.i, cal->ctl.q);
2628 
2629 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2630 		kfree(cal, M_DEVBUF);
2631 	}
2632 	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2633 		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2634 		    &pg->pg_rfatt);
2635 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
2636 			device_printf(sc->sc_dev,
2637 			    "failed to recalibrate LO\n");
2638 			goto fail;
2639 		}
2640 		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2641 		bwn_lo_write(mac, &cal->ctl);
2642 	}
2643 
2644 fail:
2645 	bwn_mac_enable(mac);
2646 }
2647 
2648 static void
2649 bwn_phy_g_task_60s(struct bwn_mac *mac)
2650 {
2651 	struct bwn_phy *phy = &mac->mac_phy;
2652 	struct bwn_softc *sc = mac->mac_sc;
2653 	uint8_t old = phy->chan;
2654 
2655 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2656 		return;
2657 
2658 	bwn_mac_suspend(mac);
2659 	bwn_nrssi_slope_11g(mac);
2660 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2661 		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2662 		bwn_switch_channel(mac, old);
2663 	}
2664 	bwn_mac_enable(mac);
2665 }
2666 
2667 static void
2668 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2669 {
2670 
2671 	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2672 }
2673 
2674 static int
2675 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2676 	const struct ieee80211_bpf_params *params)
2677 {
2678 	struct ieee80211com *ic = ni->ni_ic;
2679 	struct ifnet *ifp = ic->ic_ifp;
2680 	struct bwn_softc *sc = ic->ic_softc;
2681 	struct bwn_mac *mac = sc->sc_curmac;
2682 
2683 	if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2684 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
2685 		ieee80211_free_node(ni);
2686 		m_freem(m);
2687 		return (ENETDOWN);
2688 	}
2689 
2690 	if (bwn_tx_isfull(sc, m)) {
2691 		ieee80211_free_node(ni);
2692 		m_freem(m);
2693 		ifp->if_oerrors++;
2694 		return (ENOBUFS);
2695 	}
2696 
2697 	if (bwn_tx_start(sc, ni, m) != 0) {
2698 		if (ni != NULL)
2699 			ieee80211_free_node(ni);
2700 		ifp->if_oerrors++;
2701 	}
2702 	sc->sc_watchdog_timer = 5;
2703 	return (0);
2704 }
2705 
2706 /*
2707  * Callback from the 802.11 layer to update the slot time
2708  * based on the current setting.  We use it to notify the
2709  * firmware of ERP changes and the f/w takes care of things
2710  * like slot time and preamble.
2711  */
2712 static void
2713 bwn_updateslot(struct ieee80211com *ic)
2714 {
2715 	struct bwn_softc *sc = ic->ic_softc;
2716 	struct bwn_mac *mac;
2717 
2718 	if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
2719 		mac = (struct bwn_mac *)sc->sc_curmac;
2720 		bwn_set_slot_time(mac,
2721 		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2722 	}
2723 }
2724 
2725 /*
2726  * Callback from the 802.11 layer after a promiscuous mode change.
2727  * Note this interface does not check the operating mode as this
2728  * is an internal callback and we are expected to honor the current
2729  * state (e.g. this is used for setting the interface in promiscuous
2730  * mode when operating in hostap mode to do ACS).
2731  */
2732 static void
2733 bwn_update_promisc(struct ieee80211com *ic)
2734 {
2735 	struct bwn_softc *sc = ic->ic_softc;
2736 	struct bwn_mac *mac = sc->sc_curmac;
2737 
2738 	mac = sc->sc_curmac;
2739 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2740 		if (ic->ic_ifp->if_flags & IFF_PROMISC)
2741 			sc->sc_filters |= BWN_MACCTL_PROMISC;
2742 		else
2743 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2744 		bwn_set_opmode(mac);
2745 	}
2746 }
2747 
2748 /*
2749  * Callback from the 802.11 layer to update WME parameters.
2750  */
2751 static int
2752 bwn_wme_update(struct ieee80211com *ic)
2753 {
2754 	struct bwn_softc *sc = ic->ic_softc;
2755 	struct bwn_mac *mac = sc->sc_curmac;
2756 	struct wmeParams *wmep;
2757 	int i;
2758 
2759 	mac = sc->sc_curmac;
2760 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2761 		bwn_mac_suspend(mac);
2762 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
2763 			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2764 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2765 		}
2766 		bwn_mac_enable(mac);
2767 	}
2768 	return (0);
2769 }
2770 
2771 static void
2772 bwn_scan_start(struct ieee80211com *ic)
2773 {
2774 	struct bwn_softc *sc = ic->ic_softc;
2775 	struct bwn_mac *mac;
2776 
2777 	mac = sc->sc_curmac;
2778 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2779 		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2780 		bwn_set_opmode(mac);
2781 		/* disable CFP update during scan */
2782 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2783 	}
2784 }
2785 
2786 static void
2787 bwn_scan_end(struct ieee80211com *ic)
2788 {
2789 	struct bwn_softc *sc = ic->ic_softc;
2790 	struct bwn_mac *mac;
2791 
2792 	mac = sc->sc_curmac;
2793 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2794 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2795 		bwn_set_opmode(mac);
2796 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2797 	}
2798 }
2799 
2800 static void
2801 bwn_set_channel(struct ieee80211com *ic)
2802 {
2803 	struct bwn_softc *sc = ic->ic_softc;
2804 	struct bwn_mac *mac = sc->sc_curmac;
2805 	struct bwn_phy *phy = &mac->mac_phy;
2806 	int chan, error;
2807 
2808 	error = bwn_switch_band(sc, ic->ic_curchan);
2809 	if (error)
2810 		goto fail;
2811 	bwn_mac_suspend(mac);
2812 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2813 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2814 	if (chan != phy->chan)
2815 		bwn_switch_channel(mac, chan);
2816 
2817 	/* TX power level */
2818 	if (ic->ic_curchan->ic_maxpower != 0 &&
2819 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
2820 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2821 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2822 		    BWN_TXPWR_IGNORE_TSSI);
2823 	}
2824 
2825 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2826 	if (phy->set_antenna)
2827 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2828 
2829 	if (sc->sc_rf_enabled != phy->rf_on) {
2830 		if (sc->sc_rf_enabled) {
2831 			bwn_rf_turnon(mac);
2832 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2833 				device_printf(sc->sc_dev,
2834 				    "please turn on the RF switch\n");
2835 		} else
2836 			bwn_rf_turnoff(mac);
2837 	}
2838 
2839 	bwn_mac_enable(mac);
2840 
2841 fail:
2842 	/*
2843 	 * Setup radio tap channel freq and flags
2844 	 */
2845 	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2846 		htole16(ic->ic_curchan->ic_freq);
2847 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2848 		htole16(ic->ic_curchan->ic_flags & 0xffff);
2849 }
2850 
2851 static struct ieee80211vap *
2852 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2853     enum ieee80211_opmode opmode, int flags,
2854     const uint8_t bssid[IEEE80211_ADDR_LEN],
2855     const uint8_t mac0[IEEE80211_ADDR_LEN])
2856 {
2857 	struct bwn_softc *sc = ic->ic_softc;
2858 	struct ieee80211vap *vap;
2859 	struct bwn_vap *bvp;
2860 	uint8_t mac[IEEE80211_ADDR_LEN];
2861 
2862 	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
2863 		return NULL;
2864 
2865 	IEEE80211_ADDR_COPY(mac, mac0);
2866 	switch (opmode) {
2867 	case IEEE80211_M_HOSTAP:
2868 	case IEEE80211_M_MBSS:
2869 	case IEEE80211_M_STA:
2870 	case IEEE80211_M_WDS:
2871 	case IEEE80211_M_MONITOR:
2872 	case IEEE80211_M_IBSS:
2873 	case IEEE80211_M_AHDEMO:
2874 		break;
2875 	default:
2876 		return (NULL);
2877 	}
2878 
2879 	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2880 
2881 	bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap),
2882 	    M_80211_VAP, M_INTWAIT | M_ZERO);
2883 	vap = &bvp->bv_vap;
2884 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2885 	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2886 	/* override with driver methods */
2887 	bvp->bv_newstate = vap->iv_newstate;
2888 	vap->iv_newstate = bwn_newstate;
2889 
2890 	/* override max aid so sta's cannot assoc when we're out of sta id's */
2891 	vap->iv_max_aid = BWN_STAID_MAX;
2892 
2893 	ieee80211_ratectl_init(vap);
2894 
2895 	/* complete setup */
2896 	ieee80211_vap_attach(vap, ieee80211_media_change,
2897 	    ieee80211_media_status);
2898 	ic->ic_opmode = opmode;
2899 	return (vap);
2900 }
2901 
2902 static void
2903 bwn_vap_delete(struct ieee80211vap *vap)
2904 {
2905 	struct bwn_vap *bvp = BWN_VAP(vap);
2906 
2907 	ieee80211_ratectl_deinit(vap);
2908 	ieee80211_vap_detach(vap);
2909 	kfree(bvp, M_80211_VAP);
2910 }
2911 
2912 static void
2913 bwn_init(void *arg)
2914 {
2915 	struct bwn_softc *sc = arg;
2916 	struct ifnet *ifp = sc->sc_ifp;
2917 	struct ieee80211com *ic = ifp->if_l2com;
2918 	int error = 0;
2919 
2920 	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2921 		__func__, ifp->if_flags);
2922 
2923 	wlan_assert_serialized();
2924 	error = bwn_init_locked(sc);
2925 
2926 	if (error == 0)
2927 		ieee80211_start_all(ic);	/* start all vap's */
2928 }
2929 
2930 static int
2931 bwn_init_locked(struct bwn_softc *sc)
2932 {
2933 	struct bwn_mac *mac;
2934 	struct ifnet *ifp = sc->sc_ifp;
2935 	int error;
2936 
2937 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2938 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2939 	sc->sc_filters = 0;
2940 	bwn_wme_clear(sc);
2941 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2942 	sc->sc_rf_enabled = 1;
2943 
2944 	mac = sc->sc_curmac;
2945 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2946 		error = bwn_core_init(mac);
2947 		if (error != 0)
2948 			return (error);
2949 	}
2950 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
2951 		bwn_core_start(mac);
2952 
2953 	bwn_set_opmode(mac);
2954 	bwn_set_pretbtt(mac);
2955 	bwn_spu_setdelay(mac, 0);
2956 	bwn_set_macaddr(mac);
2957 
2958 	ifp->if_flags |= IFF_RUNNING;
2959 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2960 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2961 
2962 	return (0);
2963 }
2964 
2965 static void
2966 bwn_stop(struct bwn_softc *sc, int statechg)
2967 {
2968 
2969 	wlan_assert_serialized();
2970 	bwn_stop_locked(sc, statechg);
2971 }
2972 
2973 static void
2974 bwn_stop_locked(struct bwn_softc *sc, int statechg)
2975 {
2976 	struct bwn_mac *mac = sc->sc_curmac;
2977 	struct ifnet *ifp = sc->sc_ifp;
2978 
2979 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2980 		/* XXX FIXME opmode not based on VAP */
2981 		bwn_set_opmode(mac);
2982 		bwn_set_macaddr(mac);
2983 	}
2984 
2985 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2986 		bwn_core_stop(mac);
2987 
2988 	callout_stop(&sc->sc_led_blink_ch);
2989 	sc->sc_led_blinking = 0;
2990 
2991 	bwn_core_exit(mac);
2992 	sc->sc_rf_enabled = 0;
2993 
2994 	ifp->if_flags &= ~IFF_RUNNING;
2995 	ifq_clr_oactive(&ifp->if_snd);
2996 }
2997 
2998 static void
2999 bwn_wme_clear(struct bwn_softc *sc)
3000 {
3001 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
3002 	struct wmeParams *p;
3003 	unsigned int i;
3004 
3005 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3006 	    ("%s:%d: fail", __func__, __LINE__));
3007 
3008 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
3009 		p = &(sc->sc_wmeParams[i]);
3010 
3011 		switch (bwn_wme_shm_offsets[i]) {
3012 		case BWN_WME_VOICE:
3013 			p->wmep_txopLimit = 0;
3014 			p->wmep_aifsn = 2;
3015 			/* XXX FIXME: log2(cwmin) */
3016 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3017 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3018 			break;
3019 		case BWN_WME_VIDEO:
3020 			p->wmep_txopLimit = 0;
3021 			p->wmep_aifsn = 2;
3022 			/* XXX FIXME: log2(cwmin) */
3023 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3024 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3025 			break;
3026 		case BWN_WME_BESTEFFORT:
3027 			p->wmep_txopLimit = 0;
3028 			p->wmep_aifsn = 3;
3029 			/* XXX FIXME: log2(cwmin) */
3030 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3031 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3032 			break;
3033 		case BWN_WME_BACKGROUND:
3034 			p->wmep_txopLimit = 0;
3035 			p->wmep_aifsn = 7;
3036 			/* XXX FIXME: log2(cwmin) */
3037 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3038 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3039 			break;
3040 		default:
3041 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3042 		}
3043 	}
3044 }
3045 
3046 static int
3047 bwn_core_init(struct bwn_mac *mac)
3048 {
3049 	struct bwn_softc *sc = mac->mac_sc;
3050 	uint64_t hf;
3051 	int error;
3052 
3053 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3054 	    ("%s:%d: fail", __func__, __LINE__));
3055 
3056 	siba_powerup(sc->sc_dev, 0);
3057 	if (!siba_dev_isup(sc->sc_dev))
3058 		bwn_reset_core(mac,
3059 		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3060 
3061 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3062 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3063 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3064 	BWN_GETTIME(mac->mac_phy.nexttime);
3065 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3066 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3067 	mac->mac_stats.link_noise = -95;
3068 	mac->mac_reason_intr = 0;
3069 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
3070 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3071 #ifdef BWN_DEBUG
3072 	if (sc->sc_debug & BWN_DEBUG_XMIT)
3073 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3074 #endif
3075 	mac->mac_suspended = 1;
3076 	mac->mac_task_state = 0;
3077 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3078 
3079 	mac->mac_phy.init_pre(mac);
3080 
3081 	siba_pcicore_intr(sc->sc_dev);
3082 
3083 	siba_fix_imcfglobug(sc->sc_dev);
3084 	bwn_bt_disable(mac);
3085 	if (mac->mac_phy.prepare_hw) {
3086 		error = mac->mac_phy.prepare_hw(mac);
3087 		if (error)
3088 			goto fail0;
3089 	}
3090 	error = bwn_chip_init(mac);
3091 	if (error)
3092 		goto fail0;
3093 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3094 	    siba_get_revid(sc->sc_dev));
3095 	hf = bwn_hf_read(mac);
3096 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3097 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3098 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3099 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3100 		if (mac->mac_phy.rev == 1)
3101 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3102 	}
3103 	if (mac->mac_phy.rf_ver == 0x2050) {
3104 		if (mac->mac_phy.rf_rev < 6)
3105 			hf |= BWN_HF_FORCE_VCO_RECALC;
3106 		if (mac->mac_phy.rf_rev == 6)
3107 			hf |= BWN_HF_4318_TSSI;
3108 	}
3109 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3110 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3111 	if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3112 	    (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3113 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3114 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3115 	bwn_hf_write(mac, hf);
3116 
3117 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3118 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3119 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3120 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3121 
3122 	bwn_rate_init(mac);
3123 	bwn_set_phytxctl(mac);
3124 
3125 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3126 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3127 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3128 
3129 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3130 		bwn_pio_init(mac);
3131 	else
3132 		bwn_dma_init(mac);
3133 	bwn_wme_init(mac);
3134 	bwn_spu_setdelay(mac, 1);
3135 	bwn_bt_enable(mac);
3136 
3137 	siba_powerup(sc->sc_dev,
3138 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3139 	bwn_set_macaddr(mac);
3140 	bwn_crypt_init(mac);
3141 
3142 	/* XXX LED initializatin */
3143 
3144 	mac->mac_status = BWN_MAC_STATUS_INITED;
3145 
3146 	return (error);
3147 
3148 fail0:
3149 	siba_powerdown(sc->sc_dev);
3150 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3151 	    ("%s:%d: fail", __func__, __LINE__));
3152 	return (error);
3153 }
3154 
3155 static void
3156 bwn_core_start(struct bwn_mac *mac)
3157 {
3158 	struct bwn_softc *sc = mac->mac_sc;
3159 	uint32_t tmp;
3160 
3161 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3162 	    ("%s:%d: fail", __func__, __LINE__));
3163 
3164 	if (siba_get_revid(sc->sc_dev) < 5)
3165 		return;
3166 
3167 	while (1) {
3168 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3169 		if (!(tmp & 0x00000001))
3170 			break;
3171 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3172 	}
3173 
3174 	bwn_mac_enable(mac);
3175 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3176 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3177 
3178 	mac->mac_status = BWN_MAC_STATUS_STARTED;
3179 }
3180 
3181 static void
3182 bwn_core_exit(struct bwn_mac *mac)
3183 {
3184 	struct bwn_softc *sc = mac->mac_sc;
3185 	uint32_t macctl;
3186 
3187 	wlan_assert_serialized();
3188 
3189 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3190 	    ("%s:%d: fail", __func__, __LINE__));
3191 
3192 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
3193 		return;
3194 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
3195 
3196 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3197 	macctl &= ~BWN_MACCTL_MCODE_RUN;
3198 	macctl |= BWN_MACCTL_MCODE_JMP0;
3199 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3200 
3201 	bwn_dma_stop(mac);
3202 	bwn_pio_stop(mac);
3203 	bwn_chip_exit(mac);
3204 	mac->mac_phy.switch_analog(mac, 0);
3205 	siba_dev_down(sc->sc_dev, 0);
3206 	siba_powerdown(sc->sc_dev);
3207 }
3208 
3209 static void
3210 bwn_bt_disable(struct bwn_mac *mac)
3211 {
3212 	struct bwn_softc *sc = mac->mac_sc;
3213 
3214 	(void)sc;
3215 	/* XXX do nothing yet */
3216 }
3217 
3218 static int
3219 bwn_chip_init(struct bwn_mac *mac)
3220 {
3221 	struct bwn_softc *sc = mac->mac_sc;
3222 	struct bwn_phy *phy = &mac->mac_phy;
3223 	uint32_t macctl;
3224 	int error;
3225 
3226 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3227 	if (phy->gmode)
3228 		macctl |= BWN_MACCTL_GMODE;
3229 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3230 
3231 	error = bwn_fw_fillinfo(mac);
3232 	if (error)
3233 		return (error);
3234 	error = bwn_fw_loaducode(mac);
3235 	if (error)
3236 		return (error);
3237 
3238 	error = bwn_gpio_init(mac);
3239 	if (error)
3240 		return (error);
3241 
3242 	error = bwn_fw_loadinitvals(mac);
3243 	if (error) {
3244 		siba_gpio_set(sc->sc_dev, 0);
3245 		return (error);
3246 	}
3247 	phy->switch_analog(mac, 1);
3248 	error = bwn_phy_init(mac);
3249 	if (error) {
3250 		siba_gpio_set(sc->sc_dev, 0);
3251 		return (error);
3252 	}
3253 	if (phy->set_im)
3254 		phy->set_im(mac, BWN_IMMODE_NONE);
3255 	if (phy->set_antenna)
3256 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
3257 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3258 
3259 	if (phy->type == BWN_PHYTYPE_B)
3260 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3261 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
3262 	if (siba_get_revid(sc->sc_dev) < 5)
3263 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
3264 
3265 	BWN_WRITE_4(mac, BWN_MACCTL,
3266 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3267 	BWN_WRITE_4(mac, BWN_MACCTL,
3268 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3269 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3270 
3271 	bwn_set_opmode(mac);
3272 	if (siba_get_revid(sc->sc_dev) < 3) {
3273 		BWN_WRITE_2(mac, 0x060e, 0x0000);
3274 		BWN_WRITE_2(mac, 0x0610, 0x8000);
3275 		BWN_WRITE_2(mac, 0x0604, 0x0000);
3276 		BWN_WRITE_2(mac, 0x0606, 0x0200);
3277 	} else {
3278 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
3279 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
3280 	}
3281 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3282 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00);
3283 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3284 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3285 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3286 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3287 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3288 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3289 	    siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3290 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3291 	return (error);
3292 }
3293 
3294 /* read hostflags */
3295 static uint64_t
3296 bwn_hf_read(struct bwn_mac *mac)
3297 {
3298 	uint64_t ret;
3299 
3300 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3301 	ret <<= 16;
3302 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3303 	ret <<= 16;
3304 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3305 	return (ret);
3306 }
3307 
3308 static void
3309 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3310 {
3311 
3312 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3313 	    (value & 0x00000000ffffull));
3314 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3315 	    (value & 0x0000ffff0000ull) >> 16);
3316 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3317 	    (value & 0xffff00000000ULL) >> 32);
3318 }
3319 
3320 static void
3321 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3322 {
3323 
3324 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3325 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3326 }
3327 
3328 static void
3329 bwn_rate_init(struct bwn_mac *mac)
3330 {
3331 
3332 	switch (mac->mac_phy.type) {
3333 	case BWN_PHYTYPE_A:
3334 	case BWN_PHYTYPE_G:
3335 	case BWN_PHYTYPE_LP:
3336 	case BWN_PHYTYPE_N:
3337 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3338 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3339 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3340 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3341 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3342 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3343 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3344 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
3345 			break;
3346 		/* FALLTHROUGH */
3347 	case BWN_PHYTYPE_B:
3348 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3349 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3350 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3351 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3352 		break;
3353 	default:
3354 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3355 	}
3356 }
3357 
3358 static void
3359 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3360 {
3361 	uint16_t offset;
3362 
3363 	if (ofdm) {
3364 		offset = 0x480;
3365 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3366 	} else {
3367 		offset = 0x4c0;
3368 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3369 	}
3370 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3371 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
3372 }
3373 
3374 static uint8_t
3375 bwn_plcp_getcck(const uint8_t bitrate)
3376 {
3377 
3378 	switch (bitrate) {
3379 	case BWN_CCK_RATE_1MB:
3380 		return (0x0a);
3381 	case BWN_CCK_RATE_2MB:
3382 		return (0x14);
3383 	case BWN_CCK_RATE_5MB:
3384 		return (0x37);
3385 	case BWN_CCK_RATE_11MB:
3386 		return (0x6e);
3387 	}
3388 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3389 	return (0);
3390 }
3391 
3392 static uint8_t
3393 bwn_plcp_getofdm(const uint8_t bitrate)
3394 {
3395 
3396 	switch (bitrate) {
3397 	case BWN_OFDM_RATE_6MB:
3398 		return (0xb);
3399 	case BWN_OFDM_RATE_9MB:
3400 		return (0xf);
3401 	case BWN_OFDM_RATE_12MB:
3402 		return (0xa);
3403 	case BWN_OFDM_RATE_18MB:
3404 		return (0xe);
3405 	case BWN_OFDM_RATE_24MB:
3406 		return (0x9);
3407 	case BWN_OFDM_RATE_36MB:
3408 		return (0xd);
3409 	case BWN_OFDM_RATE_48MB:
3410 		return (0x8);
3411 	case BWN_OFDM_RATE_54MB:
3412 		return (0xc);
3413 	}
3414 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3415 	return (0);
3416 }
3417 
3418 static void
3419 bwn_set_phytxctl(struct bwn_mac *mac)
3420 {
3421 	uint16_t ctl;
3422 
3423 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3424 	    BWN_TX_PHY_TXPWR);
3425 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3426 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3427 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3428 }
3429 
3430 static void
3431 bwn_pio_init(struct bwn_mac *mac)
3432 {
3433 	struct bwn_pio *pio = &mac->mac_method.pio;
3434 
3435 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3436 	    & ~BWN_MACCTL_BIGENDIAN);
3437 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3438 
3439 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3440 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3441 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3442 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3443 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3444 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3445 }
3446 
3447 static void
3448 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3449     int index)
3450 {
3451 	struct bwn_pio_txpkt *tp;
3452 	struct bwn_softc *sc = mac->mac_sc;
3453 	unsigned int i;
3454 
3455 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3456 	tq->tq_index = index;
3457 
3458 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3459 	if (siba_get_revid(sc->sc_dev) >= 8)
3460 		tq->tq_size = 1920;
3461 	else {
3462 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3463 		tq->tq_size -= 80;
3464 	}
3465 
3466 	TAILQ_INIT(&tq->tq_pktlist);
3467 	for (i = 0; i < N(tq->tq_pkts); i++) {
3468 		tp = &(tq->tq_pkts[i]);
3469 		tp->tp_index = i;
3470 		tp->tp_queue = tq;
3471 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3472 	}
3473 }
3474 
3475 static uint16_t
3476 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3477 {
3478 	struct bwn_softc *sc = mac->mac_sc;
3479 	static const uint16_t bases[] = {
3480 		BWN_PIO_BASE0,
3481 		BWN_PIO_BASE1,
3482 		BWN_PIO_BASE2,
3483 		BWN_PIO_BASE3,
3484 		BWN_PIO_BASE4,
3485 		BWN_PIO_BASE5,
3486 		BWN_PIO_BASE6,
3487 		BWN_PIO_BASE7,
3488 	};
3489 	static const uint16_t bases_rev11[] = {
3490 		BWN_PIO11_BASE0,
3491 		BWN_PIO11_BASE1,
3492 		BWN_PIO11_BASE2,
3493 		BWN_PIO11_BASE3,
3494 		BWN_PIO11_BASE4,
3495 		BWN_PIO11_BASE5,
3496 	};
3497 
3498 	if (siba_get_revid(sc->sc_dev) >= 11) {
3499 		if (index >= N(bases_rev11))
3500 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
3501 		return (bases_rev11[index]);
3502 	}
3503 	if (index >= N(bases))
3504 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
3505 	return (bases[index]);
3506 }
3507 
3508 static void
3509 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3510     int index)
3511 {
3512 	struct bwn_softc *sc = mac->mac_sc;
3513 
3514 	prq->prq_mac = mac;
3515 	prq->prq_rev = siba_get_revid(sc->sc_dev);
3516 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3517 	bwn_dma_rxdirectfifo(mac, index, 1);
3518 }
3519 
3520 static void
3521 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3522 {
3523 	if (tq == NULL)
3524 		return;
3525 	bwn_pio_cancel_tx_packets(tq);
3526 }
3527 
3528 static void
3529 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3530 {
3531 
3532 	bwn_destroy_pioqueue_tx(pio);
3533 }
3534 
3535 static uint16_t
3536 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3537     uint16_t offset)
3538 {
3539 
3540 	return (BWN_READ_2(mac, tq->tq_base + offset));
3541 }
3542 
3543 static void
3544 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3545 {
3546 	uint32_t ctl;
3547 	int type;
3548 	uint16_t base;
3549 
3550 	type = bwn_dma_mask2type(bwn_dma_mask(mac));
3551 	base = bwn_dma_base(type, idx);
3552 	if (type == BWN_DMA_64BIT) {
3553 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3554 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3555 		if (enable)
3556 			ctl |= BWN_DMA64_RXDIRECTFIFO;
3557 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3558 	} else {
3559 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3560 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3561 		if (enable)
3562 			ctl |= BWN_DMA32_RXDIRECTFIFO;
3563 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3564 	}
3565 }
3566 
3567 static uint64_t
3568 bwn_dma_mask(struct bwn_mac *mac)
3569 {
3570 	uint32_t tmp;
3571 	uint16_t base;
3572 
3573 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3574 	if (tmp & SIBA_TGSHIGH_DMA64)
3575 		return (BWN_DMA_BIT_MASK(64));
3576 	base = bwn_dma_base(0, 0);
3577 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3578 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3579 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
3580 		return (BWN_DMA_BIT_MASK(32));
3581 
3582 	return (BWN_DMA_BIT_MASK(30));
3583 }
3584 
3585 static int
3586 bwn_dma_mask2type(uint64_t dmamask)
3587 {
3588 
3589 	if (dmamask == BWN_DMA_BIT_MASK(30))
3590 		return (BWN_DMA_30BIT);
3591 	if (dmamask == BWN_DMA_BIT_MASK(32))
3592 		return (BWN_DMA_32BIT);
3593 	if (dmamask == BWN_DMA_BIT_MASK(64))
3594 		return (BWN_DMA_64BIT);
3595 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3596 	return (BWN_DMA_30BIT);
3597 }
3598 
3599 static void
3600 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3601 {
3602 	struct bwn_pio_txpkt *tp;
3603 	unsigned int i;
3604 
3605 	for (i = 0; i < N(tq->tq_pkts); i++) {
3606 		tp = &(tq->tq_pkts[i]);
3607 		if (tp->tp_m) {
3608 			m_freem(tp->tp_m);
3609 			tp->tp_m = NULL;
3610 		}
3611 	}
3612 }
3613 
3614 static uint16_t
3615 bwn_dma_base(int type, int controller_idx)
3616 {
3617 	static const uint16_t map64[] = {
3618 		BWN_DMA64_BASE0,
3619 		BWN_DMA64_BASE1,
3620 		BWN_DMA64_BASE2,
3621 		BWN_DMA64_BASE3,
3622 		BWN_DMA64_BASE4,
3623 		BWN_DMA64_BASE5,
3624 	};
3625 	static const uint16_t map32[] = {
3626 		BWN_DMA32_BASE0,
3627 		BWN_DMA32_BASE1,
3628 		BWN_DMA32_BASE2,
3629 		BWN_DMA32_BASE3,
3630 		BWN_DMA32_BASE4,
3631 		BWN_DMA32_BASE5,
3632 	};
3633 
3634 	if (type == BWN_DMA_64BIT) {
3635 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3636 		    ("%s:%d: fail", __func__, __LINE__));
3637 		return (map64[controller_idx]);
3638 	}
3639 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3640 	    ("%s:%d: fail", __func__, __LINE__));
3641 	return (map32[controller_idx]);
3642 }
3643 
3644 static void
3645 bwn_dma_init(struct bwn_mac *mac)
3646 {
3647 	struct bwn_dma *dma = &mac->mac_method.dma;
3648 
3649 	/* setup TX DMA channels. */
3650 	bwn_dma_setup(dma->wme[WME_AC_BK]);
3651 	bwn_dma_setup(dma->wme[WME_AC_BE]);
3652 	bwn_dma_setup(dma->wme[WME_AC_VI]);
3653 	bwn_dma_setup(dma->wme[WME_AC_VO]);
3654 	bwn_dma_setup(dma->mcast);
3655 	/* setup RX DMA channel. */
3656 	bwn_dma_setup(dma->rx);
3657 }
3658 
3659 static struct bwn_dma_ring *
3660 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3661     int for_tx, int type)
3662 {
3663 	struct bwn_dma *dma = &mac->mac_method.dma;
3664 	struct bwn_dma_ring *dr;
3665 	struct bwn_dmadesc_generic *desc;
3666 	struct bwn_dmadesc_meta *mt;
3667 	struct bwn_softc *sc = mac->mac_sc;
3668 	int error, i;
3669 
3670 	dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO);
3671 	dr->dr_numslots = BWN_RXRING_SLOTS;
3672 	if (for_tx)
3673 		dr->dr_numslots = BWN_TXRING_SLOTS;
3674 
3675 	dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3676 	    M_DEVBUF, M_INTWAIT | M_ZERO);
3677 
3678 	dr->dr_type = type;
3679 	dr->dr_mac = mac;
3680 	dr->dr_base = bwn_dma_base(type, controller_index);
3681 	dr->dr_index = controller_index;
3682 	if (type == BWN_DMA_64BIT) {
3683 		dr->getdesc = bwn_dma_64_getdesc;
3684 		dr->setdesc = bwn_dma_64_setdesc;
3685 		dr->start_transfer = bwn_dma_64_start_transfer;
3686 		dr->suspend = bwn_dma_64_suspend;
3687 		dr->resume = bwn_dma_64_resume;
3688 		dr->get_curslot = bwn_dma_64_get_curslot;
3689 		dr->set_curslot = bwn_dma_64_set_curslot;
3690 	} else {
3691 		dr->getdesc = bwn_dma_32_getdesc;
3692 		dr->setdesc = bwn_dma_32_setdesc;
3693 		dr->start_transfer = bwn_dma_32_start_transfer;
3694 		dr->suspend = bwn_dma_32_suspend;
3695 		dr->resume = bwn_dma_32_resume;
3696 		dr->get_curslot = bwn_dma_32_get_curslot;
3697 		dr->set_curslot = bwn_dma_32_set_curslot;
3698 	}
3699 	if (for_tx) {
3700 		dr->dr_tx = 1;
3701 		dr->dr_curslot = -1;
3702 	} else {
3703 		if (dr->dr_index == 0) {
3704 			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3705 			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3706 		} else
3707 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3708 	}
3709 
3710 	error = bwn_dma_allocringmemory(dr);
3711 	if (error)
3712 		goto fail1;
3713 
3714 	if (for_tx) {
3715 		/*
3716 		 * Assumption: BWN_TXRING_SLOTS can be divided by
3717 		 * BWN_TX_SLOTS_PER_FRAME
3718 		 */
3719 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3720 		    ("%s:%d: fail", __func__, __LINE__));
3721 
3722 		/*
3723 		 * Create TX ring DMA stuffs
3724 		 */
3725 		dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag,
3726 		    4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3727 		    BWN_MAX_HDRSIZE(mac),
3728 		    BUS_DMA_WAITOK | BUS_DMA_ZERO,
3729 		    &dr->dr_txring_dtag, &dr->dr_txring_dmap,
3730 		    &dr->dr_txring_paddr);
3731 		if (dr->dr_txhdr_cache == NULL) {
3732 			device_printf(sc->sc_dev,
3733 			    "can't create TX ring DMA memory\n");
3734 			goto fail1;
3735 		}
3736 
3737 		for (i = 0; i < dr->dr_numslots; i += 2) {
3738 			dr->getdesc(dr, i, &desc, &mt);
3739 
3740 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3741 			mt->mt_m = NULL;
3742 			mt->mt_ni = NULL;
3743 			mt->mt_islast = 0;
3744 			mt->mt_dmap = dr->dr_txring_dmap;
3745 			mt->mt_paddr = dr->dr_txring_paddr +
3746 			    (i / BWN_TX_SLOTS_PER_FRAME) *
3747 			    BWN_MAX_HDRSIZE(mac);
3748 
3749 			dr->getdesc(dr, i + 1, &desc, &mt);
3750 
3751 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3752 			mt->mt_m = NULL;
3753 			mt->mt_ni = NULL;
3754 			mt->mt_islast = 1;
3755 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
3756 			    &mt->mt_dmap);
3757 			if (error) {
3758 				device_printf(sc->sc_dev,
3759 				     "can't create RX buf DMA map\n");
3760 				goto fail2;
3761 			}
3762 		}
3763 	} else {
3764 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3765 		    &dr->dr_spare_dmap);
3766 		if (error) {
3767 			device_printf(sc->sc_dev,
3768 			    "can't create RX buf DMA map\n");
3769 			goto out;		/* XXX wrong! */
3770 		}
3771 
3772 		for (i = 0; i < dr->dr_numslots; i++) {
3773 			dr->getdesc(dr, i, &desc, &mt);
3774 
3775 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3776 			    &mt->mt_dmap);
3777 			if (error) {
3778 				device_printf(sc->sc_dev,
3779 				    "can't create RX buf DMA map\n");
3780 				goto out;	/* XXX wrong! */
3781 			}
3782 			error = bwn_dma_newbuf(dr, desc, mt, 1);
3783 			if (error) {
3784 				device_printf(sc->sc_dev,
3785 				    "failed to allocate RX buf\n");
3786 				goto out;	/* XXX wrong! */
3787 			}
3788 		}
3789 
3790 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3791 		    BUS_DMASYNC_PREWRITE);
3792 
3793 		dr->dr_usedslot = dr->dr_numslots;
3794 	}
3795 
3796       out:
3797 	return (dr);
3798 
3799 fail2:
3800 	/* XXX free up dma allocations */
3801 fail1:
3802 	kfree(dr->dr_meta, M_DEVBUF);
3803 	kfree(dr, M_DEVBUF);
3804 	return (NULL);
3805 }
3806 
3807 static void
3808 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3809 {
3810 
3811 	if (dr == NULL)
3812 		return;
3813 
3814 	bwn_dma_free_descbufs(*dr);
3815 	bwn_dma_free_ringmemory(*dr);
3816 
3817 	if ((*dr)->dr_meta != NULL)
3818 		kfree((*dr)->dr_meta, M_DEVBUF);
3819 	kfree(*dr, M_DEVBUF);
3820 
3821 	*dr = NULL;
3822 }
3823 
3824 static void
3825 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3826     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3827 {
3828 	struct bwn_dmadesc32 *desc;
3829 
3830 	*meta = &(dr->dr_meta[slot]);
3831 	desc = dr->dr_ring_descbase;
3832 	desc = &(desc[slot]);
3833 
3834 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3835 }
3836 
3837 static void
3838 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3839     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3840     int start, int end, int irq)
3841 {
3842 	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3843 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3844 	uint32_t addr, addrext, ctl;
3845 	int slot;
3846 
3847 	slot = (int)(&(desc->dma.dma32) - descbase);
3848 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3849 	    ("%s:%d: fail", __func__, __LINE__));
3850 
3851 	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3852 	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3853 	addr |= siba_dma_translation(sc->sc_dev);
3854 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3855 	if (slot == dr->dr_numslots - 1)
3856 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
3857 	if (start)
3858 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
3859 	if (end)
3860 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
3861 	if (irq)
3862 		ctl |= BWN_DMA32_DCTL_IRQ;
3863 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3864 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
3865 
3866 	desc->dma.dma32.control = htole32(ctl);
3867 	desc->dma.dma32.address = htole32(addr);
3868 }
3869 
3870 static void
3871 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3872 {
3873 
3874 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3875 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3876 }
3877 
3878 static void
3879 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3880 {
3881 
3882 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3883 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3884 }
3885 
3886 static void
3887 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3888 {
3889 
3890 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3891 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3892 }
3893 
3894 static int
3895 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3896 {
3897 	uint32_t val;
3898 
3899 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3900 	val &= BWN_DMA32_RXDPTR;
3901 
3902 	return (val / sizeof(struct bwn_dmadesc32));
3903 }
3904 
3905 static void
3906 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3907 {
3908 
3909 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3910 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3911 }
3912 
3913 static void
3914 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3915     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3916 {
3917 	struct bwn_dmadesc64 *desc;
3918 
3919 	*meta = &(dr->dr_meta[slot]);
3920 	desc = dr->dr_ring_descbase;
3921 	desc = &(desc[slot]);
3922 
3923 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3924 }
3925 
3926 static void
3927 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3928     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3929     int start, int end, int irq)
3930 {
3931 	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3932 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3933 	int slot;
3934 	uint32_t ctl0 = 0, ctl1 = 0;
3935 	uint32_t addrlo, addrhi;
3936 	uint32_t addrext;
3937 
3938 	slot = (int)(&(desc->dma.dma64) - descbase);
3939 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3940 	    ("%s:%d: fail", __func__, __LINE__));
3941 
3942 	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3943 	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3944 	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3945 	    30;
3946 	addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3947 	if (slot == dr->dr_numslots - 1)
3948 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3949 	if (start)
3950 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3951 	if (end)
3952 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3953 	if (irq)
3954 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
3955 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3956 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3957 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
3958 
3959 	desc->dma.dma64.control0 = htole32(ctl0);
3960 	desc->dma.dma64.control1 = htole32(ctl1);
3961 	desc->dma.dma64.address_low = htole32(addrlo);
3962 	desc->dma.dma64.address_high = htole32(addrhi);
3963 }
3964 
3965 static void
3966 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3967 {
3968 
3969 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3970 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3971 }
3972 
3973 static void
3974 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3975 {
3976 
3977 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3978 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3979 }
3980 
3981 static void
3982 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3983 {
3984 
3985 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3986 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3987 }
3988 
3989 static int
3990 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3991 {
3992 	uint32_t val;
3993 
3994 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3995 	val &= BWN_DMA64_RXSTATDPTR;
3996 
3997 	return (val / sizeof(struct bwn_dmadesc64));
3998 }
3999 
4000 static void
4001 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4002 {
4003 
4004 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4005 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4006 }
4007 
4008 static int
4009 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4010 {
4011 	struct bwn_mac *mac = dr->dr_mac;
4012 	struct bwn_dma *dma = &mac->mac_method.dma;
4013 	struct bwn_softc *sc = mac->mac_sc;
4014 	int error;
4015 
4016 	error = bus_dma_tag_create(dma->parent_dtag,
4017 			    BWN_ALIGN, 0,
4018 			    BUS_SPACE_MAXADDR,
4019 			    BUS_SPACE_MAXADDR,
4020 			    NULL, NULL,
4021 			    BWN_DMA_RINGMEMSIZE,
4022 			    1,
4023 			    BUS_SPACE_MAXSIZE_32BIT,
4024 			    0,
4025 			    &dr->dr_ring_dtag);
4026 	if (error) {
4027 		device_printf(sc->sc_dev,
4028 		    "can't create TX ring DMA tag: TODO frees\n");
4029 		return (-1);
4030 	}
4031 
4032 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
4033 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4034 	    &dr->dr_ring_dmap);
4035 	if (error) {
4036 		device_printf(sc->sc_dev,
4037 		    "can't allocate DMA mem: TODO frees\n");
4038 		return (-1);
4039 	}
4040 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4041 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4042 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0);
4043 	if (error) {
4044 		device_printf(sc->sc_dev,
4045 		    "can't load DMA mem: TODO free\n");
4046 		return (-1);
4047 	}
4048 
4049 	return (0);
4050 }
4051 
4052 static void
4053 bwn_dma_setup(struct bwn_dma_ring *dr)
4054 {
4055 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
4056 	uint64_t ring64;
4057 	uint32_t addrext, ring32, value;
4058 	uint32_t trans = siba_dma_translation(sc->sc_dev);
4059 
4060 	if (dr->dr_tx) {
4061 		dr->dr_curslot = -1;
4062 
4063 		if (dr->dr_type == BWN_DMA_64BIT) {
4064 			ring64 = (uint64_t)(dr->dr_ring_dmabase);
4065 			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4066 			    >> 30;
4067 			value = BWN_DMA64_TXENABLE;
4068 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4069 			    & BWN_DMA64_TXADDREXT_MASK;
4070 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4071 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4072 			    (ring64 & 0xffffffff));
4073 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4074 			    ((ring64 >> 32) &
4075 			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4076 		} else {
4077 			ring32 = (uint32_t)(dr->dr_ring_dmabase);
4078 			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4079 			value = BWN_DMA32_TXENABLE;
4080 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4081 			    & BWN_DMA32_TXADDREXT_MASK;
4082 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4083 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4084 			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4085 		}
4086 		return;
4087 	}
4088 
4089 	/*
4090 	 * set for RX
4091 	 */
4092 	dr->dr_usedslot = dr->dr_numslots;
4093 
4094 	if (dr->dr_type == BWN_DMA_64BIT) {
4095 		ring64 = (uint64_t)(dr->dr_ring_dmabase);
4096 		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4097 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4098 		value |= BWN_DMA64_RXENABLE;
4099 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4100 		    & BWN_DMA64_RXADDREXT_MASK;
4101 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4102 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4103 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4104 		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4105 		    | (trans << 1));
4106 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4107 		    sizeof(struct bwn_dmadesc64));
4108 	} else {
4109 		ring32 = (uint32_t)(dr->dr_ring_dmabase);
4110 		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4111 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4112 		value |= BWN_DMA32_RXENABLE;
4113 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4114 		    & BWN_DMA32_RXADDREXT_MASK;
4115 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4116 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4117 		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4118 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4119 		    sizeof(struct bwn_dmadesc32));
4120 	}
4121 }
4122 
4123 static void
4124 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4125 {
4126 
4127 	if (dr->dr_tx) {
4128 		bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap);
4129 		if (dr->dr_txhdr_cache != NULL)
4130 			bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache,
4131 			    dr->dr_txring_dmap);
4132 		bus_dma_tag_destroy(dr->dr_txring_dtag);
4133 	}
4134 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4135 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4136 	    dr->dr_ring_dmap);
4137 	bus_dma_tag_destroy(dr->dr_ring_dtag);
4138 }
4139 
4140 static void
4141 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4142 {
4143 
4144 	if (dr->dr_tx) {
4145 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4146 		if (dr->dr_type == BWN_DMA_64BIT) {
4147 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4148 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4149 		} else
4150 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4151 	} else {
4152 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4153 		if (dr->dr_type == BWN_DMA_64BIT) {
4154 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4155 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4156 		} else
4157 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4158 	}
4159 }
4160 
4161 static void
4162 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4163 {
4164 	struct bwn_dmadesc_generic *desc;
4165 	struct bwn_dmadesc_meta *meta;
4166 	struct bwn_mac *mac = dr->dr_mac;
4167 	struct bwn_dma *dma = &mac->mac_method.dma;
4168 	struct bwn_softc *sc = mac->mac_sc;
4169 	int i;
4170 
4171 	if (!dr->dr_usedslot)
4172 		return;
4173 	for (i = 0; i < dr->dr_numslots; i++) {
4174 		dr->getdesc(dr, i, &desc, &meta);
4175 
4176 		if (meta->mt_m == NULL) {
4177 			if (!dr->dr_tx)
4178 				device_printf(sc->sc_dev, "%s: not TX?\n",
4179 				    __func__);
4180 			continue;
4181 		}
4182 		if (dr->dr_tx) {
4183 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
4184 				/* Nothing */
4185 			} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
4186 				bus_dmamap_unload(dma->txbuf_dtag,
4187 				    meta->mt_dmap);
4188 			}
4189 		} else
4190 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4191 		bwn_dma_free_descbuf(dr, meta);
4192 	}
4193 }
4194 
4195 static int
4196 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4197     int type)
4198 {
4199 	struct bwn_softc *sc = mac->mac_sc;
4200 	uint32_t value;
4201 	int i;
4202 	uint16_t offset;
4203 
4204 	for (i = 0; i < 10; i++) {
4205 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4206 		    BWN_DMA32_TXSTATUS;
4207 		value = BWN_READ_4(mac, base + offset);
4208 		if (type == BWN_DMA_64BIT) {
4209 			value &= BWN_DMA64_TXSTAT;
4210 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
4211 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4212 			    value == BWN_DMA64_TXSTAT_STOPPED)
4213 				break;
4214 		} else {
4215 			value &= BWN_DMA32_TXSTATE;
4216 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
4217 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4218 			    value == BWN_DMA32_TXSTAT_STOPPED)
4219 				break;
4220 		}
4221 		DELAY(1000);
4222 	}
4223 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4224 	BWN_WRITE_4(mac, base + offset, 0);
4225 	for (i = 0; i < 10; i++) {
4226 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4227 						   BWN_DMA32_TXSTATUS;
4228 		value = BWN_READ_4(mac, base + offset);
4229 		if (type == BWN_DMA_64BIT) {
4230 			value &= BWN_DMA64_TXSTAT;
4231 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
4232 				i = -1;
4233 				break;
4234 			}
4235 		} else {
4236 			value &= BWN_DMA32_TXSTATE;
4237 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
4238 				i = -1;
4239 				break;
4240 			}
4241 		}
4242 		DELAY(1000);
4243 	}
4244 	if (i != -1) {
4245 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4246 		return (ENODEV);
4247 	}
4248 	DELAY(1000);
4249 
4250 	return (0);
4251 }
4252 
4253 static int
4254 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4255     int type)
4256 {
4257 	struct bwn_softc *sc = mac->mac_sc;
4258 	uint32_t value;
4259 	int i;
4260 	uint16_t offset;
4261 
4262 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4263 	BWN_WRITE_4(mac, base + offset, 0);
4264 	for (i = 0; i < 10; i++) {
4265 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4266 		    BWN_DMA32_RXSTATUS;
4267 		value = BWN_READ_4(mac, base + offset);
4268 		if (type == BWN_DMA_64BIT) {
4269 			value &= BWN_DMA64_RXSTAT;
4270 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
4271 				i = -1;
4272 				break;
4273 			}
4274 		} else {
4275 			value &= BWN_DMA32_RXSTATE;
4276 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
4277 				i = -1;
4278 				break;
4279 			}
4280 		}
4281 		DELAY(1000);
4282 	}
4283 	if (i != -1) {
4284 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4285 		return (ENODEV);
4286 	}
4287 
4288 	return (0);
4289 }
4290 
4291 static void
4292 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4293     struct bwn_dmadesc_meta *meta)
4294 {
4295 
4296 	if (meta->mt_m != NULL) {
4297 		m_freem(meta->mt_m);
4298 		meta->mt_m = NULL;
4299 	}
4300 	if (meta->mt_ni != NULL) {
4301 		ieee80211_free_node(meta->mt_ni);
4302 		meta->mt_ni = NULL;
4303 	}
4304 }
4305 
4306 static void
4307 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4308 {
4309 	struct bwn_rxhdr4 *rxhdr;
4310 	unsigned char *frame;
4311 
4312 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
4313 	rxhdr->frame_len = 0;
4314 
4315 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4316 	    sizeof(struct bwn_plcp6) + 2,
4317 	    ("%s:%d: fail", __func__, __LINE__));
4318 	frame = mtod(m, char *) + dr->dr_frameoffset;
4319 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4320 }
4321 
4322 static uint8_t
4323 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4324 {
4325 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4326 
4327 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4328 	    == 0xff);
4329 }
4330 
4331 static void
4332 bwn_wme_init(struct bwn_mac *mac)
4333 {
4334 
4335 	bwn_wme_load(mac);
4336 
4337 	/* enable WME support. */
4338 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4339 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4340 	    BWN_IFSCTL_USE_EDCF);
4341 }
4342 
4343 static void
4344 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4345 {
4346 	struct bwn_softc *sc = mac->mac_sc;
4347 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4348 	uint16_t delay;	/* microsec */
4349 
4350 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4351 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4352 		delay = 500;
4353 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4354 		delay = max(delay, (uint16_t)2400);
4355 
4356 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4357 }
4358 
4359 static void
4360 bwn_bt_enable(struct bwn_mac *mac)
4361 {
4362 	struct bwn_softc *sc = mac->mac_sc;
4363 	uint64_t hf;
4364 
4365 	if (bwn_bluetooth == 0)
4366 		return;
4367 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4368 		return;
4369 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4370 		return;
4371 
4372 	hf = bwn_hf_read(mac);
4373 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4374 		hf |= BWN_HF_BT_COEXISTALT;
4375 	else
4376 		hf |= BWN_HF_BT_COEXIST;
4377 	bwn_hf_write(mac, hf);
4378 }
4379 
4380 static void
4381 bwn_set_macaddr(struct bwn_mac *mac)
4382 {
4383 
4384 	bwn_mac_write_bssid(mac);
4385 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4386 }
4387 
4388 static void
4389 bwn_clear_keys(struct bwn_mac *mac)
4390 {
4391 	int i;
4392 
4393 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
4394 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4395 		    ("%s:%d: fail", __func__, __LINE__));
4396 
4397 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4398 		    NULL, BWN_SEC_KEYSIZE, NULL);
4399 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4400 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4401 			    NULL, BWN_SEC_KEYSIZE, NULL);
4402 		}
4403 		mac->mac_key[i].keyconf = NULL;
4404 	}
4405 }
4406 
4407 static void
4408 bwn_crypt_init(struct bwn_mac *mac)
4409 {
4410 	struct bwn_softc *sc = mac->mac_sc;
4411 
4412 	mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4413 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4414 	    ("%s:%d: fail", __func__, __LINE__));
4415 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4416 	mac->mac_ktp *= 2;
4417 	if (siba_get_revid(sc->sc_dev) >= 5)
4418 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4419 	bwn_clear_keys(mac);
4420 }
4421 
4422 static void
4423 bwn_chip_exit(struct bwn_mac *mac)
4424 {
4425 	struct bwn_softc *sc = mac->mac_sc;
4426 
4427 	bwn_phy_exit(mac);
4428 	siba_gpio_set(sc->sc_dev, 0);
4429 }
4430 
4431 static int
4432 bwn_fw_fillinfo(struct bwn_mac *mac)
4433 {
4434 	int error;
4435 
4436 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4437 	if (error == 0)
4438 		return (0);
4439 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4440 	if (error == 0)
4441 		return (0);
4442 	return (error);
4443 }
4444 
4445 static int
4446 bwn_gpio_init(struct bwn_mac *mac)
4447 {
4448 	struct bwn_softc *sc = mac->mac_sc;
4449 	uint32_t mask = 0x1f, set = 0xf, value;
4450 
4451 	BWN_WRITE_4(mac, BWN_MACCTL,
4452 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4453 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
4454 	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4455 
4456 	if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4457 		mask |= 0x0060;
4458 		set |= 0x0060;
4459 	}
4460 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4461 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
4462 		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4463 		mask |= 0x0200;
4464 		set |= 0x0200;
4465 	}
4466 	if (siba_get_revid(sc->sc_dev) >= 2)
4467 		mask |= 0x0010;
4468 
4469 	value = siba_gpio_get(sc->sc_dev);
4470 	if (value == -1)
4471 		return (0);
4472 	siba_gpio_set(sc->sc_dev, (value & mask) | set);
4473 
4474 	return (0);
4475 }
4476 
4477 static int
4478 bwn_fw_loadinitvals(struct bwn_mac *mac)
4479 {
4480 #define	GETFWOFFSET(fwp, offset)				\
4481 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4482 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
4483 	const struct bwn_fwhdr *hdr;
4484 	struct bwn_fw *fw = &mac->mac_fw;
4485 	int error;
4486 
4487 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4488 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4489 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4490 	if (error)
4491 		return (error);
4492 	if (fw->initvals_band.fw) {
4493 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4494 		error = bwn_fwinitvals_write(mac,
4495 		    GETFWOFFSET(fw->initvals_band, hdr_len),
4496 		    be32toh(hdr->size),
4497 		    fw->initvals_band.fw->datasize - hdr_len);
4498 	}
4499 	return (error);
4500 #undef GETFWOFFSET
4501 }
4502 
4503 static int
4504 bwn_phy_init(struct bwn_mac *mac)
4505 {
4506 	struct bwn_softc *sc = mac->mac_sc;
4507 	int error;
4508 
4509 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4510 	mac->mac_phy.rf_onoff(mac, 1);
4511 	error = mac->mac_phy.init(mac);
4512 	if (error) {
4513 		device_printf(sc->sc_dev, "PHY init failed\n");
4514 		goto fail0;
4515 	}
4516 	error = bwn_switch_channel(mac,
4517 	    mac->mac_phy.get_default_chan(mac));
4518 	if (error) {
4519 		device_printf(sc->sc_dev,
4520 		    "failed to switch default channel\n");
4521 		goto fail1;
4522 	}
4523 	return (0);
4524 fail1:
4525 	if (mac->mac_phy.exit)
4526 		mac->mac_phy.exit(mac);
4527 fail0:
4528 	mac->mac_phy.rf_onoff(mac, 0);
4529 
4530 	return (error);
4531 }
4532 
4533 static void
4534 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4535 {
4536 	uint16_t ant;
4537 	uint16_t tmp;
4538 
4539 	ant = bwn_ant2phy(antenna);
4540 
4541 	/* For ACK/CTS */
4542 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4543 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4544 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4545 	/* For Probe Resposes */
4546 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4547 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4548 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4549 }
4550 
4551 static void
4552 bwn_set_opmode(struct bwn_mac *mac)
4553 {
4554 	struct bwn_softc *sc = mac->mac_sc;
4555 	struct ifnet *ifp = sc->sc_ifp;
4556 	struct ieee80211com *ic = ifp->if_l2com;
4557 	uint32_t ctl;
4558 	uint16_t cfp_pretbtt;
4559 
4560 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4561 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4562 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4563 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4564 	ctl |= BWN_MACCTL_STA;
4565 
4566 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4567 	    ic->ic_opmode == IEEE80211_M_MBSS)
4568 		ctl |= BWN_MACCTL_HOSTAP;
4569 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
4570 		ctl &= ~BWN_MACCTL_STA;
4571 	ctl |= sc->sc_filters;
4572 
4573 	if (siba_get_revid(sc->sc_dev) <= 4)
4574 		ctl |= BWN_MACCTL_PROMISC;
4575 
4576 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4577 
4578 	cfp_pretbtt = 2;
4579 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4580 		if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4581 		    siba_get_chiprev(sc->sc_dev) == 3)
4582 			cfp_pretbtt = 100;
4583 		else
4584 			cfp_pretbtt = 50;
4585 	}
4586 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4587 }
4588 
4589 static int
4590 bwn_dma_gettype(struct bwn_mac *mac)
4591 {
4592 	uint32_t tmp;
4593 	uint16_t base;
4594 
4595 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4596 	if (tmp & SIBA_TGSHIGH_DMA64)
4597 		return (BWN_DMA_64BIT);
4598 	base = bwn_dma_base(0, 0);
4599 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4600 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4601 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
4602 		return (BWN_DMA_32BIT);
4603 
4604 	return (BWN_DMA_30BIT);
4605 }
4606 
4607 static void
4608 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4609 {
4610 	if (!error) {
4611 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4612 		*((bus_addr_t *)arg) = seg->ds_addr;
4613 	}
4614 }
4615 
4616 static void
4617 bwn_phy_g_init_sub(struct bwn_mac *mac)
4618 {
4619 	struct bwn_phy *phy = &mac->mac_phy;
4620 	struct bwn_phy_g *pg = &phy->phy_g;
4621 	struct bwn_softc *sc = mac->mac_sc;
4622 	uint16_t i, tmp;
4623 
4624 	if (phy->rev == 1)
4625 		bwn_phy_init_b5(mac);
4626 	else
4627 		bwn_phy_init_b6(mac);
4628 
4629 	if (phy->rev >= 2 || phy->gmode)
4630 		bwn_phy_init_a(mac);
4631 
4632 	if (phy->rev >= 2) {
4633 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4634 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4635 	}
4636 	if (phy->rev == 2) {
4637 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4638 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4639 	}
4640 	if (phy->rev > 5) {
4641 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4642 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4643 	}
4644 	if (phy->gmode || phy->rev >= 2) {
4645 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4646 		tmp &= BWN_PHYVER_VERSION;
4647 		if (tmp == 3 || tmp == 5) {
4648 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4649 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4650 		}
4651 		if (tmp == 5) {
4652 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4653 			    0x1f00);
4654 		}
4655 	}
4656 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4657 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4658 	if (phy->rf_rev == 8) {
4659 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4660 		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4661 	}
4662 	if (BWN_HAS_LOOPBACK(phy))
4663 		bwn_loopback_calcgain(mac);
4664 
4665 	if (phy->rf_rev != 8) {
4666 		if (pg->pg_initval == 0xffff)
4667 			pg->pg_initval = bwn_rf_init_bcm2050(mac);
4668 		else
4669 			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4670 	}
4671 	bwn_lo_g_init(mac);
4672 	if (BWN_HAS_TXMAG(phy)) {
4673 		BWN_RF_WRITE(mac, 0x52,
4674 		    (BWN_RF_READ(mac, 0x52) & 0xff00)
4675 		    | pg->pg_loctl.tx_bias |
4676 		    pg->pg_loctl.tx_magn);
4677 	} else {
4678 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4679 	}
4680 	if (phy->rev >= 6) {
4681 		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4682 		    (pg->pg_loctl.tx_bias << 12));
4683 	}
4684 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4685 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4686 	else
4687 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4688 	if (phy->rev < 2)
4689 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4690 	else
4691 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4692 	if (phy->gmode || phy->rev >= 2) {
4693 		bwn_lo_g_adjust(mac);
4694 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4695 	}
4696 
4697 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4698 		for (i = 0; i < 64; i++) {
4699 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4700 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4701 			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4702 			    -32), 31));
4703 		}
4704 		bwn_nrssi_threshold(mac);
4705 	} else if (phy->gmode || phy->rev >= 2) {
4706 		if (pg->pg_nrssi[0] == -1000) {
4707 			KASSERT(pg->pg_nrssi[1] == -1000,
4708 			    ("%s:%d: fail", __func__, __LINE__));
4709 			bwn_nrssi_slope_11g(mac);
4710 		} else
4711 			bwn_nrssi_threshold(mac);
4712 	}
4713 	if (phy->rf_rev == 8)
4714 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4715 	bwn_phy_hwpctl_init(mac);
4716 	if ((siba_get_chipid(sc->sc_dev) == 0x4306
4717 	     && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4718 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4719 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4720 	}
4721 }
4722 
4723 static uint8_t
4724 bwn_has_hwpctl(struct bwn_mac *mac)
4725 {
4726 
4727 	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4728 		return (0);
4729 	return (mac->mac_phy.use_hwpctl(mac));
4730 }
4731 
4732 static void
4733 bwn_phy_init_b5(struct bwn_mac *mac)
4734 {
4735 	struct bwn_phy *phy = &mac->mac_phy;
4736 	struct bwn_phy_g *pg = &phy->phy_g;
4737 	struct bwn_softc *sc = mac->mac_sc;
4738 	uint16_t offset, value;
4739 	uint8_t old_channel;
4740 
4741 	if (phy->analog == 1)
4742 		BWN_RF_SET(mac, 0x007a, 0x0050);
4743 	if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4744 	    (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4745 		value = 0x2120;
4746 		for (offset = 0x00a8; offset < 0x00c7; offset++) {
4747 			BWN_PHY_WRITE(mac, offset, value);
4748 			value += 0x202;
4749 		}
4750 	}
4751 	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4752 	if (phy->rf_ver == 0x2050)
4753 		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4754 
4755 	if (phy->gmode || phy->rev >= 2) {
4756 		if (phy->rf_ver == 0x2050) {
4757 			BWN_RF_SET(mac, 0x007a, 0x0020);
4758 			BWN_RF_SET(mac, 0x0051, 0x0004);
4759 		}
4760 		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4761 
4762 		BWN_PHY_SET(mac, 0x0802, 0x0100);
4763 		BWN_PHY_SET(mac, 0x042b, 0x2000);
4764 
4765 		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4766 
4767 		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4768 		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4769 		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4770 	}
4771 
4772 	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4773 		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4774 
4775 	if (phy->analog == 1) {
4776 		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4777 		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4778 		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4779 		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4780 		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4781 	} else
4782 		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4783 	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4784 	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4785 
4786 	if (phy->analog == 1)
4787 		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4788 	else
4789 		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4790 
4791 	if (phy->analog == 0)
4792 		BWN_WRITE_2(mac, 0x03e4, 0x3000);
4793 
4794 	old_channel = phy->chan;
4795 	bwn_phy_g_switch_chan(mac, 7, 0);
4796 
4797 	if (phy->rf_ver != 0x2050) {
4798 		BWN_RF_WRITE(mac, 0x0075, 0x0080);
4799 		BWN_RF_WRITE(mac, 0x0079, 0x0081);
4800 	}
4801 
4802 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
4803 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
4804 
4805 	if (phy->rf_ver == 0x2050) {
4806 		BWN_RF_WRITE(mac, 0x0050, 0x0020);
4807 		BWN_RF_WRITE(mac, 0x005a, 0x0070);
4808 	}
4809 
4810 	BWN_RF_WRITE(mac, 0x005b, 0x007b);
4811 	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4812 	BWN_RF_SET(mac, 0x007a, 0x0007);
4813 
4814 	bwn_phy_g_switch_chan(mac, old_channel, 0);
4815 	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4816 	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4817 	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4818 
4819 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4820 	    pg->pg_txctl);
4821 
4822 	if (phy->rf_ver == 0x2050)
4823 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
4824 
4825 	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4826 }
4827 
4828 static void
4829 bwn_loopback_calcgain(struct bwn_mac *mac)
4830 {
4831 	struct bwn_phy *phy = &mac->mac_phy;
4832 	struct bwn_phy_g *pg = &phy->phy_g;
4833 	struct bwn_softc *sc = mac->mac_sc;
4834 	uint16_t backup_phy[16] = { 0 };
4835 	uint16_t backup_radio[3];
4836 	uint16_t backup_bband;
4837 	uint16_t i, j, loop_i_max;
4838 	uint16_t trsw_rx;
4839 	uint16_t loop1_outer_done, loop1_inner_done;
4840 
4841 	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4842 	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4843 	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4844 	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4845 	if (phy->rev != 1) {
4846 		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4847 		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4848 	}
4849 	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4850 	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4851 	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4852 	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4853 	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4854 	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4855 	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4856 	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4857 	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4858 	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4859 	backup_bband = pg->pg_bbatt.att;
4860 	backup_radio[0] = BWN_RF_READ(mac, 0x52);
4861 	backup_radio[1] = BWN_RF_READ(mac, 0x43);
4862 	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4863 
4864 	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4865 	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4866 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4867 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4868 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4869 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4870 	if (phy->rev != 1) {
4871 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4872 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4873 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4874 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4875 	}
4876 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4877 	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4878 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4879 	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4880 
4881 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4882 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4883 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4884 
4885 	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4886 	if (phy->rev != 1) {
4887 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4888 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4889 	}
4890 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4891 
4892 	if (phy->rf_rev == 8)
4893 		BWN_RF_WRITE(mac, 0x43, 0x000f);
4894 	else {
4895 		BWN_RF_WRITE(mac, 0x52, 0);
4896 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4897 	}
4898 	bwn_phy_g_set_bbatt(mac, 11);
4899 
4900 	if (phy->rev >= 3)
4901 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4902 	else
4903 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4904 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4905 
4906 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4907 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4908 
4909 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4910 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4911 
4912 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4913 		if (phy->rev >= 7) {
4914 			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4915 			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4916 		}
4917 	}
4918 	BWN_RF_MASK(mac, 0x7a, 0x00f7);
4919 
4920 	j = 0;
4921 	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4922 	for (i = 0; i < loop_i_max; i++) {
4923 		for (j = 0; j < 16; j++) {
4924 			BWN_RF_WRITE(mac, 0x43, i);
4925 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4926 			    (j << 8));
4927 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4928 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4929 			DELAY(20);
4930 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4931 				goto done0;
4932 		}
4933 	}
4934 done0:
4935 	loop1_outer_done = i;
4936 	loop1_inner_done = j;
4937 	if (j >= 8) {
4938 		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4939 		trsw_rx = 0x1b;
4940 		for (j = j - 8; j < 16; j++) {
4941 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4942 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4943 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4944 			DELAY(20);
4945 			trsw_rx -= 3;
4946 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4947 				goto done1;
4948 		}
4949 	} else
4950 		trsw_rx = 0x18;
4951 done1:
4952 
4953 	if (phy->rev != 1) {
4954 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4955 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4956 	}
4957 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4958 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4959 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4960 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4961 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4962 	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4963 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4964 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4965 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4966 
4967 	bwn_phy_g_set_bbatt(mac, backup_bband);
4968 
4969 	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4970 	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4971 	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4972 
4973 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4974 	DELAY(10);
4975 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4976 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4977 	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4978 	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4979 
4980 	pg->pg_max_lb_gain =
4981 	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4982 	pg->pg_trsw_rx_gain = trsw_rx * 2;
4983 }
4984 
4985 static uint16_t
4986 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4987 {
4988 	struct bwn_phy *phy = &mac->mac_phy;
4989 	uint32_t tmp1 = 0, tmp2 = 0;
4990 	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4991 	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4992 	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4993 	static const uint8_t rcc_table[] = {
4994 		0x02, 0x03, 0x01, 0x0f,
4995 		0x06, 0x07, 0x05, 0x0f,
4996 		0x0a, 0x0b, 0x09, 0x0f,
4997 		0x0e, 0x0f, 0x0d, 0x0f,
4998 	};
4999 
5000 	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5001 	    rfoverval = rfover = cck3 = 0;
5002 	radio0 = BWN_RF_READ(mac, 0x43);
5003 	radio1 = BWN_RF_READ(mac, 0x51);
5004 	radio2 = BWN_RF_READ(mac, 0x52);
5005 	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5006 	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5007 	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5008 	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5009 
5010 	if (phy->type == BWN_PHYTYPE_B) {
5011 		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5012 		reg0 = BWN_READ_2(mac, 0x3ec);
5013 
5014 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5015 		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5016 	} else if (phy->gmode || phy->rev >= 2) {
5017 		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5018 		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5019 		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5020 		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5021 		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5022 		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5023 
5024 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5025 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5026 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5027 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5028 		if (BWN_HAS_LOOPBACK(phy)) {
5029 			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5030 			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5031 			if (phy->rev >= 3)
5032 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5033 			else
5034 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5035 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5036 		}
5037 
5038 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5039 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5040 			BWN_LPD(0, 1, 1)));
5041 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5042 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5043 	}
5044 	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5045 
5046 	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5047 	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5048 	reg1 = BWN_READ_2(mac, 0x3e6);
5049 	reg2 = BWN_READ_2(mac, 0x3f4);
5050 
5051 	if (phy->analog == 0)
5052 		BWN_WRITE_2(mac, 0x03e6, 0x0122);
5053 	else {
5054 		if (phy->analog >= 2)
5055 			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5056 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5057 		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5058 	}
5059 
5060 	reg = BWN_RF_READ(mac, 0x60);
5061 	index = (reg & 0x001e) >> 1;
5062 	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5063 
5064 	if (phy->type == BWN_PHYTYPE_B)
5065 		BWN_RF_WRITE(mac, 0x78, 0x26);
5066 	if (phy->gmode || phy->rev >= 2) {
5067 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5068 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5069 			BWN_LPD(0, 1, 1)));
5070 	}
5071 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5072 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5073 	if (phy->gmode || phy->rev >= 2) {
5074 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5075 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5076 			BWN_LPD(0, 0, 1)));
5077 	}
5078 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5079 	BWN_RF_SET(mac, 0x51, 0x0004);
5080 	if (phy->rf_rev == 8)
5081 		BWN_RF_WRITE(mac, 0x43, 0x1f);
5082 	else {
5083 		BWN_RF_WRITE(mac, 0x52, 0);
5084 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5085 	}
5086 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5087 
5088 	for (i = 0; i < 16; i++) {
5089 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5090 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5091 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5092 		if (phy->gmode || phy->rev >= 2) {
5093 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5094 			    bwn_rf_2050_rfoverval(mac,
5095 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5096 		}
5097 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5098 		DELAY(10);
5099 		if (phy->gmode || phy->rev >= 2) {
5100 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5101 			    bwn_rf_2050_rfoverval(mac,
5102 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5103 		}
5104 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5105 		DELAY(10);
5106 		if (phy->gmode || phy->rev >= 2) {
5107 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5108 			    bwn_rf_2050_rfoverval(mac,
5109 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5110 		}
5111 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5112 		DELAY(20);
5113 		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5114 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5115 		if (phy->gmode || phy->rev >= 2) {
5116 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5117 			    bwn_rf_2050_rfoverval(mac,
5118 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5119 		}
5120 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5121 	}
5122 	DELAY(10);
5123 
5124 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5125 	tmp1++;
5126 	tmp1 >>= 9;
5127 
5128 	for (i = 0; i < 16; i++) {
5129 		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5130 		BWN_RF_WRITE(mac, 0x78, radio78);
5131 		DELAY(10);
5132 		for (j = 0; j < 16; j++) {
5133 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5134 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5135 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5136 			if (phy->gmode || phy->rev >= 2) {
5137 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5138 				    bwn_rf_2050_rfoverval(mac,
5139 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5140 			}
5141 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5142 			DELAY(10);
5143 			if (phy->gmode || phy->rev >= 2) {
5144 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5145 				    bwn_rf_2050_rfoverval(mac,
5146 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5147 			}
5148 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5149 			DELAY(10);
5150 			if (phy->gmode || phy->rev >= 2) {
5151 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5152 				    bwn_rf_2050_rfoverval(mac,
5153 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5154 			}
5155 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5156 			DELAY(10);
5157 			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5158 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5159 			if (phy->gmode || phy->rev >= 2) {
5160 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5161 				    bwn_rf_2050_rfoverval(mac,
5162 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5163 			}
5164 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5165 		}
5166 		tmp2++;
5167 		tmp2 >>= 8;
5168 		if (tmp1 < tmp2)
5169 			break;
5170 	}
5171 
5172 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5173 	BWN_RF_WRITE(mac, 0x51, radio1);
5174 	BWN_RF_WRITE(mac, 0x52, radio2);
5175 	BWN_RF_WRITE(mac, 0x43, radio0);
5176 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5177 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5178 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5179 	BWN_WRITE_2(mac, 0x3e6, reg1);
5180 	if (phy->analog != 0)
5181 		BWN_WRITE_2(mac, 0x3f4, reg2);
5182 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5183 	bwn_spu_workaround(mac, phy->chan);
5184 	if (phy->type == BWN_PHYTYPE_B) {
5185 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5186 		BWN_WRITE_2(mac, 0x3ec, reg0);
5187 	} else if (phy->gmode) {
5188 		BWN_WRITE_2(mac, BWN_PHY_RADIO,
5189 			    BWN_READ_2(mac, BWN_PHY_RADIO)
5190 			    & 0x7fff);
5191 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5192 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5193 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5194 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5195 			      analogoverval);
5196 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5197 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5198 		if (BWN_HAS_LOOPBACK(phy)) {
5199 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5200 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5201 		}
5202 	}
5203 
5204 	return ((i > 15) ? radio78 : rcc);
5205 }
5206 
5207 static void
5208 bwn_phy_init_b6(struct bwn_mac *mac)
5209 {
5210 	struct bwn_phy *phy = &mac->mac_phy;
5211 	struct bwn_phy_g *pg = &phy->phy_g;
5212 	struct bwn_softc *sc = mac->mac_sc;
5213 	uint16_t offset, val;
5214 	uint8_t old_channel;
5215 
5216 	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5217 	    ("%s:%d: fail", __func__, __LINE__));
5218 
5219 	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5220 	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5221 	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5222 		BWN_RF_WRITE(mac, 0x51, 0x37);
5223 		BWN_RF_WRITE(mac, 0x52, 0x70);
5224 		BWN_RF_WRITE(mac, 0x53, 0xb3);
5225 		BWN_RF_WRITE(mac, 0x54, 0x9b);
5226 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5227 		BWN_RF_WRITE(mac, 0x5b, 0x88);
5228 		BWN_RF_WRITE(mac, 0x5d, 0x88);
5229 		BWN_RF_WRITE(mac, 0x5e, 0x88);
5230 		BWN_RF_WRITE(mac, 0x7d, 0x88);
5231 		bwn_hf_write(mac,
5232 		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5233 	}
5234 	if (phy->rf_rev == 8) {
5235 		BWN_RF_WRITE(mac, 0x51, 0);
5236 		BWN_RF_WRITE(mac, 0x52, 0x40);
5237 		BWN_RF_WRITE(mac, 0x53, 0xb7);
5238 		BWN_RF_WRITE(mac, 0x54, 0x98);
5239 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5240 		BWN_RF_WRITE(mac, 0x5b, 0x6b);
5241 		BWN_RF_WRITE(mac, 0x5c, 0x0f);
5242 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5243 			BWN_RF_WRITE(mac, 0x5d, 0xfa);
5244 			BWN_RF_WRITE(mac, 0x5e, 0xd8);
5245 		} else {
5246 			BWN_RF_WRITE(mac, 0x5d, 0xf5);
5247 			BWN_RF_WRITE(mac, 0x5e, 0xb8);
5248 		}
5249 		BWN_RF_WRITE(mac, 0x0073, 0x0003);
5250 		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5251 		BWN_RF_WRITE(mac, 0x007c, 0x0001);
5252 		BWN_RF_WRITE(mac, 0x007e, 0x0008);
5253 	}
5254 	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5255 		BWN_PHY_WRITE(mac, offset, val);
5256 		val -= 0x0202;
5257 	}
5258 	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5259 		BWN_PHY_WRITE(mac, offset, val);
5260 		val -= 0x0202;
5261 	}
5262 	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5263 		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5264 		val += 0x0202;
5265 	}
5266 	if (phy->type == BWN_PHYTYPE_G) {
5267 		BWN_RF_SET(mac, 0x007a, 0x0020);
5268 		BWN_RF_SET(mac, 0x0051, 0x0004);
5269 		BWN_PHY_SET(mac, 0x0802, 0x0100);
5270 		BWN_PHY_SET(mac, 0x042b, 0x2000);
5271 		BWN_PHY_WRITE(mac, 0x5b, 0);
5272 		BWN_PHY_WRITE(mac, 0x5c, 0);
5273 	}
5274 
5275 	old_channel = phy->chan;
5276 	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5277 
5278 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
5279 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
5280 	DELAY(40);
5281 	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5282 		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5283 		BWN_RF_WRITE(mac, 0x50, 0x20);
5284 	}
5285 	if (phy->rf_rev <= 2) {
5286 		BWN_RF_WRITE(mac, 0x7c, 0x20);
5287 		BWN_RF_WRITE(mac, 0x5a, 0x70);
5288 		BWN_RF_WRITE(mac, 0x5b, 0x7b);
5289 		BWN_RF_WRITE(mac, 0x5c, 0xb0);
5290 	}
5291 	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5292 
5293 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5294 
5295 	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5296 	if (phy->rf_rev >= 6)
5297 		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5298 	else
5299 		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5300 	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5301 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5302 	    pg->pg_txctl);
5303 	if (phy->rf_rev <= 5)
5304 		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5305 	if (phy->rf_rev <= 2)
5306 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5307 
5308 	if (phy->analog == 4) {
5309 		BWN_WRITE_2(mac, 0x3e4, 9);
5310 		BWN_PHY_MASK(mac, 0x61, 0x0fff);
5311 	} else
5312 		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5313 	if (phy->type == BWN_PHYTYPE_B)
5314 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5315 	else if (phy->type == BWN_PHYTYPE_G)
5316 		BWN_WRITE_2(mac, 0x03e6, 0x0);
5317 }
5318 
5319 static void
5320 bwn_phy_init_a(struct bwn_mac *mac)
5321 {
5322 	struct bwn_phy *phy = &mac->mac_phy;
5323 	struct bwn_softc *sc = mac->mac_sc;
5324 
5325 	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5326 	    ("%s:%d: fail", __func__, __LINE__));
5327 
5328 	if (phy->rev >= 6) {
5329 		if (phy->type == BWN_PHYTYPE_A)
5330 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5331 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5332 			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5333 		else
5334 			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5335 	}
5336 
5337 	bwn_wa_init(mac);
5338 
5339 	if (phy->type == BWN_PHYTYPE_G &&
5340 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5341 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5342 }
5343 
5344 static void
5345 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5346 {
5347 	int i;
5348 
5349 	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5350 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5351 }
5352 
5353 static void
5354 bwn_wa_agc(struct bwn_mac *mac)
5355 {
5356 	struct bwn_phy *phy = &mac->mac_phy;
5357 
5358 	if (phy->rev == 1) {
5359 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5360 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5361 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5362 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5363 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5364 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5365 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5366 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5367 		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5368 	} else {
5369 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5370 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5371 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5372 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5373 	}
5374 
5375 	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5376 	    0x5700);
5377 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5378 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5379 	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5380 	BWN_RF_SET(mac, 0x7a, 0x0008);
5381 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5382 	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5383 	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5384 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5385 	if (phy->rev == 1)
5386 		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5387 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5388 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5389 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5390 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5391 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5392 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5393 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5394 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5395 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5396 	if (phy->rev == 1) {
5397 		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5398 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5399 	} else {
5400 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5401 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5402 		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5403 		if (phy->rev >= 6) {
5404 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5405 			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5406 			    (uint16_t)~0xf000, 0x3000);
5407 		}
5408 	}
5409 	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5410 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5411 	if (phy->rev == 1) {
5412 		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5413 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5414 		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5415 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5416 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5417 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5418 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5419 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5420 	} else {
5421 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5422 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5423 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5424 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5425 	}
5426 	if (phy->rev >= 6) {
5427 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5428 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5429 	}
5430 	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5431 }
5432 
5433 static void
5434 bwn_wa_grev1(struct bwn_mac *mac)
5435 {
5436 	struct bwn_phy *phy = &mac->mac_phy;
5437 	int i;
5438 	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5439 	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5440 	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5441 
5442 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5443 
5444 	/* init CRSTHRES and ANTDWELL */
5445 	if (phy->rev == 1) {
5446 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5447 	} else if (phy->rev == 2) {
5448 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5449 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5450 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5451 	} else {
5452 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5453 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5454 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5455 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5456 	}
5457 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5458 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5459 	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5460 
5461 	/* XXX support PHY-A??? */
5462 	for (i = 0; i < N(bwn_tab_finefreqg); i++)
5463 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5464 		    bwn_tab_finefreqg[i]);
5465 
5466 	/* XXX support PHY-A??? */
5467 	if (phy->rev == 1)
5468 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5469 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5470 			    bwn_tab_noise_g1[i]);
5471 	else
5472 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5473 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5474 			    bwn_tab_noise_g2[i]);
5475 
5476 
5477 	for (i = 0; i < N(bwn_tab_rotor); i++)
5478 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5479 		    bwn_tab_rotor[i]);
5480 
5481 	/* XXX support PHY-A??? */
5482 	if (phy->rev >= 6) {
5483 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5484 		    BWN_PHY_ENCORE_EN)
5485 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5486 		else
5487 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5488 	} else
5489 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5490 
5491 	for (i = 0; i < N(bwn_tab_retard); i++)
5492 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5493 		    bwn_tab_retard[i]);
5494 
5495 	if (phy->rev == 1) {
5496 		for (i = 0; i < 16; i++)
5497 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5498 			    i, 0x0020);
5499 	} else {
5500 		for (i = 0; i < 32; i++)
5501 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5502 	}
5503 
5504 	bwn_wa_agc(mac);
5505 }
5506 
5507 static void
5508 bwn_wa_grev26789(struct bwn_mac *mac)
5509 {
5510 	struct bwn_phy *phy = &mac->mac_phy;
5511 	int i;
5512 	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5513 	uint16_t ofdmrev;
5514 
5515 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5516 
5517 	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5518 
5519 	/* init CRSTHRES and ANTDWELL */
5520 	if (phy->rev == 1)
5521 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5522 	else if (phy->rev == 2) {
5523 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5524 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5525 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5526 	} else {
5527 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5528 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5529 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5530 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5531 	}
5532 
5533 	for (i = 0; i < 64; i++)
5534 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5535 
5536 	/* XXX support PHY-A??? */
5537 	if (phy->rev == 1)
5538 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5539 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5540 			    bwn_tab_noise_g1[i]);
5541 	else
5542 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5543 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5544 			    bwn_tab_noise_g2[i]);
5545 
5546 	/* XXX support PHY-A??? */
5547 	if (phy->rev >= 6) {
5548 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5549 		    BWN_PHY_ENCORE_EN)
5550 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5551 		else
5552 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5553 	} else
5554 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5555 
5556 	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5557 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5558 		    bwn_tab_sigmasqr2[i]);
5559 
5560 	if (phy->rev == 1) {
5561 		for (i = 0; i < 16; i++)
5562 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5563 			    0x0020);
5564 	} else {
5565 		for (i = 0; i < 32; i++)
5566 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5567 	}
5568 
5569 	bwn_wa_agc(mac);
5570 
5571 	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5572 	if (ofdmrev > 2) {
5573 		if (phy->type == BWN_PHYTYPE_A)
5574 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5575 		else
5576 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5577 	} else {
5578 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5579 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5580 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5581 	}
5582 
5583 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5584 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5585 }
5586 
5587 static void
5588 bwn_wa_init(struct bwn_mac *mac)
5589 {
5590 	struct bwn_phy *phy = &mac->mac_phy;
5591 	struct bwn_softc *sc = mac->mac_sc;
5592 
5593 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5594 
5595 	switch (phy->rev) {
5596 	case 1:
5597 		bwn_wa_grev1(mac);
5598 		break;
5599 	case 2:
5600 	case 6:
5601 	case 7:
5602 	case 8:
5603 	case 9:
5604 		bwn_wa_grev26789(mac);
5605 		break;
5606 	default:
5607 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5608 	}
5609 
5610 	if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5611 	    siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5612 	    siba_get_pci_revid(sc->sc_dev) != 0x17) {
5613 		if (phy->rev < 2) {
5614 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5615 			    0x0002);
5616 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5617 			    0x0001);
5618 		} else {
5619 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5620 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5621 			if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5622 			     BWN_BFL_EXTLNA) &&
5623 			    (phy->rev >= 7)) {
5624 				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5625 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5626 				    0x0020, 0x0001);
5627 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5628 				    0x0021, 0x0001);
5629 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5630 				    0x0022, 0x0001);
5631 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5632 				    0x0023, 0x0000);
5633 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5634 				    0x0000, 0x0000);
5635 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5636 				    0x0003, 0x0002);
5637 			}
5638 		}
5639 	}
5640 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5641 		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5642 		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5643 	}
5644 
5645 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5646 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5647 }
5648 
5649 static void
5650 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5651     uint16_t value)
5652 {
5653 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5654 	uint16_t addr;
5655 
5656 	addr = table + offset;
5657 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5658 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5659 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5660 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5661 	}
5662 	pg->pg_ofdmtab_addr = addr;
5663 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5664 }
5665 
5666 static void
5667 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5668     uint32_t value)
5669 {
5670 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5671 	uint16_t addr;
5672 
5673 	addr = table + offset;
5674 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5675 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5676 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5677 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5678 	}
5679 	pg->pg_ofdmtab_addr = addr;
5680 
5681 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5682 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5683 }
5684 
5685 static void
5686 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5687     uint16_t value)
5688 {
5689 
5690 	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5691 	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5692 }
5693 
5694 static void
5695 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5696 {
5697 	struct bwn_phy *phy = &mac->mac_phy;
5698 	struct bwn_softc *sc = mac->mac_sc;
5699 	unsigned int i, max_loop;
5700 	uint16_t value;
5701 	uint32_t buffer[5] = {
5702 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5703 	};
5704 
5705 	if (ofdm) {
5706 		max_loop = 0x1e;
5707 		buffer[0] = 0x000201cc;
5708 	} else {
5709 		max_loop = 0xfa;
5710 		buffer[0] = 0x000b846e;
5711 	}
5712 
5713 	for (i = 0; i < 5; i++)
5714 		bwn_ram_write(mac, i * 4, buffer[i]);
5715 
5716 	BWN_WRITE_2(mac, 0x0568, 0x0000);
5717 	BWN_WRITE_2(mac, 0x07c0,
5718 	    (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5719 	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5720 	BWN_WRITE_2(mac, 0x050c, value);
5721 	if (phy->type == BWN_PHYTYPE_LP)
5722 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
5723 	BWN_WRITE_2(mac, 0x0508, 0x0000);
5724 	BWN_WRITE_2(mac, 0x050a, 0x0000);
5725 	BWN_WRITE_2(mac, 0x054c, 0x0000);
5726 	BWN_WRITE_2(mac, 0x056a, 0x0014);
5727 	BWN_WRITE_2(mac, 0x0568, 0x0826);
5728 	BWN_WRITE_2(mac, 0x0500, 0x0000);
5729 	if (phy->type == BWN_PHYTYPE_LP)
5730 		BWN_WRITE_2(mac, 0x0502, 0x0050);
5731 	else
5732 		BWN_WRITE_2(mac, 0x0502, 0x0030);
5733 
5734 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5735 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
5736 	for (i = 0x00; i < max_loop; i++) {
5737 		value = BWN_READ_2(mac, 0x050e);
5738 		if (value & 0x0080)
5739 			break;
5740 		DELAY(10);
5741 	}
5742 	for (i = 0x00; i < 0x0a; i++) {
5743 		value = BWN_READ_2(mac, 0x050e);
5744 		if (value & 0x0400)
5745 			break;
5746 		DELAY(10);
5747 	}
5748 	for (i = 0x00; i < 0x19; i++) {
5749 		value = BWN_READ_2(mac, 0x0690);
5750 		if (!(value & 0x0100))
5751 			break;
5752 		DELAY(10);
5753 	}
5754 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5755 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
5756 }
5757 
5758 static void
5759 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5760 {
5761 	uint32_t macctl;
5762 
5763 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5764 
5765 	macctl = BWN_READ_4(mac, BWN_MACCTL);
5766 	if (macctl & BWN_MACCTL_BIGENDIAN)
5767 		kprintf("TODO: need swap\n");
5768 
5769 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5770 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5771 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5772 }
5773 
5774 static void
5775 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5776 {
5777 	uint16_t value;
5778 
5779 	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5780 	    ("%s:%d: fail", __func__, __LINE__));
5781 
5782 	value = (uint8_t) (ctl->q);
5783 	value |= ((uint8_t) (ctl->i)) << 8;
5784 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5785 }
5786 
5787 static uint16_t
5788 bwn_lo_calcfeed(struct bwn_mac *mac,
5789     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5790 {
5791 	struct bwn_phy *phy = &mac->mac_phy;
5792 	struct bwn_softc *sc = mac->mac_sc;
5793 	uint16_t rfover;
5794 	uint16_t feedthrough;
5795 
5796 	if (phy->gmode) {
5797 		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5798 		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5799 
5800 		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5801 		    ("%s:%d: fail", __func__, __LINE__));
5802 		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5803 		    ("%s:%d: fail", __func__, __LINE__));
5804 
5805 		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5806 
5807 		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5808 		if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5809 		    phy->rev > 6)
5810 			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5811 
5812 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5813 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5814 		DELAY(10);
5815 		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5816 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5817 		DELAY(10);
5818 		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5819 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5820 		DELAY(10);
5821 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5822 	} else {
5823 		pga |= BWN_PHY_PGACTL_UNKNOWN;
5824 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5825 		DELAY(10);
5826 		pga |= BWN_PHY_PGACTL_LOWBANDW;
5827 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5828 		DELAY(10);
5829 		pga |= BWN_PHY_PGACTL_LPF;
5830 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5831 	}
5832 	DELAY(21);
5833 	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5834 
5835 	return (feedthrough);
5836 }
5837 
5838 static uint16_t
5839 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5840     uint16_t *value, uint16_t *pad_mix_gain)
5841 {
5842 	struct bwn_phy *phy = &mac->mac_phy;
5843 	uint16_t reg, v, padmix;
5844 
5845 	if (phy->type == BWN_PHYTYPE_B) {
5846 		v = 0x30;
5847 		if (phy->rf_rev <= 5) {
5848 			reg = 0x43;
5849 			padmix = 0;
5850 		} else {
5851 			reg = 0x52;
5852 			padmix = 5;
5853 		}
5854 	} else {
5855 		if (phy->rev >= 2 && phy->rf_rev == 8) {
5856 			reg = 0x43;
5857 			v = 0x10;
5858 			padmix = 2;
5859 		} else {
5860 			reg = 0x52;
5861 			v = 0x30;
5862 			padmix = 5;
5863 		}
5864 	}
5865 	if (value)
5866 		*value = v;
5867 	if (pad_mix_gain)
5868 		*pad_mix_gain = padmix;
5869 
5870 	return (reg);
5871 }
5872 
5873 static void
5874 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5875 {
5876 	struct bwn_phy *phy = &mac->mac_phy;
5877 	struct bwn_phy_g *pg = &phy->phy_g;
5878 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5879 	uint16_t reg, mask;
5880 	uint16_t trsw_rx, pga;
5881 	uint16_t rf_pctl_reg;
5882 
5883 	static const uint8_t tx_bias_values[] = {
5884 		0x09, 0x08, 0x0a, 0x01, 0x00,
5885 		0x02, 0x05, 0x04, 0x06,
5886 	};
5887 	static const uint8_t tx_magn_values[] = {
5888 		0x70, 0x40,
5889 	};
5890 
5891 	if (!BWN_HAS_LOOPBACK(phy)) {
5892 		rf_pctl_reg = 6;
5893 		trsw_rx = 2;
5894 		pga = 0;
5895 	} else {
5896 		int lb_gain;
5897 
5898 		trsw_rx = 0;
5899 		lb_gain = pg->pg_max_lb_gain / 2;
5900 		if (lb_gain > 10) {
5901 			rf_pctl_reg = 0;
5902 			pga = abs(10 - lb_gain) / 6;
5903 			pga = MIN(MAX(pga, 0), 15);
5904 		} else {
5905 			int cmp_val;
5906 			int tmp;
5907 
5908 			pga = 0;
5909 			cmp_val = 0x24;
5910 			if ((phy->rev >= 2) &&
5911 			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5912 				cmp_val = 0x3c;
5913 			tmp = lb_gain;
5914 			if ((10 - lb_gain) < cmp_val)
5915 				tmp = (10 - lb_gain);
5916 			if (tmp < 0)
5917 				tmp += 6;
5918 			else
5919 				tmp += 3;
5920 			cmp_val /= 4;
5921 			tmp /= 4;
5922 			if (tmp >= cmp_val)
5923 				rf_pctl_reg = cmp_val;
5924 			else
5925 				rf_pctl_reg = tmp;
5926 		}
5927 	}
5928 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5929 	bwn_phy_g_set_bbatt(mac, 2);
5930 
5931 	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5932 	mask = ~mask;
5933 	BWN_RF_MASK(mac, reg, mask);
5934 
5935 	if (BWN_HAS_TXMAG(phy)) {
5936 		int i, j;
5937 		int feedthrough;
5938 		int min_feedth = 0xffff;
5939 		uint8_t tx_magn, tx_bias;
5940 
5941 		for (i = 0; i < N(tx_magn_values); i++) {
5942 			tx_magn = tx_magn_values[i];
5943 			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5944 			for (j = 0; j < N(tx_bias_values); j++) {
5945 				tx_bias = tx_bias_values[j];
5946 				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5947 				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5948 				    trsw_rx);
5949 				if (feedthrough < min_feedth) {
5950 					lo->tx_bias = tx_bias;
5951 					lo->tx_magn = tx_magn;
5952 					min_feedth = feedthrough;
5953 				}
5954 				if (lo->tx_bias == 0)
5955 					break;
5956 			}
5957 			BWN_RF_WRITE(mac, 0x52,
5958 					  (BWN_RF_READ(mac, 0x52)
5959 					   & 0xff00) | lo->tx_bias | lo->
5960 					  tx_magn);
5961 		}
5962 	} else {
5963 		lo->tx_magn = 0;
5964 		lo->tx_bias = 0;
5965 		BWN_RF_MASK(mac, 0x52, 0xfff0);
5966 	}
5967 
5968 	BWN_GETTIME(lo->txctl_measured_time);
5969 }
5970 
5971 static void
5972 bwn_lo_get_powervector(struct bwn_mac *mac)
5973 {
5974 	struct bwn_phy *phy = &mac->mac_phy;
5975 	struct bwn_phy_g *pg = &phy->phy_g;
5976 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5977 	int i;
5978 	uint64_t tmp;
5979 	uint64_t power_vector = 0;
5980 
5981 	for (i = 0; i < 8; i += 2) {
5982 		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5983 		power_vector |= (tmp << (i * 8));
5984 		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5985 	}
5986 	if (power_vector)
5987 		lo->power_vector = power_vector;
5988 
5989 	BWN_GETTIME(lo->pwr_vec_read_time);
5990 }
5991 
5992 static void
5993 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5994     int use_trsw_rx)
5995 {
5996 	struct bwn_phy *phy = &mac->mac_phy;
5997 	struct bwn_phy_g *pg = &phy->phy_g;
5998 	uint16_t tmp;
5999 
6000 	if (max_rx_gain < 0)
6001 		max_rx_gain = 0;
6002 
6003 	if (BWN_HAS_LOOPBACK(phy)) {
6004 		int trsw_rx = 0;
6005 		int trsw_rx_gain;
6006 
6007 		if (use_trsw_rx) {
6008 			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6009 			if (max_rx_gain >= trsw_rx_gain) {
6010 				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6011 				trsw_rx = 0x20;
6012 			}
6013 		} else
6014 			trsw_rx_gain = max_rx_gain;
6015 		if (trsw_rx_gain < 9) {
6016 			pg->pg_lna_lod_gain = 0;
6017 		} else {
6018 			pg->pg_lna_lod_gain = 1;
6019 			trsw_rx_gain -= 8;
6020 		}
6021 		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6022 		pg->pg_pga_gain = trsw_rx_gain / 3;
6023 		if (pg->pg_pga_gain >= 5) {
6024 			pg->pg_pga_gain -= 5;
6025 			pg->pg_lna_gain = 2;
6026 		} else
6027 			pg->pg_lna_gain = 0;
6028 	} else {
6029 		pg->pg_lna_gain = 0;
6030 		pg->pg_trsw_rx_gain = 0x20;
6031 		if (max_rx_gain >= 0x14) {
6032 			pg->pg_lna_lod_gain = 1;
6033 			pg->pg_pga_gain = 2;
6034 		} else if (max_rx_gain >= 0x12) {
6035 			pg->pg_lna_lod_gain = 1;
6036 			pg->pg_pga_gain = 1;
6037 		} else if (max_rx_gain >= 0xf) {
6038 			pg->pg_lna_lod_gain = 1;
6039 			pg->pg_pga_gain = 0;
6040 		} else {
6041 			pg->pg_lna_lod_gain = 0;
6042 			pg->pg_pga_gain = 0;
6043 		}
6044 	}
6045 
6046 	tmp = BWN_RF_READ(mac, 0x7a);
6047 	if (pg->pg_lna_lod_gain == 0)
6048 		tmp &= ~0x0008;
6049 	else
6050 		tmp |= 0x0008;
6051 	BWN_RF_WRITE(mac, 0x7a, tmp);
6052 }
6053 
6054 static void
6055 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6056 {
6057 	struct bwn_phy *phy = &mac->mac_phy;
6058 	struct bwn_phy_g *pg = &phy->phy_g;
6059 	struct bwn_softc *sc = mac->mac_sc;
6060 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6061 	struct timespec ts;
6062 	uint16_t tmp;
6063 
6064 	if (bwn_has_hwpctl(mac)) {
6065 		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6066 		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6067 		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6068 		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6069 		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6070 
6071 		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6072 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6073 		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6074 		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6075 	}
6076 	if (phy->type == BWN_PHYTYPE_B &&
6077 	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6078 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6079 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6080 	}
6081 	if (phy->rev >= 2) {
6082 		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6083 		sav->phy_analogoverval =
6084 		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6085 		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6086 		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6087 		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6088 		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6089 		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6090 
6091 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6092 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6093 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6094 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6095 		if (phy->type == BWN_PHYTYPE_G) {
6096 			if ((phy->rev >= 7) &&
6097 			    (siba_sprom_get_bf_lo(sc->sc_dev) &
6098 			     BWN_BFL_EXTLNA)) {
6099 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6100 			} else {
6101 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6102 			}
6103 		} else {
6104 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6105 		}
6106 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6107 	}
6108 	sav->reg0 = BWN_READ_2(mac, 0x3f4);
6109 	sav->reg1 = BWN_READ_2(mac, 0x3e2);
6110 	sav->rf0 = BWN_RF_READ(mac, 0x43);
6111 	sav->rf1 = BWN_RF_READ(mac, 0x7a);
6112 	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6113 	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6114 	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6115 	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6116 
6117 	if (!BWN_HAS_TXMAG(phy)) {
6118 		sav->rf2 = BWN_RF_READ(mac, 0x52);
6119 		sav->rf2 &= 0x00f0;
6120 	}
6121 	if (phy->type == BWN_PHYTYPE_B) {
6122 		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6123 		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6124 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6125 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6126 	} else {
6127 		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6128 			    | 0x8000);
6129 	}
6130 	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6131 		    & 0xf000);
6132 
6133 	tmp =
6134 	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6135 	BWN_PHY_WRITE(mac, tmp, 0x007f);
6136 
6137 	tmp = sav->phy_syncctl;
6138 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6139 	tmp = sav->rf1;
6140 	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6141 
6142 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6143 	if (phy->type == BWN_PHYTYPE_G ||
6144 	    (phy->type == BWN_PHYTYPE_B &&
6145 	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6146 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6147 	} else
6148 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6149 	if (phy->rev >= 2)
6150 		bwn_dummy_transmission(mac, 0, 1);
6151 	bwn_phy_g_switch_chan(mac, 6, 0);
6152 	BWN_RF_READ(mac, 0x51);
6153 	if (phy->type == BWN_PHYTYPE_G)
6154 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6155 
6156 	nanouptime(&ts);
6157 	if (time_before(lo->txctl_measured_time,
6158 	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6159 		bwn_lo_measure_txctl_values(mac);
6160 
6161 	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6162 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6163 	else {
6164 		if (phy->type == BWN_PHYTYPE_B)
6165 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6166 		else
6167 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6168 	}
6169 }
6170 
6171 static void
6172 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6173 {
6174 	struct bwn_phy *phy = &mac->mac_phy;
6175 	struct bwn_phy_g *pg = &phy->phy_g;
6176 	uint16_t tmp;
6177 
6178 	if (phy->rev >= 2) {
6179 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6180 		tmp = (pg->pg_pga_gain << 8);
6181 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6182 		DELAY(5);
6183 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6184 		DELAY(2);
6185 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6186 	} else {
6187 		tmp = (pg->pg_pga_gain | 0xefa0);
6188 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6189 	}
6190 	if (phy->type == BWN_PHYTYPE_G) {
6191 		if (phy->rev >= 3)
6192 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6193 		else
6194 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6195 		if (phy->rev >= 2)
6196 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6197 		else
6198 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6199 	}
6200 	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6201 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6202 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6203 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6204 	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6205 	BWN_RF_WRITE(mac, 0x43, sav->rf0);
6206 	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6207 	if (!BWN_HAS_TXMAG(phy)) {
6208 		tmp = sav->rf2;
6209 		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6210 	}
6211 	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6212 	if (phy->type == BWN_PHYTYPE_B &&
6213 	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6214 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6215 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6216 	}
6217 	if (phy->rev >= 2) {
6218 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6219 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6220 			      sav->phy_analogoverval);
6221 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6222 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6223 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6224 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6225 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6226 	}
6227 	if (bwn_has_hwpctl(mac)) {
6228 		tmp = (sav->phy_lomask & 0xbfff);
6229 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6230 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6231 		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6232 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6233 		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6234 	}
6235 	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6236 }
6237 
6238 static int
6239 bwn_lo_probe_loctl(struct bwn_mac *mac,
6240     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6241 {
6242 	struct bwn_phy *phy = &mac->mac_phy;
6243 	struct bwn_phy_g *pg = &phy->phy_g;
6244 	struct bwn_loctl orig, test;
6245 	struct bwn_loctl prev = { -100, -100 };
6246 	static const struct bwn_loctl modifiers[] = {
6247 		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6248 		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6249 	};
6250 	int begin, end, lower = 0, i;
6251 	uint16_t feedth;
6252 
6253 	if (d->curstate == 0) {
6254 		begin = 1;
6255 		end = 8;
6256 	} else if (d->curstate % 2 == 0) {
6257 		begin = d->curstate - 1;
6258 		end = d->curstate + 1;
6259 	} else {
6260 		begin = d->curstate - 2;
6261 		end = d->curstate + 2;
6262 	}
6263 	if (begin < 1)
6264 		begin += 8;
6265 	if (end > 8)
6266 		end -= 8;
6267 
6268 	memcpy(&orig, probe, sizeof(struct bwn_loctl));
6269 	i = begin;
6270 	d->curstate = i;
6271 	while (1) {
6272 		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6273 		memcpy(&test, &orig, sizeof(struct bwn_loctl));
6274 		test.i += modifiers[i - 1].i * d->multipler;
6275 		test.q += modifiers[i - 1].q * d->multipler;
6276 		if ((test.i != prev.i || test.q != prev.q) &&
6277 		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6278 			bwn_lo_write(mac, &test);
6279 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6280 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6281 			if (feedth < d->feedth) {
6282 				memcpy(probe, &test,
6283 				    sizeof(struct bwn_loctl));
6284 				lower = 1;
6285 				d->feedth = feedth;
6286 				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6287 					break;
6288 			}
6289 		}
6290 		memcpy(&prev, &test, sizeof(prev));
6291 		if (i == end)
6292 			break;
6293 		if (i == 8)
6294 			i = 1;
6295 		else
6296 			i++;
6297 		d->curstate = i;
6298 	}
6299 
6300 	return (lower);
6301 }
6302 
6303 static void
6304 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6305 {
6306 	struct bwn_phy *phy = &mac->mac_phy;
6307 	struct bwn_phy_g *pg = &phy->phy_g;
6308 	struct bwn_lo_g_sm d;
6309 	struct bwn_loctl probe;
6310 	int lower, repeat, cnt = 0;
6311 	uint16_t feedth;
6312 
6313 	d.nmeasure = 0;
6314 	d.multipler = 1;
6315 	if (BWN_HAS_LOOPBACK(phy))
6316 		d.multipler = 3;
6317 
6318 	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6319 	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6320 
6321 	do {
6322 		bwn_lo_write(mac, &d.loctl);
6323 		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6324 		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6325 		if (feedth < 0x258) {
6326 			if (feedth >= 0x12c)
6327 				*rxgain += 6;
6328 			else
6329 				*rxgain += 3;
6330 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6331 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6332 		}
6333 		d.feedth = feedth;
6334 		d.curstate = 0;
6335 		do {
6336 			KASSERT(d.curstate >= 0 && d.curstate <= 8,
6337 			    ("%s:%d: fail", __func__, __LINE__));
6338 			memcpy(&probe, &d.loctl,
6339 			       sizeof(struct bwn_loctl));
6340 			lower = bwn_lo_probe_loctl(mac, &probe, &d);
6341 			if (!lower)
6342 				break;
6343 			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6344 				break;
6345 			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6346 			d.nmeasure++;
6347 		} while (d.nmeasure < 24);
6348 		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6349 
6350 		if (BWN_HAS_LOOPBACK(phy)) {
6351 			if (d.feedth > 0x1194)
6352 				*rxgain -= 6;
6353 			else if (d.feedth < 0x5dc)
6354 				*rxgain += 3;
6355 			if (cnt == 0) {
6356 				if (d.feedth <= 0x5dc) {
6357 					d.multipler = 1;
6358 					cnt++;
6359 				} else
6360 					d.multipler = 2;
6361 			} else if (cnt == 2)
6362 				d.multipler = 1;
6363 		}
6364 		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6365 	} while (++cnt < repeat);
6366 }
6367 
6368 static struct bwn_lo_calib *
6369 bwn_lo_calibset(struct bwn_mac *mac,
6370     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6371 {
6372 	struct bwn_phy *phy = &mac->mac_phy;
6373 	struct bwn_phy_g *pg = &phy->phy_g;
6374 	struct bwn_loctl loctl = { 0, 0 };
6375 	struct bwn_lo_calib *cal;
6376 	struct bwn_lo_g_value sval = { 0 };
6377 	int rxgain;
6378 	uint16_t pad, reg, value;
6379 
6380 	sval.old_channel = phy->chan;
6381 	bwn_mac_suspend(mac);
6382 	bwn_lo_save(mac, &sval);
6383 
6384 	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6385 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6386 	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6387 
6388 	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6389 	if (rfatt->padmix)
6390 		rxgain -= pad;
6391 	if (BWN_HAS_LOOPBACK(phy))
6392 		rxgain += pg->pg_max_lb_gain;
6393 	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6394 	bwn_phy_g_set_bbatt(mac, bbatt->att);
6395 	bwn_lo_probe_sm(mac, &loctl, &rxgain);
6396 
6397 	bwn_lo_restore(mac, &sval);
6398 	bwn_mac_enable(mac);
6399 
6400 	cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO);
6401 	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6402 	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6403 	memcpy(&cal->ctl, &loctl, sizeof(loctl));
6404 
6405 	BWN_GETTIME(cal->calib_time);
6406 
6407 	return (cal);
6408 }
6409 
6410 static struct bwn_lo_calib *
6411 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6412     const struct bwn_rfatt *rfatt)
6413 {
6414 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6415 	struct bwn_lo_calib *c;
6416 
6417 	TAILQ_FOREACH(c, &lo->calib_list, list) {
6418 		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6419 			continue;
6420 		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6421 			continue;
6422 		return (c);
6423 	}
6424 
6425 	c = bwn_lo_calibset(mac, bbatt, rfatt);
6426 	if (c == NULL)	/* XXX ivadasz: can't happen */
6427 		return (NULL);
6428 	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6429 
6430 	return (c);
6431 }
6432 
6433 static void
6434 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6435 {
6436 	struct bwn_phy *phy = &mac->mac_phy;
6437 	struct bwn_phy_g *pg = &phy->phy_g;
6438 	struct bwn_softc *sc = mac->mac_sc;
6439 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6440 	const struct bwn_rfatt *rfatt;
6441 	const struct bwn_bbatt *bbatt;
6442 	uint64_t pvector;
6443 	int i;
6444 	int rf_offset, bb_offset;
6445 	uint8_t changed = 0;
6446 
6447 	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6448 	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6449 	    ("%s:%d: fail", __func__, __LINE__));
6450 
6451 	pvector = lo->power_vector;
6452 	if (!update && !pvector)
6453 		return;
6454 
6455 	bwn_mac_suspend(mac);
6456 
6457 	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6458 		struct bwn_lo_calib *cal;
6459 		int idx;
6460 		uint16_t val;
6461 
6462 		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6463 			continue;
6464 		bb_offset = i / lo->rfatt.len;
6465 		rf_offset = i % lo->rfatt.len;
6466 		bbatt = &(lo->bbatt.array[bb_offset]);
6467 		rfatt = &(lo->rfatt.array[rf_offset]);
6468 
6469 		cal = bwn_lo_calibset(mac, bbatt, rfatt);
6470 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
6471 			device_printf(sc->sc_dev, "LO: Could not "
6472 			    "calibrate DC table entry\n");
6473 			continue;
6474 		}
6475 		val = (uint8_t)(cal->ctl.q);
6476 		val |= ((uint8_t)(cal->ctl.i)) << 4;
6477 		kfree(cal, M_DEVBUF);
6478 
6479 		idx = i / 2;
6480 		if (i % 2)
6481 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6482 			    | ((val & 0x00ff) << 8);
6483 		else
6484 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6485 			    | (val & 0x00ff);
6486 		changed = 1;
6487 	}
6488 	if (changed) {
6489 		for (i = 0; i < BWN_DC_LT_SIZE; i++)
6490 			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6491 	}
6492 	bwn_mac_enable(mac);
6493 }
6494 
6495 static void
6496 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6497 {
6498 
6499 	if (!rf->padmix)
6500 		return;
6501 	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6502 		rf->att = 4;
6503 }
6504 
6505 static void
6506 bwn_lo_g_adjust(struct bwn_mac *mac)
6507 {
6508 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6509 	struct bwn_lo_calib *cal;
6510 	struct bwn_rfatt rf;
6511 
6512 	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6513 	bwn_lo_fixup_rfatt(&rf);
6514 
6515 	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6516 	if (cal == NULL)	/* XXX ivadasz: can't happen */
6517 		return;
6518 	bwn_lo_write(mac, &cal->ctl);
6519 }
6520 
6521 static void
6522 bwn_lo_g_init(struct bwn_mac *mac)
6523 {
6524 
6525 	if (!bwn_has_hwpctl(mac))
6526 		return;
6527 
6528 	bwn_lo_get_powervector(mac);
6529 	bwn_phy_g_dc_lookup_init(mac, 1);
6530 }
6531 
6532 static void
6533 bwn_mac_suspend(struct bwn_mac *mac)
6534 {
6535 	struct bwn_softc *sc = mac->mac_sc;
6536 	int i;
6537 	uint32_t tmp;
6538 
6539 	KASSERT(mac->mac_suspended >= 0,
6540 	    ("%s:%d: fail", __func__, __LINE__));
6541 
6542 	if (mac->mac_suspended == 0) {
6543 		bwn_psctl(mac, BWN_PS_AWAKE);
6544 		BWN_WRITE_4(mac, BWN_MACCTL,
6545 			    BWN_READ_4(mac, BWN_MACCTL)
6546 			    & ~BWN_MACCTL_ON);
6547 		BWN_READ_4(mac, BWN_MACCTL);
6548 		for (i = 35; i; i--) {
6549 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6550 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6551 				goto out;
6552 			DELAY(10);
6553 		}
6554 		for (i = 40; i; i--) {
6555 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6556 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6557 				goto out;
6558 			DELAY(1000);
6559 		}
6560 		device_printf(sc->sc_dev, "MAC suspend failed\n");
6561 	}
6562 out:
6563 	mac->mac_suspended++;
6564 }
6565 
6566 static void
6567 bwn_mac_enable(struct bwn_mac *mac)
6568 {
6569 	struct bwn_softc *sc = mac->mac_sc;
6570 	uint16_t state;
6571 
6572 	state = bwn_shm_read_2(mac, BWN_SHARED,
6573 	    BWN_SHARED_UCODESTAT);
6574 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6575 	    state != BWN_SHARED_UCODESTAT_SLEEP)
6576 		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6577 
6578 	mac->mac_suspended--;
6579 	KASSERT(mac->mac_suspended >= 0,
6580 	    ("%s:%d: fail", __func__, __LINE__));
6581 	if (mac->mac_suspended == 0) {
6582 		BWN_WRITE_4(mac, BWN_MACCTL,
6583 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6584 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6585 		BWN_READ_4(mac, BWN_MACCTL);
6586 		BWN_READ_4(mac, BWN_INTR_REASON);
6587 		bwn_psctl(mac, 0);
6588 	}
6589 }
6590 
6591 static void
6592 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6593 {
6594 	struct bwn_softc *sc = mac->mac_sc;
6595 	int i;
6596 	uint16_t ucstat;
6597 
6598 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6599 	    ("%s:%d: fail", __func__, __LINE__));
6600 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6601 	    ("%s:%d: fail", __func__, __LINE__));
6602 
6603 	/* XXX forcibly awake and hwps-off */
6604 
6605 	BWN_WRITE_4(mac, BWN_MACCTL,
6606 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6607 	    ~BWN_MACCTL_HWPS);
6608 	BWN_READ_4(mac, BWN_MACCTL);
6609 	if (siba_get_revid(sc->sc_dev) >= 5) {
6610 		for (i = 0; i < 100; i++) {
6611 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6612 			    BWN_SHARED_UCODESTAT);
6613 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6614 				break;
6615 			DELAY(10);
6616 		}
6617 	}
6618 }
6619 
6620 static int16_t
6621 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6622 {
6623 
6624 	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6625 	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6626 }
6627 
6628 static void
6629 bwn_nrssi_threshold(struct bwn_mac *mac)
6630 {
6631 	struct bwn_phy *phy = &mac->mac_phy;
6632 	struct bwn_phy_g *pg = &phy->phy_g;
6633 	struct bwn_softc *sc = mac->mac_sc;
6634 	int32_t a, b;
6635 	int16_t tmp16;
6636 	uint16_t tmpu16;
6637 
6638 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6639 
6640 	if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6641 		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6642 			a = 0x13;
6643 			b = 0x12;
6644 		} else {
6645 			a = 0xe;
6646 			b = 0x11;
6647 		}
6648 
6649 		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6650 		a += (pg->pg_nrssi[0] << 6);
6651 		a += (a < 32) ? 31 : 32;
6652 		a = a >> 6;
6653 		a = MIN(MAX(a, -31), 31);
6654 
6655 		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6656 		b += (pg->pg_nrssi[0] << 6);
6657 		if (b < 32)
6658 			b += 31;
6659 		else
6660 			b += 32;
6661 		b = b >> 6;
6662 		b = MIN(MAX(b, -31), 31);
6663 
6664 		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6665 		tmpu16 |= ((uint32_t)b & 0x0000003f);
6666 		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6667 		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6668 		return;
6669 	}
6670 
6671 	tmp16 = bwn_nrssi_read(mac, 0x20);
6672 	if (tmp16 >= 0x20)
6673 		tmp16 -= 0x40;
6674 	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6675 }
6676 
6677 static void
6678 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6679 {
6680 #define	SAVE_RF_MAX		3
6681 #define	SAVE_PHY_COMM_MAX	4
6682 #define	SAVE_PHY3_MAX		8
6683 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6684 		{ 0x7a, 0x52, 0x43 };
6685 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6686 		{ 0x15, 0x5a, 0x59, 0x58 };
6687 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6688 		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6689 		0x0801, 0x0060, 0x0014, 0x0478
6690 	};
6691 	struct bwn_phy *phy = &mac->mac_phy;
6692 	struct bwn_phy_g *pg = &phy->phy_g;
6693 	int32_t i, tmp32, phy3_idx = 0;
6694 	uint16_t delta, tmp;
6695 	uint16_t save_rf[SAVE_RF_MAX];
6696 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6697 	uint16_t save_phy3[SAVE_PHY3_MAX];
6698 	uint16_t ant_div, phy0, chan_ex;
6699 	int16_t nrssi0, nrssi1;
6700 
6701 	KASSERT(phy->type == BWN_PHYTYPE_G,
6702 	    ("%s:%d: fail", __func__, __LINE__));
6703 
6704 	if (phy->rf_rev >= 9)
6705 		return;
6706 	if (phy->rf_rev == 8)
6707 		bwn_nrssi_offset(mac);
6708 
6709 	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6710 	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6711 
6712 	/*
6713 	 * Save RF/PHY registers for later restoration
6714 	 */
6715 	ant_div = BWN_READ_2(mac, 0x03e2);
6716 	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6717 	for (i = 0; i < SAVE_RF_MAX; ++i)
6718 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6719 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6720 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6721 
6722 	phy0 = BWN_READ_2(mac, BWN_PHY0);
6723 	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6724 	if (phy->rev >= 3) {
6725 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
6726 			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6727 		BWN_PHY_WRITE(mac, 0x002e, 0);
6728 		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6729 		switch (phy->rev) {
6730 		case 4:
6731 		case 6:
6732 		case 7:
6733 			BWN_PHY_SET(mac, 0x0478, 0x0100);
6734 			BWN_PHY_SET(mac, 0x0801, 0x0040);
6735 			break;
6736 		case 3:
6737 		case 5:
6738 			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6739 			break;
6740 		}
6741 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6742 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6743 	}
6744 	/*
6745 	 * Calculate nrssi0
6746 	 */
6747 	BWN_RF_SET(mac, 0x007a, 0x0070);
6748 	bwn_set_all_gains(mac, 0, 8, 0);
6749 	BWN_RF_MASK(mac, 0x007a, 0x00f7);
6750 	if (phy->rev >= 2) {
6751 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6752 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6753 	}
6754 	BWN_RF_SET(mac, 0x007a, 0x0080);
6755 	DELAY(20);
6756 
6757 	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6758 	if (nrssi0 >= 0x0020)
6759 		nrssi0 -= 0x0040;
6760 
6761 	/*
6762 	 * Calculate nrssi1
6763 	 */
6764 	BWN_RF_MASK(mac, 0x007a, 0x007f);
6765 	if (phy->rev >= 2)
6766 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6767 
6768 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6769 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6770 	BWN_RF_SET(mac, 0x007a, 0x000f);
6771 	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6772 	if (phy->rev >= 2) {
6773 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6774 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6775 	}
6776 
6777 	bwn_set_all_gains(mac, 3, 0, 1);
6778 	if (phy->rf_rev == 8) {
6779 		BWN_RF_WRITE(mac, 0x0043, 0x001f);
6780 	} else {
6781 		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6782 		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6783 		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6784 		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6785 	}
6786 	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6787 	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6788 	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6789 	DELAY(20);
6790 	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6791 
6792 	/*
6793 	 * Install calculated narrow RSSI values
6794 	 */
6795 	if (nrssi1 >= 0x0020)
6796 		nrssi1 -= 0x0040;
6797 	if (nrssi0 == nrssi1)
6798 		pg->pg_nrssi_slope = 0x00010000;
6799 	else
6800 		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6801 	if (nrssi0 >= -4) {
6802 		pg->pg_nrssi[0] = nrssi1;
6803 		pg->pg_nrssi[1] = nrssi0;
6804 	}
6805 
6806 	/*
6807 	 * Restore saved RF/PHY registers
6808 	 */
6809 	if (phy->rev >= 3) {
6810 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6811 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6812 			    save_phy3[phy3_idx]);
6813 		}
6814 	}
6815 	if (phy->rev >= 2) {
6816 		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6817 		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6818 	}
6819 
6820 	for (i = 0; i < SAVE_RF_MAX; ++i)
6821 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6822 
6823 	BWN_WRITE_2(mac, 0x03e2, ant_div);
6824 	BWN_WRITE_2(mac, 0x03e6, phy0);
6825 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6826 
6827 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6828 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6829 
6830 	bwn_spu_workaround(mac, phy->chan);
6831 	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6832 	bwn_set_original_gains(mac);
6833 	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6834 	if (phy->rev >= 3) {
6835 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6836 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6837 			    save_phy3[phy3_idx]);
6838 		}
6839 	}
6840 
6841 	delta = 0x1f - pg->pg_nrssi[0];
6842 	for (i = 0; i < 64; i++) {
6843 		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6844 		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6845 		pg->pg_nrssi_lt[i] = tmp32;
6846 	}
6847 
6848 	bwn_nrssi_threshold(mac);
6849 #undef SAVE_RF_MAX
6850 #undef SAVE_PHY_COMM_MAX
6851 #undef SAVE_PHY3_MAX
6852 }
6853 
6854 static void
6855 bwn_nrssi_offset(struct bwn_mac *mac)
6856 {
6857 #define	SAVE_RF_MAX		2
6858 #define	SAVE_PHY_COMM_MAX	10
6859 #define	SAVE_PHY6_MAX		8
6860 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6861 		{ 0x7a, 0x43 };
6862 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6863 		0x0001, 0x0811, 0x0812, 0x0814,
6864 		0x0815, 0x005a, 0x0059, 0x0058,
6865 		0x000a, 0x0003
6866 	};
6867 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6868 		0x002e, 0x002f, 0x080f, 0x0810,
6869 		0x0801, 0x0060, 0x0014, 0x0478
6870 	};
6871 	struct bwn_phy *phy = &mac->mac_phy;
6872 	int i, phy6_idx = 0;
6873 	uint16_t save_rf[SAVE_RF_MAX];
6874 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6875 	uint16_t save_phy6[SAVE_PHY6_MAX];
6876 	int16_t nrssi;
6877 	uint16_t saved = 0xffff;
6878 
6879 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6880 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6881 	for (i = 0; i < SAVE_RF_MAX; ++i)
6882 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6883 
6884 	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6885 	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6886 	BWN_PHY_SET(mac, 0x0811, 0x000c);
6887 	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6888 	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6889 	if (phy->rev >= 6) {
6890 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
6891 			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6892 
6893 		BWN_PHY_WRITE(mac, 0x002e, 0);
6894 		BWN_PHY_WRITE(mac, 0x002f, 0);
6895 		BWN_PHY_WRITE(mac, 0x080f, 0);
6896 		BWN_PHY_WRITE(mac, 0x0810, 0);
6897 		BWN_PHY_SET(mac, 0x0478, 0x0100);
6898 		BWN_PHY_SET(mac, 0x0801, 0x0040);
6899 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6900 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6901 	}
6902 	BWN_RF_SET(mac, 0x007a, 0x0070);
6903 	BWN_RF_SET(mac, 0x007a, 0x0080);
6904 	DELAY(30);
6905 
6906 	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6907 	if (nrssi >= 0x20)
6908 		nrssi -= 0x40;
6909 	if (nrssi == 31) {
6910 		for (i = 7; i >= 4; i--) {
6911 			BWN_RF_WRITE(mac, 0x007b, i);
6912 			DELAY(20);
6913 			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6914 			    0x003f);
6915 			if (nrssi >= 0x20)
6916 				nrssi -= 0x40;
6917 			if (nrssi < 31 && saved == 0xffff)
6918 				saved = i;
6919 		}
6920 		if (saved == 0xffff)
6921 			saved = 4;
6922 	} else {
6923 		BWN_RF_MASK(mac, 0x007a, 0x007f);
6924 		if (phy->rev != 1) {
6925 			BWN_PHY_SET(mac, 0x0814, 0x0001);
6926 			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6927 		}
6928 		BWN_PHY_SET(mac, 0x0811, 0x000c);
6929 		BWN_PHY_SET(mac, 0x0812, 0x000c);
6930 		BWN_PHY_SET(mac, 0x0811, 0x0030);
6931 		BWN_PHY_SET(mac, 0x0812, 0x0030);
6932 		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6933 		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6934 		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6935 		if (phy->rev == 0)
6936 			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6937 		else
6938 			BWN_PHY_SET(mac, 0x000a, 0x2000);
6939 		if (phy->rev != 1) {
6940 			BWN_PHY_SET(mac, 0x0814, 0x0004);
6941 			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6942 		}
6943 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6944 		BWN_RF_SET(mac, 0x007a, 0x000f);
6945 		bwn_set_all_gains(mac, 3, 0, 1);
6946 		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6947 		DELAY(30);
6948 		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6949 		if (nrssi >= 0x20)
6950 			nrssi -= 0x40;
6951 		if (nrssi == -32) {
6952 			for (i = 0; i < 4; i++) {
6953 				BWN_RF_WRITE(mac, 0x007b, i);
6954 				DELAY(20);
6955 				nrssi = (int16_t)((BWN_PHY_READ(mac,
6956 				    0x047f) >> 8) & 0x003f);
6957 				if (nrssi >= 0x20)
6958 					nrssi -= 0x40;
6959 				if (nrssi > -31 && saved == 0xffff)
6960 					saved = i;
6961 			}
6962 			if (saved == 0xffff)
6963 				saved = 3;
6964 		} else
6965 			saved = 0;
6966 	}
6967 	BWN_RF_WRITE(mac, 0x007b, saved);
6968 
6969 	/*
6970 	 * Restore saved RF/PHY registers
6971 	 */
6972 	if (phy->rev >= 6) {
6973 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6974 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6975 			    save_phy6[phy6_idx]);
6976 		}
6977 	}
6978 	if (phy->rev != 1) {
6979 		for (i = 3; i < 5; i++)
6980 			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6981 			    save_phy_comm[i]);
6982 	}
6983 	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6984 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6985 
6986 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6987 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6988 
6989 	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6990 	BWN_PHY_SET(mac, 0x0429, 0x8000);
6991 	bwn_set_original_gains(mac);
6992 	if (phy->rev >= 6) {
6993 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6994 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6995 			    save_phy6[phy6_idx]);
6996 		}
6997 	}
6998 
6999 	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7000 	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7001 	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7002 }
7003 
7004 static void
7005 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7006     int16_t third)
7007 {
7008 	struct bwn_phy *phy = &mac->mac_phy;
7009 	uint16_t i;
7010 	uint16_t start = 0x08, end = 0x18;
7011 	uint16_t tmp;
7012 	uint16_t table;
7013 
7014 	if (phy->rev <= 1) {
7015 		start = 0x10;
7016 		end = 0x20;
7017 	}
7018 
7019 	table = BWN_OFDMTAB_GAINX;
7020 	if (phy->rev <= 1)
7021 		table = BWN_OFDMTAB_GAINX_R1;
7022 	for (i = 0; i < 4; i++)
7023 		bwn_ofdmtab_write_2(mac, table, i, first);
7024 
7025 	for (i = start; i < end; i++)
7026 		bwn_ofdmtab_write_2(mac, table, i, second);
7027 
7028 	if (third != -1) {
7029 		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7030 		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7031 		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7032 		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7033 	}
7034 	bwn_dummy_transmission(mac, 0, 1);
7035 }
7036 
7037 static void
7038 bwn_set_original_gains(struct bwn_mac *mac)
7039 {
7040 	struct bwn_phy *phy = &mac->mac_phy;
7041 	uint16_t i, tmp;
7042 	uint16_t table;
7043 	uint16_t start = 0x0008, end = 0x0018;
7044 
7045 	if (phy->rev <= 1) {
7046 		start = 0x0010;
7047 		end = 0x0020;
7048 	}
7049 
7050 	table = BWN_OFDMTAB_GAINX;
7051 	if (phy->rev <= 1)
7052 		table = BWN_OFDMTAB_GAINX_R1;
7053 	for (i = 0; i < 4; i++) {
7054 		tmp = (i & 0xfffc);
7055 		tmp |= (i & 0x0001) << 1;
7056 		tmp |= (i & 0x0002) >> 1;
7057 
7058 		bwn_ofdmtab_write_2(mac, table, i, tmp);
7059 	}
7060 
7061 	for (i = start; i < end; i++)
7062 		bwn_ofdmtab_write_2(mac, table, i, i - start);
7063 
7064 	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7065 	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7066 	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7067 	bwn_dummy_transmission(mac, 0, 1);
7068 }
7069 
7070 static void
7071 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7072 {
7073 	struct bwn_phy *phy = &mac->mac_phy;
7074 	struct bwn_phy_g *pg = &phy->phy_g;
7075 	struct bwn_rfatt old_rfatt, rfatt;
7076 	struct bwn_bbatt old_bbatt, bbatt;
7077 	struct bwn_softc *sc = mac->mac_sc;
7078 	uint8_t old_txctl = 0;
7079 
7080 	KASSERT(phy->type == BWN_PHYTYPE_G,
7081 	    ("%s:%d: fail", __func__, __LINE__));
7082 
7083 	if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7084 	    (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7085 		return;
7086 
7087 	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7088 
7089 	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7090 
7091 	if (!phy->gmode)
7092 		return;
7093 	bwn_hwpctl_early_init(mac);
7094 	if (pg->pg_curtssi == 0) {
7095 		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7096 			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7097 		} else {
7098 			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7099 			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7100 			old_txctl = pg->pg_txctl;
7101 
7102 			bbatt.att = 11;
7103 			if (phy->rf_rev == 8) {
7104 				rfatt.att = 15;
7105 				rfatt.padmix = 1;
7106 			} else {
7107 				rfatt.att = 9;
7108 				rfatt.padmix = 0;
7109 			}
7110 			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7111 		}
7112 		bwn_dummy_transmission(mac, 0, 1);
7113 		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7114 		if (phy->rf_ver == 0x2050 && phy->analog == 0)
7115 			BWN_RF_MASK(mac, 0x0076, 0xff7b);
7116 		else
7117 			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7118 			    &old_rfatt, old_txctl);
7119 	}
7120 	bwn_hwpctl_init_gphy(mac);
7121 
7122 	/* clear TSSI */
7123 	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7124 	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7125 	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7126 	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7127 }
7128 
7129 static void
7130 bwn_hwpctl_early_init(struct bwn_mac *mac)
7131 {
7132 	struct bwn_phy *phy = &mac->mac_phy;
7133 
7134 	if (!bwn_has_hwpctl(mac)) {
7135 		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7136 		return;
7137 	}
7138 
7139 	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7140 	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7141 	BWN_PHY_SET(mac, 0x047c, 0x0002);
7142 	BWN_PHY_SET(mac, 0x047a, 0xf000);
7143 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7144 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7145 		BWN_PHY_SET(mac, 0x005d, 0x8000);
7146 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7147 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7148 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7149 	} else {
7150 		BWN_PHY_SET(mac, 0x0036, 0x0200);
7151 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7152 		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7153 		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7154 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7155 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7156 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7157 	}
7158 }
7159 
7160 static void
7161 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7162 {
7163 	struct bwn_phy *phy = &mac->mac_phy;
7164 	struct bwn_phy_g *pg = &phy->phy_g;
7165 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7166 	int i;
7167 	uint16_t nr_written = 0, tmp, value;
7168 	uint8_t rf, bb;
7169 
7170 	if (!bwn_has_hwpctl(mac)) {
7171 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7172 		return;
7173 	}
7174 
7175 	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7176 	    (pg->pg_idletssi - pg->pg_curtssi));
7177 	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7178 	    (pg->pg_idletssi - pg->pg_curtssi));
7179 
7180 	for (i = 0; i < 32; i++)
7181 		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7182 	for (i = 32; i < 64; i++)
7183 		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7184 	for (i = 0; i < 64; i += 2) {
7185 		value = (uint16_t) pg->pg_tssi2dbm[i];
7186 		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7187 		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7188 	}
7189 
7190 	for (rf = 0; rf < lo->rfatt.len; rf++) {
7191 		for (bb = 0; bb < lo->bbatt.len; bb++) {
7192 			if (nr_written >= 0x40)
7193 				return;
7194 			tmp = lo->bbatt.array[bb].att;
7195 			tmp <<= 8;
7196 			if (phy->rf_rev == 8)
7197 				tmp |= 0x50;
7198 			else
7199 				tmp |= 0x40;
7200 			tmp |= lo->rfatt.array[rf].att;
7201 			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7202 			nr_written++;
7203 		}
7204 	}
7205 
7206 	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7207 	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7208 
7209 	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7210 	BWN_PHY_SET(mac, 0x0478, 0x0800);
7211 	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7212 	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7213 
7214 	bwn_phy_g_dc_lookup_init(mac, 1);
7215 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7216 }
7217 
7218 static void
7219 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7220 {
7221 	struct bwn_softc *sc = mac->mac_sc;
7222 
7223 	if (spu != 0)
7224 		bwn_spu_workaround(mac, channel);
7225 
7226 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7227 
7228 	if (channel == 14) {
7229 		if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7230 			bwn_hf_write(mac,
7231 			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7232 		else
7233 			bwn_hf_write(mac,
7234 			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7235 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7236 		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7237 		return;
7238 	}
7239 
7240 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7241 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7242 }
7243 
7244 static uint16_t
7245 bwn_phy_g_chan2freq(uint8_t channel)
7246 {
7247 	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7248 
7249 	KASSERT(channel >= 1 && channel <= 14,
7250 	    ("%s:%d: fail", __func__, __LINE__));
7251 
7252 	return (bwn_phy_g_rf_channels[channel - 1]);
7253 }
7254 
7255 static void
7256 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7257     const struct bwn_rfatt *rfatt, uint8_t txctl)
7258 {
7259 	struct bwn_phy *phy = &mac->mac_phy;
7260 	struct bwn_phy_g *pg = &phy->phy_g;
7261 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7262 	uint16_t bb, rf;
7263 	uint16_t tx_bias, tx_magn;
7264 
7265 	bb = bbatt->att;
7266 	rf = rfatt->att;
7267 	tx_bias = lo->tx_bias;
7268 	tx_magn = lo->tx_magn;
7269 	if (tx_bias == 0xff)
7270 		tx_bias = 0;
7271 
7272 	pg->pg_txctl = txctl;
7273 	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7274 	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7275 	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7276 	bwn_phy_g_set_bbatt(mac, bb);
7277 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7278 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7279 		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7280 	else {
7281 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7282 		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7283 	}
7284 	if (BWN_HAS_TXMAG(phy))
7285 		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7286 	else
7287 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7288 	bwn_lo_g_adjust(mac);
7289 }
7290 
7291 static void
7292 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7293     uint16_t bbatt)
7294 {
7295 	struct bwn_phy *phy = &mac->mac_phy;
7296 
7297 	if (phy->analog == 0) {
7298 		BWN_WRITE_2(mac, BWN_PHY0,
7299 		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7300 		return;
7301 	}
7302 	if (phy->analog > 1) {
7303 		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7304 		return;
7305 	}
7306 	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7307 }
7308 
7309 static uint16_t
7310 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7311 {
7312 	struct bwn_phy *phy = &mac->mac_phy;
7313 	struct bwn_phy_g *pg = &phy->phy_g;
7314 	struct bwn_softc *sc = mac->mac_sc;
7315 	int max_lb_gain;
7316 	uint16_t extlna;
7317 	uint16_t i;
7318 
7319 	if (phy->gmode == 0)
7320 		return (0);
7321 
7322 	if (BWN_HAS_LOOPBACK(phy)) {
7323 		max_lb_gain = pg->pg_max_lb_gain;
7324 		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7325 		if (max_lb_gain >= 0x46) {
7326 			extlna = 0x3000;
7327 			max_lb_gain -= 0x46;
7328 		} else if (max_lb_gain >= 0x3a) {
7329 			extlna = 0x1000;
7330 			max_lb_gain -= 0x3a;
7331 		} else if (max_lb_gain >= 0x2e) {
7332 			extlna = 0x2000;
7333 			max_lb_gain -= 0x2e;
7334 		} else {
7335 			extlna = 0;
7336 			max_lb_gain -= 0x10;
7337 		}
7338 
7339 		for (i = 0; i < 16; i++) {
7340 			max_lb_gain -= (i * 6);
7341 			if (max_lb_gain < 6)
7342 				break;
7343 		}
7344 
7345 		if ((phy->rev < 7) ||
7346 		    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7347 			if (reg == BWN_PHY_RFOVER) {
7348 				return (0x1b3);
7349 			} else if (reg == BWN_PHY_RFOVERVAL) {
7350 				extlna |= (i << 8);
7351 				switch (lpd) {
7352 				case BWN_LPD(0, 1, 1):
7353 					return (0x0f92);
7354 				case BWN_LPD(0, 0, 1):
7355 				case BWN_LPD(1, 0, 1):
7356 					return (0x0092 | extlna);
7357 				case BWN_LPD(1, 0, 0):
7358 					return (0x0093 | extlna);
7359 				}
7360 				KASSERT(0 == 1,
7361 				    ("%s:%d: fail", __func__, __LINE__));
7362 			}
7363 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7364 		} else {
7365 			if (reg == BWN_PHY_RFOVER)
7366 				return (0x9b3);
7367 			if (reg == BWN_PHY_RFOVERVAL) {
7368 				if (extlna)
7369 					extlna |= 0x8000;
7370 				extlna |= (i << 8);
7371 				switch (lpd) {
7372 				case BWN_LPD(0, 1, 1):
7373 					return (0x8f92);
7374 				case BWN_LPD(0, 0, 1):
7375 					return (0x8092 | extlna);
7376 				case BWN_LPD(1, 0, 1):
7377 					return (0x2092 | extlna);
7378 				case BWN_LPD(1, 0, 0):
7379 					return (0x2093 | extlna);
7380 				}
7381 				KASSERT(0 == 1,
7382 				    ("%s:%d: fail", __func__, __LINE__));
7383 			}
7384 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7385 		}
7386 		return (0);
7387 	}
7388 
7389 	if ((phy->rev < 7) ||
7390 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7391 		if (reg == BWN_PHY_RFOVER) {
7392 			return (0x1b3);
7393 		} else if (reg == BWN_PHY_RFOVERVAL) {
7394 			switch (lpd) {
7395 			case BWN_LPD(0, 1, 1):
7396 				return (0x0fb2);
7397 			case BWN_LPD(0, 0, 1):
7398 				return (0x00b2);
7399 			case BWN_LPD(1, 0, 1):
7400 				return (0x30b2);
7401 			case BWN_LPD(1, 0, 0):
7402 				return (0x30b3);
7403 			}
7404 			KASSERT(0 == 1,
7405 			    ("%s:%d: fail", __func__, __LINE__));
7406 		}
7407 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7408 	} else {
7409 		if (reg == BWN_PHY_RFOVER) {
7410 			return (0x9b3);
7411 		} else if (reg == BWN_PHY_RFOVERVAL) {
7412 			switch (lpd) {
7413 			case BWN_LPD(0, 1, 1):
7414 				return (0x8fb2);
7415 			case BWN_LPD(0, 0, 1):
7416 				return (0x80b2);
7417 			case BWN_LPD(1, 0, 1):
7418 				return (0x20b2);
7419 			case BWN_LPD(1, 0, 0):
7420 				return (0x20b3);
7421 			}
7422 			KASSERT(0 == 1,
7423 			    ("%s:%d: fail", __func__, __LINE__));
7424 		}
7425 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7426 	}
7427 	return (0);
7428 }
7429 
7430 static void
7431 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7432 {
7433 
7434 	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7435 		return;
7436 	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7437 	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7438 	DELAY(1000);
7439 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7440 }
7441 
7442 static int
7443 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7444 {
7445 	struct bwn_softc *sc = mac->mac_sc;
7446 	struct bwn_fw *fw = &mac->mac_fw;
7447 	const uint8_t rev = siba_get_revid(sc->sc_dev);
7448 	const char *filename;
7449 	uint32_t high;
7450 	int error;
7451 
7452 	/* microcode */
7453 	if (rev >= 5 && rev <= 10)
7454 		filename = "ucode5";
7455 	else if (rev >= 11 && rev <= 12)
7456 		filename = "ucode11";
7457 	else if (rev == 13)
7458 		filename = "ucode13";
7459 	else if (rev == 14)
7460 		filename = "ucode14";
7461 	else if (rev >= 15)
7462 		filename = "ucode15";
7463 	else {
7464 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7465 		bwn_release_firmware(mac);
7466 		return (EOPNOTSUPP);
7467 	}
7468 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
7469 	if (error) {
7470 		bwn_release_firmware(mac);
7471 		return (error);
7472 	}
7473 
7474 	/* PCM */
7475 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7476 	if (rev >= 5 && rev <= 10) {
7477 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7478 		if (error == ENOENT)
7479 			fw->no_pcmfile = 1;
7480 		else if (error) {
7481 			bwn_release_firmware(mac);
7482 			return (error);
7483 		}
7484 	} else if (rev < 11) {
7485 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7486 		return (EOPNOTSUPP);
7487 	}
7488 
7489 	/* initvals */
7490 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7491 	switch (mac->mac_phy.type) {
7492 	case BWN_PHYTYPE_A:
7493 		if (rev < 5 || rev > 10)
7494 			goto fail1;
7495 		if (high & BWN_TGSHIGH_HAVE_2GHZ)
7496 			filename = "a0g1initvals5";
7497 		else
7498 			filename = "a0g0initvals5";
7499 		break;
7500 	case BWN_PHYTYPE_G:
7501 		if (rev >= 5 && rev <= 10)
7502 			filename = "b0g0initvals5";
7503 		else if (rev >= 13)
7504 			filename = "b0g0initvals13";
7505 		else
7506 			goto fail1;
7507 		break;
7508 	case BWN_PHYTYPE_LP:
7509 		if (rev == 13)
7510 			filename = "lp0initvals13";
7511 		else if (rev == 14)
7512 			filename = "lp0initvals14";
7513 		else if (rev >= 15)
7514 			filename = "lp0initvals15";
7515 		else
7516 			goto fail1;
7517 		break;
7518 	case BWN_PHYTYPE_N:
7519 		if (rev >= 11 && rev <= 12)
7520 			filename = "n0initvals11";
7521 		else
7522 			goto fail1;
7523 		break;
7524 	default:
7525 		goto fail1;
7526 	}
7527 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
7528 	if (error) {
7529 		bwn_release_firmware(mac);
7530 		return (error);
7531 	}
7532 
7533 	/* bandswitch initvals */
7534 	switch (mac->mac_phy.type) {
7535 	case BWN_PHYTYPE_A:
7536 		if (rev >= 5 && rev <= 10) {
7537 			if (high & BWN_TGSHIGH_HAVE_2GHZ)
7538 				filename = "a0g1bsinitvals5";
7539 			else
7540 				filename = "a0g0bsinitvals5";
7541 		} else if (rev >= 11)
7542 			filename = NULL;
7543 		else
7544 			goto fail1;
7545 		break;
7546 	case BWN_PHYTYPE_G:
7547 		if (rev >= 5 && rev <= 10)
7548 			filename = "b0g0bsinitvals5";
7549 		else if (rev >= 11)
7550 			filename = NULL;
7551 		else
7552 			goto fail1;
7553 		break;
7554 	case BWN_PHYTYPE_LP:
7555 		if (rev == 13)
7556 			filename = "lp0bsinitvals13";
7557 		else if (rev == 14)
7558 			filename = "lp0bsinitvals14";
7559 		else if (rev >= 15)
7560 			filename = "lp0bsinitvals15";
7561 		else
7562 			goto fail1;
7563 		break;
7564 	case BWN_PHYTYPE_N:
7565 		if (rev >= 11 && rev <= 12)
7566 			filename = "n0bsinitvals11";
7567 		else
7568 			goto fail1;
7569 		break;
7570 	default:
7571 		goto fail1;
7572 	}
7573 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7574 	if (error) {
7575 		bwn_release_firmware(mac);
7576 		return (error);
7577 	}
7578 	return (0);
7579 fail1:
7580 	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7581 	bwn_release_firmware(mac);
7582 	return (EOPNOTSUPP);
7583 }
7584 
7585 static int
7586 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7587     const char *name, struct bwn_fwfile *bfw)
7588 {
7589 	const struct bwn_fwhdr *hdr;
7590 	struct bwn_softc *sc = mac->mac_sc;
7591 	const struct firmware *fw;
7592 	char namebuf[64];
7593 
7594 	if (name == NULL) {
7595 		bwn_do_release_fw(bfw);
7596 		return (0);
7597 	}
7598 	if (bfw->filename != NULL) {
7599 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7600 			return (0);
7601 		bwn_do_release_fw(bfw);
7602 	}
7603 
7604 	ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7605 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7606 	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7607 	wlan_assert_serialized();
7608 	wlan_serialize_exit();
7609 	fw = firmware_get(namebuf);
7610 	wlan_serialize_enter();
7611 	if (fw == NULL) {
7612 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7613 		    namebuf);
7614 		return (ENOENT);
7615 	}
7616 	if (fw->datasize < sizeof(struct bwn_fwhdr))
7617 		goto fail;
7618 	hdr = (const struct bwn_fwhdr *)(fw->data);
7619 	switch (hdr->type) {
7620 	case BWN_FWTYPE_UCODE:
7621 	case BWN_FWTYPE_PCM:
7622 		if (be32toh(hdr->size) !=
7623 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
7624 			goto fail;
7625 		/* FALLTHROUGH */
7626 	case BWN_FWTYPE_IV:
7627 		if (hdr->ver != 1)
7628 			goto fail;
7629 		break;
7630 	default:
7631 		goto fail;
7632 	}
7633 	bfw->filename = name;
7634 	bfw->fw = fw;
7635 	bfw->type = type;
7636 	return (0);
7637 fail:
7638 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7639 	if (fw != NULL)
7640 		firmware_put(fw, FIRMWARE_UNLOAD);
7641 	return (EPROTO);
7642 }
7643 
7644 static void
7645 bwn_release_firmware(struct bwn_mac *mac)
7646 {
7647 
7648 	bwn_do_release_fw(&mac->mac_fw.ucode);
7649 	bwn_do_release_fw(&mac->mac_fw.pcm);
7650 	bwn_do_release_fw(&mac->mac_fw.initvals);
7651 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
7652 }
7653 
7654 static void
7655 bwn_do_release_fw(struct bwn_fwfile *bfw)
7656 {
7657 
7658 	if (bfw->fw != NULL)
7659 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7660 	bfw->fw = NULL;
7661 	bfw->filename = NULL;
7662 }
7663 
7664 static int
7665 bwn_fw_loaducode(struct bwn_mac *mac)
7666 {
7667 #define	GETFWOFFSET(fwp, offset)	\
7668 	((const uint32_t *)((const char *)fwp.fw->data + offset))
7669 #define	GETFWSIZE(fwp, offset)	\
7670 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
7671 	struct bwn_softc *sc = mac->mac_sc;
7672 	const uint32_t *data;
7673 	unsigned int i;
7674 	uint32_t ctl;
7675 	uint16_t date, fwcaps, time;
7676 	int error = 0;
7677 
7678 	ctl = BWN_READ_4(mac, BWN_MACCTL);
7679 	ctl |= BWN_MACCTL_MCODE_JMP0;
7680 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7681 	    __LINE__));
7682 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7683 	for (i = 0; i < 64; i++)
7684 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7685 	for (i = 0; i < 4096; i += 2)
7686 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7687 
7688 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7689 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7690 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7691 	     i++) {
7692 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7693 		DELAY(10);
7694 	}
7695 
7696 	if (mac->mac_fw.pcm.fw) {
7697 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7698 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7699 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7700 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7701 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7702 		    sizeof(struct bwn_fwhdr)); i++) {
7703 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7704 			DELAY(10);
7705 		}
7706 	}
7707 
7708 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7709 	BWN_WRITE_4(mac, BWN_MACCTL,
7710 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7711 	    BWN_MACCTL_MCODE_RUN);
7712 
7713 	for (i = 0; i < 21; i++) {
7714 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7715 			break;
7716 		if (i >= 20) {
7717 			device_printf(sc->sc_dev, "ucode timeout\n");
7718 			error = ENXIO;
7719 			goto error;
7720 		}
7721 		DELAY(50000);
7722 	}
7723 	BWN_READ_4(mac, BWN_INTR_REASON);
7724 
7725 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7726 	if (mac->mac_fw.rev <= 0x128) {
7727 		device_printf(sc->sc_dev, "the firmware is too old\n");
7728 		error = EOPNOTSUPP;
7729 		goto error;
7730 	}
7731 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7732 	    BWN_SHARED_UCODE_PATCH);
7733 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7734 	mac->mac_fw.opensource = (date == 0xffff);
7735 	if (bwn_wme != 0)
7736 		mac->mac_flags |= BWN_MAC_FLAG_WME;
7737 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7738 
7739 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7740 	if (mac->mac_fw.opensource == 0) {
7741 		device_printf(sc->sc_dev,
7742 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
7743 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7744 		if (mac->mac_fw.no_pcmfile)
7745 			device_printf(sc->sc_dev,
7746 			    "no HW crypto acceleration due to pcm5\n");
7747 	} else {
7748 		mac->mac_fw.patch = time;
7749 		fwcaps = bwn_fwcaps_read(mac);
7750 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7751 			device_printf(sc->sc_dev,
7752 			    "disabling HW crypto acceleration\n");
7753 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7754 		}
7755 		if (!(fwcaps & BWN_FWCAPS_WME)) {
7756 			device_printf(sc->sc_dev, "disabling WME support\n");
7757 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7758 		}
7759 	}
7760 
7761 	if (BWN_ISOLDFMT(mac))
7762 		device_printf(sc->sc_dev, "using old firmware image\n");
7763 
7764 	return (0);
7765 
7766 error:
7767 	BWN_WRITE_4(mac, BWN_MACCTL,
7768 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7769 	    BWN_MACCTL_MCODE_JMP0);
7770 
7771 	return (error);
7772 #undef GETFWSIZE
7773 #undef GETFWOFFSET
7774 }
7775 
7776 /* OpenFirmware only */
7777 static uint16_t
7778 bwn_fwcaps_read(struct bwn_mac *mac)
7779 {
7780 
7781 	KASSERT(mac->mac_fw.opensource == 1,
7782 	    ("%s:%d: fail", __func__, __LINE__));
7783 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7784 }
7785 
7786 static int
7787 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7788     size_t count, size_t array_size)
7789 {
7790 #define	GET_NEXTIV16(iv)						\
7791 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7792 	    sizeof(uint16_t) + sizeof(uint16_t)))
7793 #define	GET_NEXTIV32(iv)						\
7794 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7795 	    sizeof(uint16_t) + sizeof(uint32_t)))
7796 	struct bwn_softc *sc = mac->mac_sc;
7797 	const struct bwn_fwinitvals *iv;
7798 	uint16_t offset;
7799 	size_t i;
7800 	uint8_t bit32;
7801 
7802 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7803 	    ("%s:%d: fail", __func__, __LINE__));
7804 	iv = ivals;
7805 	for (i = 0; i < count; i++) {
7806 		if (array_size < sizeof(iv->offset_size))
7807 			goto fail;
7808 		array_size -= sizeof(iv->offset_size);
7809 		offset = be16toh(iv->offset_size);
7810 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7811 		offset &= BWN_FWINITVALS_OFFSET_MASK;
7812 		if (offset >= 0x1000)
7813 			goto fail;
7814 		if (bit32) {
7815 			if (array_size < sizeof(iv->data.d32))
7816 				goto fail;
7817 			array_size -= sizeof(iv->data.d32);
7818 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7819 			iv = GET_NEXTIV32(iv);
7820 		} else {
7821 
7822 			if (array_size < sizeof(iv->data.d16))
7823 				goto fail;
7824 			array_size -= sizeof(iv->data.d16);
7825 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7826 
7827 			iv = GET_NEXTIV16(iv);
7828 		}
7829 	}
7830 	if (array_size != 0)
7831 		goto fail;
7832 	return (0);
7833 fail:
7834 	device_printf(sc->sc_dev, "initvals: invalid format\n");
7835 	return (EPROTO);
7836 #undef GET_NEXTIV16
7837 #undef GET_NEXTIV32
7838 }
7839 
7840 static int
7841 bwn_switch_channel(struct bwn_mac *mac, int chan)
7842 {
7843 	struct bwn_phy *phy = &(mac->mac_phy);
7844 	struct bwn_softc *sc = mac->mac_sc;
7845 	struct ifnet *ifp = sc->sc_ifp;
7846 	struct ieee80211com *ic = ifp->if_l2com;
7847 	uint16_t channelcookie, savedcookie;
7848 	int error;
7849 
7850 	if (chan == 0xffff)
7851 		chan = phy->get_default_chan(mac);
7852 
7853 	channelcookie = chan;
7854 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7855 		channelcookie |= 0x100;
7856 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7857 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7858 	error = phy->switch_channel(mac, chan);
7859 	if (error)
7860 		goto fail;
7861 
7862 	mac->mac_phy.chan = chan;
7863 	DELAY(8000);
7864 	return (0);
7865 fail:
7866 	device_printf(sc->sc_dev, "failed to switch channel\n");
7867 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7868 	return (error);
7869 }
7870 
7871 static uint16_t
7872 bwn_ant2phy(int antenna)
7873 {
7874 
7875 	switch (antenna) {
7876 	case BWN_ANT0:
7877 		return (BWN_TX_PHY_ANT0);
7878 	case BWN_ANT1:
7879 		return (BWN_TX_PHY_ANT1);
7880 	case BWN_ANT2:
7881 		return (BWN_TX_PHY_ANT2);
7882 	case BWN_ANT3:
7883 		return (BWN_TX_PHY_ANT3);
7884 	case BWN_ANTAUTO:
7885 		return (BWN_TX_PHY_ANT01AUTO);
7886 	}
7887 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7888 	return (0);
7889 }
7890 
7891 static void
7892 bwn_wme_load(struct bwn_mac *mac)
7893 {
7894 	struct bwn_softc *sc = mac->mac_sc;
7895 	int i;
7896 
7897 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7898 	    ("%s:%d: fail", __func__, __LINE__));
7899 
7900 	bwn_mac_suspend(mac);
7901 	for (i = 0; i < N(sc->sc_wmeParams); i++)
7902 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7903 		    bwn_wme_shm_offsets[i]);
7904 	bwn_mac_enable(mac);
7905 }
7906 
7907 static void
7908 bwn_wme_loadparams(struct bwn_mac *mac,
7909     const struct wmeParams *p, uint16_t shm_offset)
7910 {
7911 #define	SM(_v, _f)      (((_v) << _f##_S) & _f)
7912 	struct bwn_softc *sc = mac->mac_sc;
7913 	uint16_t params[BWN_NR_WMEPARAMS];
7914 	int slot, tmp;
7915 	unsigned int i;
7916 
7917 	slot = BWN_READ_2(mac, BWN_RNG) &
7918 	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7919 
7920 	memset(&params, 0, sizeof(params));
7921 
7922 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7923 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7924 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7925 
7926 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7927 	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7928 	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7929 	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7930 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7931 	params[BWN_WMEPARAM_BSLOTS] = slot;
7932 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7933 
7934 	for (i = 0; i < N(params); i++) {
7935 		if (i == BWN_WMEPARAM_STATUS) {
7936 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
7937 			    shm_offset + (i * 2));
7938 			tmp |= 0x100;
7939 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7940 			    tmp);
7941 		} else {
7942 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7943 			    params[i]);
7944 		}
7945 	}
7946 }
7947 
7948 static void
7949 bwn_mac_write_bssid(struct bwn_mac *mac)
7950 {
7951 	struct bwn_softc *sc = mac->mac_sc;
7952 	uint32_t tmp;
7953 	int i;
7954 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7955 
7956 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7957 	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
7958 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7959 	    IEEE80211_ADDR_LEN);
7960 
7961 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7962 		tmp = (uint32_t) (mac_bssid[i + 0]);
7963 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7964 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7965 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7966 		bwn_ram_write(mac, 0x20 + i, tmp);
7967 	}
7968 }
7969 
7970 static void
7971 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7972     const uint8_t *macaddr)
7973 {
7974 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7975 	uint16_t data;
7976 
7977 	if (mac == NULL)
7978 		macaddr = zero;
7979 
7980 	offset |= 0x0020;
7981 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7982 
7983 	data = macaddr[0];
7984 	data |= macaddr[1] << 8;
7985 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7986 	data = macaddr[2];
7987 	data |= macaddr[3] << 8;
7988 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7989 	data = macaddr[4];
7990 	data |= macaddr[5] << 8;
7991 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7992 }
7993 
7994 static void
7995 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7996     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
7997 {
7998 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
7999 	uint8_t per_sta_keys_start = 8;
8000 
8001 	if (BWN_SEC_NEWAPI(mac))
8002 		per_sta_keys_start = 4;
8003 
8004 	KASSERT(index < mac->mac_max_nr_keys,
8005 	    ("%s:%d: fail", __func__, __LINE__));
8006 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
8007 	    ("%s:%d: fail", __func__, __LINE__));
8008 
8009 	if (index >= per_sta_keys_start)
8010 		bwn_key_macwrite(mac, index, NULL);
8011 	if (key)
8012 		memcpy(buf, key, key_len);
8013 	bwn_key_write(mac, index, algorithm, buf);
8014 	if (index >= per_sta_keys_start)
8015 		bwn_key_macwrite(mac, index, mac_addr);
8016 
8017 	mac->mac_key[index].algorithm = algorithm;
8018 }
8019 
8020 static void
8021 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8022 {
8023 	struct bwn_softc *sc = mac->mac_sc;
8024 	uint32_t addrtmp[2] = { 0, 0 };
8025 	uint8_t start = 8;
8026 
8027 	if (BWN_SEC_NEWAPI(mac))
8028 		start = 4;
8029 
8030 	KASSERT(index >= start,
8031 	    ("%s:%d: fail", __func__, __LINE__));
8032 	index -= start;
8033 
8034 	if (addr) {
8035 		addrtmp[0] = addr[0];
8036 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8037 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8038 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8039 		addrtmp[1] = addr[4];
8040 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8041 	}
8042 
8043 	if (siba_get_revid(sc->sc_dev) >= 5) {
8044 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8045 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8046 	} else {
8047 		if (index >= 8) {
8048 			bwn_shm_write_4(mac, BWN_SHARED,
8049 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8050 			bwn_shm_write_2(mac, BWN_SHARED,
8051 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8052 		}
8053 	}
8054 }
8055 
8056 static void
8057 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8058     const uint8_t *key)
8059 {
8060 	unsigned int i;
8061 	uint32_t offset;
8062 	uint16_t kidx, value;
8063 
8064 	kidx = BWN_SEC_KEY2FW(mac, index);
8065 	bwn_shm_write_2(mac, BWN_SHARED,
8066 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8067 
8068 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8069 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8070 		value = key[i];
8071 		value |= (uint16_t)(key[i + 1]) << 8;
8072 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8073 	}
8074 }
8075 
8076 static void
8077 bwn_phy_exit(struct bwn_mac *mac)
8078 {
8079 
8080 	mac->mac_phy.rf_onoff(mac, 0);
8081 	if (mac->mac_phy.exit != NULL)
8082 		mac->mac_phy.exit(mac);
8083 }
8084 
8085 static void
8086 bwn_dma_free(struct bwn_mac *mac)
8087 {
8088 	struct bwn_dma *dma;
8089 
8090 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8091 		return;
8092 	dma = &mac->mac_method.dma;
8093 
8094 	bwn_dma_ringfree(&dma->rx);
8095 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8096 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8097 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8098 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8099 	bwn_dma_ringfree(&dma->mcast);
8100 }
8101 
8102 static void
8103 bwn_core_stop(struct bwn_mac *mac)
8104 {
8105 	struct bwn_softc *sc = mac->mac_sc;
8106 
8107 	wlan_assert_serialized();
8108 
8109 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8110 		return;
8111 
8112 	callout_stop(&sc->sc_rfswitch_ch);
8113 	callout_stop(&sc->sc_task_ch);
8114 	callout_stop(&sc->sc_watchdog_ch);
8115 	sc->sc_watchdog_timer = 0;
8116 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8117 	BWN_READ_4(mac, BWN_INTR_MASK);
8118 	bwn_mac_suspend(mac);
8119 
8120 	mac->mac_status = BWN_MAC_STATUS_INITED;
8121 }
8122 
8123 static int
8124 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8125 {
8126 	struct bwn_mac *up_dev = NULL;
8127 	struct bwn_mac *down_dev;
8128 	struct bwn_mac *mac;
8129 	int err, status;
8130 	uint8_t gmode;
8131 
8132 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8133 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8134 		    mac->mac_phy.supports_2ghz) {
8135 			up_dev = mac;
8136 			gmode = 1;
8137 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8138 		    mac->mac_phy.supports_5ghz) {
8139 			up_dev = mac;
8140 			gmode = 0;
8141 		} else {
8142 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8143 			return (EINVAL);
8144 		}
8145 		if (up_dev != NULL)
8146 			break;
8147 	}
8148 	if (up_dev == NULL) {
8149 		device_printf(sc->sc_dev, "Could not find a device\n");
8150 		return (ENODEV);
8151 	}
8152 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8153 		return (0);
8154 
8155 	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8156 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8157 
8158 	down_dev = sc->sc_curmac;
8159 	status = down_dev->mac_status;
8160 	if (status >= BWN_MAC_STATUS_STARTED)
8161 		bwn_core_stop(down_dev);
8162 	if (status >= BWN_MAC_STATUS_INITED)
8163 		bwn_core_exit(down_dev);
8164 
8165 	if (down_dev != up_dev)
8166 		bwn_phy_reset(down_dev);
8167 
8168 	up_dev->mac_phy.gmode = gmode;
8169 	if (status >= BWN_MAC_STATUS_INITED) {
8170 		err = bwn_core_init(up_dev);
8171 		if (err) {
8172 			device_printf(sc->sc_dev,
8173 			    "fatal: failed to initialize for %s-GHz\n",
8174 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8175 			goto fail;
8176 		}
8177 	}
8178 	if (status >= BWN_MAC_STATUS_STARTED)
8179 		bwn_core_start(up_dev);
8180 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8181 	sc->sc_curmac = up_dev;
8182 
8183 	return (0);
8184 fail:
8185 	sc->sc_curmac = NULL;
8186 	return (err);
8187 }
8188 
8189 static void
8190 bwn_rf_turnon(struct bwn_mac *mac)
8191 {
8192 
8193 	bwn_mac_suspend(mac);
8194 	mac->mac_phy.rf_onoff(mac, 1);
8195 	mac->mac_phy.rf_on = 1;
8196 	bwn_mac_enable(mac);
8197 }
8198 
8199 static void
8200 bwn_rf_turnoff(struct bwn_mac *mac)
8201 {
8202 
8203 	bwn_mac_suspend(mac);
8204 	mac->mac_phy.rf_onoff(mac, 0);
8205 	mac->mac_phy.rf_on = 0;
8206 	bwn_mac_enable(mac);
8207 }
8208 
8209 static void
8210 bwn_phy_reset(struct bwn_mac *mac)
8211 {
8212 	struct bwn_softc *sc = mac->mac_sc;
8213 
8214 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8215 	    ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8216 	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8217 	DELAY(1000);
8218 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8219 	    (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8220 	    BWN_TGSLOW_PHYRESET);
8221 	DELAY(1000);
8222 }
8223 
8224 static int
8225 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8226 {
8227 	struct bwn_vap *bvp = BWN_VAP(vap);
8228 	struct ieee80211com *ic= vap->iv_ic;
8229 	struct ifnet *ifp = ic->ic_ifp;
8230 	enum ieee80211_state ostate = vap->iv_state;
8231 	struct bwn_softc *sc = ic->ic_softc;
8232 	struct bwn_mac *mac = sc->sc_curmac;
8233 	int error;
8234 
8235 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8236 	    ieee80211_state_name[vap->iv_state],
8237 	    ieee80211_state_name[nstate]);
8238 
8239 	error = bvp->bv_newstate(vap, nstate, arg);
8240 	if (error != 0)
8241 		return (error);
8242 
8243 	bwn_led_newstate(mac, nstate);
8244 
8245 	/*
8246 	 * Clear the BSSID when we stop a STA
8247 	 */
8248 	if (vap->iv_opmode == IEEE80211_M_STA) {
8249 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8250 			/*
8251 			 * Clear out the BSSID.  If we reassociate to
8252 			 * the same AP, this will reinialize things
8253 			 * correctly...
8254 			 */
8255 			if (ic->ic_opmode == IEEE80211_M_STA &&
8256 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8257 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8258 				bwn_set_macaddr(mac);
8259 			}
8260 		}
8261 	}
8262 
8263 	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8264 	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
8265 		/* XXX nothing to do? */
8266 	} else if (nstate == IEEE80211_S_RUN) {
8267 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8268 		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8269 		bwn_set_opmode(mac);
8270 		bwn_set_pretbtt(mac);
8271 		bwn_spu_setdelay(mac, 0);
8272 		bwn_set_macaddr(mac);
8273 	}
8274 
8275 	return (error);
8276 }
8277 
8278 static void
8279 bwn_set_pretbtt(struct bwn_mac *mac)
8280 {
8281 	struct bwn_softc *sc = mac->mac_sc;
8282 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8283 	uint16_t pretbtt;
8284 
8285 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8286 		pretbtt = 2;
8287 	else
8288 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8289 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8290 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8291 }
8292 
8293 static void
8294 bwn_intr(void *arg)
8295 {
8296 	struct bwn_mac *mac = arg;
8297 	struct bwn_softc *sc = mac->mac_sc;
8298 	uint32_t reason;
8299 
8300 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8301 	    (sc->sc_flags & BWN_FLAG_INVALID))
8302 		return;
8303 
8304 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
8305 	if (reason == 0xffffffff)	/* shared IRQ */
8306 		return;
8307 	reason &= mac->mac_intr_mask;
8308 	if (reason == 0)
8309 		return;
8310 
8311 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00;
8312 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8313 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8314 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8315 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8316 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8317 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8318 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8319 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8320 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8321 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8322 
8323 	/* Disable interrupts. */
8324 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8325 
8326 	mac->mac_reason_intr = reason;
8327 
8328 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8329 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8330 
8331 	taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
8332 	return;
8333 }
8334 
8335 static void
8336 bwn_intrtask(void *arg, int npending)
8337 {
8338 	struct bwn_mac *mac = arg;
8339 	struct bwn_softc *sc = mac->mac_sc;
8340 	struct ifnet *ifp = sc->sc_ifp;
8341 	uint32_t merged = 0;
8342 	int i, tx = 0, rx = 0;
8343 
8344 	wlan_serialize_enter();
8345 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8346 	    (sc->sc_flags & BWN_FLAG_INVALID)) {
8347 		wlan_serialize_exit();
8348 		return;
8349 	}
8350 
8351 	for (i = 0; i < N(mac->mac_reason); i++)
8352 		merged |= mac->mac_reason[i];
8353 
8354 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8355 		device_printf(sc->sc_dev, "MAC trans error\n");
8356 
8357 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8358 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8359 		mac->mac_phy.txerrors--;
8360 		if (mac->mac_phy.txerrors == 0) {
8361 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8362 			bwn_restart(mac, "PHY TX errors");
8363 		}
8364 	}
8365 
8366 	if (merged & BWN_DMAINTR_FATALMASK) {
8367 		device_printf(sc->sc_dev,
8368 		    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8369 		    mac->mac_reason[0], mac->mac_reason[1],
8370 		    mac->mac_reason[2], mac->mac_reason[3],
8371 		    mac->mac_reason[4], mac->mac_reason[5]);
8372 		bwn_restart(mac, "DMA error");
8373 		wlan_serialize_exit();
8374 		return;
8375 	}
8376 
8377 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8378 		bwn_intr_ucode_debug(mac);
8379 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8380 		bwn_intr_tbtt_indication(mac);
8381 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8382 		bwn_intr_atim_end(mac);
8383 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
8384 		bwn_intr_beacon(mac);
8385 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
8386 		bwn_intr_pmq(mac);
8387 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8388 		bwn_intr_noise(mac);
8389 
8390 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8391 		if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) {
8392 			device_printf(sc->sc_dev, "RX descriptor overflow\n");
8393 			bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx);
8394 		}
8395 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8396 			bwn_dma_rx(mac->mac_method.dma.rx);
8397 			rx = 1;
8398 		}
8399 	} else
8400 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8401 
8402 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8403 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8404 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8405 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8406 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8407 
8408 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8409 		bwn_intr_txeof(mac);
8410 		tx = 1;
8411 	}
8412 
8413 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8414 
8415 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8416 		int evt = BWN_LED_EVENT_NONE;
8417 
8418 		if (tx && rx) {
8419 			if (sc->sc_rx_rate > sc->sc_tx_rate)
8420 				evt = BWN_LED_EVENT_RX;
8421 			else
8422 				evt = BWN_LED_EVENT_TX;
8423 		} else if (tx) {
8424 			evt = BWN_LED_EVENT_TX;
8425 		} else if (rx) {
8426 			evt = BWN_LED_EVENT_RX;
8427 		} else if (rx == 0) {
8428 			evt = BWN_LED_EVENT_POLL;
8429 		}
8430 
8431 		if (evt != BWN_LED_EVENT_NONE)
8432 			bwn_led_event(mac, evt);
8433        }
8434 
8435 	if (!ifq_is_oactive(&ifp->if_snd)) {
8436 		if (!ifq_is_empty(&ifp->if_snd))
8437 			bwn_start_locked(ifp);
8438 	}
8439 
8440 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8441 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8442 
8443 	wlan_serialize_exit();
8444 }
8445 
8446 static void
8447 bwn_restart(struct bwn_mac *mac, const char *msg)
8448 {
8449 	struct bwn_softc *sc = mac->mac_sc;
8450 	struct ifnet *ifp = sc->sc_ifp;
8451 	struct ieee80211com *ic = ifp->if_l2com;
8452 
8453 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
8454 		return;
8455 
8456 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8457 	ieee80211_runtask(ic, &mac->mac_hwreset);
8458 }
8459 
8460 static void
8461 bwn_intr_ucode_debug(struct bwn_mac *mac)
8462 {
8463 	struct bwn_softc *sc = mac->mac_sc;
8464 	uint16_t reason;
8465 
8466 	if (mac->mac_fw.opensource == 0)
8467 		return;
8468 
8469 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8470 	switch (reason) {
8471 	case BWN_DEBUGINTR_PANIC:
8472 		bwn_handle_fwpanic(mac);
8473 		break;
8474 	case BWN_DEBUGINTR_DUMP_SHM:
8475 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8476 		break;
8477 	case BWN_DEBUGINTR_DUMP_REGS:
8478 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8479 		break;
8480 	case BWN_DEBUGINTR_MARKER:
8481 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8482 		break;
8483 	default:
8484 		device_printf(sc->sc_dev,
8485 		    "ucode debug unknown reason: %#x\n", reason);
8486 	}
8487 
8488 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8489 	    BWN_DEBUGINTR_ACK);
8490 }
8491 
8492 static void
8493 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8494 {
8495 	struct bwn_softc *sc = mac->mac_sc;
8496 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8497 
8498 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8499 		bwn_psctl(mac, 0);
8500 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8501 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8502 }
8503 
8504 static void
8505 bwn_intr_atim_end(struct bwn_mac *mac)
8506 {
8507 
8508 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8509 		BWN_WRITE_4(mac, BWN_MACCMD,
8510 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8511 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8512 	}
8513 }
8514 
8515 static void
8516 bwn_intr_beacon(struct bwn_mac *mac)
8517 {
8518 	struct bwn_softc *sc = mac->mac_sc;
8519 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8520 	uint32_t cmd, beacon0, beacon1;
8521 
8522 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8523 	    ic->ic_opmode == IEEE80211_M_MBSS)
8524 		return;
8525 
8526 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8527 
8528 	cmd = BWN_READ_4(mac, BWN_MACCMD);
8529 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8530 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8531 
8532 	if (beacon0 && beacon1) {
8533 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8534 		mac->mac_intr_mask |= BWN_INTR_BEACON;
8535 		return;
8536 	}
8537 
8538 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8539 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8540 		bwn_load_beacon0(mac);
8541 		bwn_load_beacon1(mac);
8542 		cmd = BWN_READ_4(mac, BWN_MACCMD);
8543 		cmd |= BWN_MACCMD_BEACON0_VALID;
8544 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8545 	} else {
8546 		if (!beacon0) {
8547 			bwn_load_beacon0(mac);
8548 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8549 			cmd |= BWN_MACCMD_BEACON0_VALID;
8550 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8551 		} else if (!beacon1) {
8552 			bwn_load_beacon1(mac);
8553 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8554 			cmd |= BWN_MACCMD_BEACON1_VALID;
8555 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8556 		}
8557 	}
8558 }
8559 
8560 static void
8561 bwn_intr_pmq(struct bwn_mac *mac)
8562 {
8563 	uint32_t tmp;
8564 
8565 	while (1) {
8566 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8567 		if (!(tmp & 0x00000008))
8568 			break;
8569 	}
8570 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8571 }
8572 
8573 static void
8574 bwn_intr_noise(struct bwn_mac *mac)
8575 {
8576 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8577 	uint16_t tmp;
8578 	uint8_t noise[4];
8579 	uint8_t i, j;
8580 	int32_t average;
8581 
8582 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
8583 		return;
8584 
8585 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8586 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8587 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8588 	    noise[3] == 0x7f)
8589 		goto new;
8590 
8591 	KASSERT(mac->mac_noise.noi_nsamples < 8,
8592 	    ("%s:%d: fail", __func__, __LINE__));
8593 	i = mac->mac_noise.noi_nsamples;
8594 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8595 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8596 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8597 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8598 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8599 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8600 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8601 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8602 	mac->mac_noise.noi_nsamples++;
8603 	if (mac->mac_noise.noi_nsamples == 8) {
8604 		average = 0;
8605 		for (i = 0; i < 8; i++) {
8606 			for (j = 0; j < 4; j++)
8607 				average += mac->mac_noise.noi_samples[i][j];
8608 		}
8609 		average = (((average / 32) * 125) + 64) / 128;
8610 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8611 		if (tmp >= 8)
8612 			average += 2;
8613 		else
8614 			average -= 25;
8615 		average -= (tmp == 8) ? 72 : 48;
8616 
8617 		mac->mac_stats.link_noise = average;
8618 		mac->mac_noise.noi_running = 0;
8619 		return;
8620 	}
8621 new:
8622 	bwn_noise_gensample(mac);
8623 }
8624 
8625 static int
8626 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8627 {
8628 	struct bwn_mac *mac = prq->prq_mac;
8629 	struct bwn_softc *sc = mac->mac_sc;
8630 	unsigned int i;
8631 
8632 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8633 		return (0);
8634 
8635 	for (i = 0; i < 5000; i++) {
8636 		if (bwn_pio_rxeof(prq) == 0)
8637 			break;
8638 	}
8639 	if (i >= 5000)
8640 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8641 	return ((i > 0) ? 1 : 0);
8642 }
8643 
8644 static void
8645 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr)
8646 {
8647 	int curslot, prevslot;
8648 
8649 	curslot = dr->get_curslot(dr);
8650 	if (curslot == 0)
8651 		prevslot = dr->dr_numslots - 1;
8652 	else
8653 		prevslot = curslot - 1;
8654 	dr->set_curslot(dr, prevslot);
8655 }
8656 
8657 static void
8658 bwn_dma_rx(struct bwn_dma_ring *dr)
8659 {
8660 	int slot, curslot;
8661 
8662 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8663 	curslot = dr->get_curslot(dr);
8664 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8665 	    ("%s:%d: fail", __func__, __LINE__));
8666 
8667 	slot = dr->dr_curslot;
8668 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8669 		bwn_dma_rxeof(dr, &slot);
8670 
8671 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8672 	    BUS_DMASYNC_PREWRITE);
8673 
8674 	dr->set_curslot(dr, slot);
8675 	dr->dr_curslot = slot;
8676 }
8677 
8678 static void
8679 bwn_intr_txeof(struct bwn_mac *mac)
8680 {
8681 	struct bwn_txstatus stat;
8682 	uint32_t stat0, stat1;
8683 	uint16_t tmp;
8684 
8685 	while (1) {
8686 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8687 		if (!(stat0 & 0x00000001))
8688 			break;
8689 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8690 
8691 		stat.cookie = (stat0 >> 16);
8692 		stat.seq = (stat1 & 0x0000ffff);
8693 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8694 		tmp = (stat0 & 0x0000ffff);
8695 		stat.framecnt = ((tmp & 0xf000) >> 12);
8696 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
8697 		stat.sreason = ((tmp & 0x001c) >> 2);
8698 		stat.pm = (tmp & 0x0080) ? 1 : 0;
8699 		stat.im = (tmp & 0x0040) ? 1 : 0;
8700 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8701 		stat.ack = (tmp & 0x0002) ? 1 : 0;
8702 
8703 		bwn_handle_txeof(mac, &stat);
8704 	}
8705 }
8706 
8707 static void
8708 bwn_hwreset(void *arg, int npending)
8709 {
8710 	struct bwn_mac *mac = arg;
8711 	struct bwn_softc *sc = mac->mac_sc;
8712 	int error = 0;
8713 	int prev_status;
8714 
8715 	wlan_serialize_enter();
8716 
8717 	prev_status = mac->mac_status;
8718 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8719 		bwn_core_stop(mac);
8720 	if (prev_status >= BWN_MAC_STATUS_INITED)
8721 		bwn_core_exit(mac);
8722 
8723 	if (prev_status >= BWN_MAC_STATUS_INITED) {
8724 		error = bwn_core_init(mac);
8725 		if (error)
8726 			goto out;
8727 	}
8728 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8729 		bwn_core_start(mac);
8730 out:
8731 	if (error) {
8732 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8733 		sc->sc_curmac = NULL;
8734 	}
8735 	wlan_serialize_exit();
8736 }
8737 
8738 static void
8739 bwn_handle_fwpanic(struct bwn_mac *mac)
8740 {
8741 	struct bwn_softc *sc = mac->mac_sc;
8742 	uint16_t reason;
8743 
8744 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8745 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8746 
8747 	if (reason == BWN_FWPANIC_RESTART)
8748 		bwn_restart(mac, "ucode panic");
8749 }
8750 
8751 static void
8752 bwn_load_beacon0(struct bwn_mac *mac)
8753 {
8754 
8755 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8756 }
8757 
8758 static void
8759 bwn_load_beacon1(struct bwn_mac *mac)
8760 {
8761 
8762 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8763 }
8764 
8765 static uint32_t
8766 bwn_jssi_read(struct bwn_mac *mac)
8767 {
8768 	uint32_t val = 0;
8769 
8770 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8771 	val <<= 16;
8772 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8773 
8774 	return (val);
8775 }
8776 
8777 static void
8778 bwn_noise_gensample(struct bwn_mac *mac)
8779 {
8780 	uint32_t jssi = 0x7f7f7f7f;
8781 
8782 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8783 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8784 	BWN_WRITE_4(mac, BWN_MACCMD,
8785 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8786 }
8787 
8788 static int
8789 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8790 {
8791 	return (dr->dr_numslots - dr->dr_usedslot);
8792 }
8793 
8794 static int
8795 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8796 {
8797 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8798 	    ("%s:%d: fail", __func__, __LINE__));
8799 	if (slot == dr->dr_numslots - 1)
8800 		return (0);
8801 	return (slot + 1);
8802 }
8803 
8804 static void
8805 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8806 {
8807 	struct bwn_mac *mac = dr->dr_mac;
8808 	struct bwn_softc *sc = mac->mac_sc;
8809 	struct bwn_dma *dma = &mac->mac_method.dma;
8810 	struct bwn_dmadesc_generic *desc;
8811 	struct bwn_dmadesc_meta *meta;
8812 	struct bwn_rxhdr4 *rxhdr;
8813 	struct ifnet *ifp = sc->sc_ifp;
8814 	struct mbuf *m;
8815 	uint32_t macstat;
8816 	int32_t tmp;
8817 	int cnt = 0;
8818 	uint16_t len;
8819 
8820 	dr->getdesc(dr, *slot, &desc, &meta);
8821 
8822 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8823 	m = meta->mt_m;
8824 
8825 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8826 		ifp->if_ierrors++;
8827 		return;
8828 	}
8829 
8830 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
8831 	len = le16toh(rxhdr->frame_len);
8832 	if (len <= 0) {
8833 		ifp->if_ierrors++;
8834 		return;
8835 	}
8836 	if (bwn_dma_check_redzone(dr, m)) {
8837 		device_printf(sc->sc_dev, "redzone error.\n");
8838 		bwn_dma_set_redzone(dr, m);
8839 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8840 		    BUS_DMASYNC_PREWRITE);
8841 		return;
8842 	}
8843 	if (len > dr->dr_rx_bufsize) {
8844 		tmp = len;
8845 		while (1) {
8846 			dr->getdesc(dr, *slot, &desc, &meta);
8847 			bwn_dma_set_redzone(dr, meta->mt_m);
8848 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8849 			    BUS_DMASYNC_PREWRITE);
8850 			*slot = bwn_dma_nextslot(dr, *slot);
8851 			cnt++;
8852 			tmp -= dr->dr_rx_bufsize;
8853 			if (tmp <= 0)
8854 				break;
8855 		}
8856 		device_printf(sc->sc_dev, "too small buffer "
8857 		       "(len %u buffer %u dropped %d)\n",
8858 		       len, dr->dr_rx_bufsize, cnt);
8859 		return;
8860 	}
8861 	macstat = le32toh(rxhdr->mac_status);
8862 	if (macstat & BWN_RX_MAC_FCSERR) {
8863 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8864 			device_printf(sc->sc_dev, "RX drop\n");
8865 			return;
8866 		}
8867 	}
8868 
8869 	m->m_pkthdr.rcvif = ifp;
8870 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8871 	m_adj(m, dr->dr_frameoffset);
8872 
8873 	bwn_rxeof(dr->dr_mac, m, rxhdr);
8874 }
8875 
8876 static void
8877 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8878 {
8879 	struct bwn_dma_ring *dr;
8880 	struct bwn_dmadesc_generic *desc;
8881 	struct bwn_dmadesc_meta *meta;
8882 	struct bwn_pio_txqueue *tq;
8883 	struct bwn_pio_txpkt *tp = NULL;
8884 	struct bwn_softc *sc = mac->mac_sc;
8885 	struct bwn_stats *stats = &mac->mac_stats;
8886 	struct ieee80211_node *ni;
8887 	struct ieee80211vap *vap;
8888 	int retrycnt = 0, slot;
8889 
8890 	if (status->im)
8891 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8892 	if (status->ampdu)
8893 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8894 	if (status->rtscnt) {
8895 		if (status->rtscnt == 0xf)
8896 			stats->rtsfail++;
8897 		else
8898 			stats->rts++;
8899 	}
8900 
8901 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8902 		if (status->ack) {
8903 			dr = bwn_dma_parse_cookie(mac, status,
8904 			    status->cookie, &slot);
8905 			if (dr == NULL) {
8906 				device_printf(sc->sc_dev,
8907 				    "failed to parse cookie\n");
8908 				return;
8909 			}
8910 			while (1) {
8911 				dr->getdesc(dr, slot, &desc, &meta);
8912 				if (meta->mt_islast) {
8913 					ni = meta->mt_ni;
8914 					vap = ni->ni_vap;
8915 					ieee80211_ratectl_tx_complete(vap, ni,
8916 					    status->ack ?
8917 					      IEEE80211_RATECTL_TX_SUCCESS :
8918 					      IEEE80211_RATECTL_TX_FAILURE,
8919 					    &retrycnt, 0);
8920 					break;
8921 				}
8922 				slot = bwn_dma_nextslot(dr, slot);
8923 			}
8924 		}
8925 		bwn_dma_handle_txeof(mac, status);
8926 	} else {
8927 		if (status->ack) {
8928 			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8929 			if (tq == NULL) {
8930 				device_printf(sc->sc_dev,
8931 				    "failed to parse cookie\n");
8932 				return;
8933 			}
8934 			ni = tp->tp_ni;
8935 			vap = ni->ni_vap;
8936 			ieee80211_ratectl_tx_complete(vap, ni,
8937 			    status->ack ?
8938 			      IEEE80211_RATECTL_TX_SUCCESS :
8939 			      IEEE80211_RATECTL_TX_FAILURE,
8940 			    &retrycnt, 0);
8941 		}
8942 		bwn_pio_handle_txeof(mac, status);
8943 	}
8944 
8945 	bwn_phy_txpower_check(mac, 0);
8946 }
8947 
8948 static uint8_t
8949 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8950 {
8951 	struct bwn_mac *mac = prq->prq_mac;
8952 	struct bwn_softc *sc = mac->mac_sc;
8953 	struct bwn_rxhdr4 rxhdr;
8954 	struct ifnet *ifp = sc->sc_ifp;
8955 	struct mbuf *m;
8956 	uint32_t ctl32, macstat, v32;
8957 	unsigned int i, padding;
8958 	uint16_t ctl16, len, totlen, v16;
8959 	unsigned char *mp;
8960 	char *data;
8961 
8962 	memset(&rxhdr, 0, sizeof(rxhdr));
8963 
8964 	if (prq->prq_rev >= 8) {
8965 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8966 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8967 			return (0);
8968 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8969 		    BWN_PIO8_RXCTL_FRAMEREADY);
8970 		for (i = 0; i < 10; i++) {
8971 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8972 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8973 				goto ready;
8974 			DELAY(10);
8975 		}
8976 	} else {
8977 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8978 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8979 			return (0);
8980 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8981 		    BWN_PIO_RXCTL_FRAMEREADY);
8982 		for (i = 0; i < 10; i++) {
8983 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8984 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8985 				goto ready;
8986 			DELAY(10);
8987 		}
8988 	}
8989 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8990 	return (1);
8991 ready:
8992 	if (prq->prq_rev >= 8)
8993 		siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8994 		    prq->prq_base + BWN_PIO8_RXDATA);
8995 	else
8996 		siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8997 		    prq->prq_base + BWN_PIO_RXDATA);
8998 	len = le16toh(rxhdr.frame_len);
8999 	if (len > 0x700) {
9000 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9001 		goto error;
9002 	}
9003 	if (len == 0) {
9004 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9005 		goto error;
9006 	}
9007 
9008 	macstat = le32toh(rxhdr.mac_status);
9009 	if (macstat & BWN_RX_MAC_FCSERR) {
9010 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9011 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
9012 			goto error;
9013 		}
9014 	}
9015 
9016 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9017 	totlen = len + padding;
9018 	KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9019 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9020 	if (m == NULL) {
9021 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
9022 		goto error;
9023 	}
9024 	mp = mtod(m, unsigned char *);
9025 	if (prq->prq_rev >= 8) {
9026 		siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9027 		    prq->prq_base + BWN_PIO8_RXDATA);
9028 		if (totlen & 3) {
9029 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9030 			data = &(mp[totlen - 1]);
9031 			switch (totlen & 3) {
9032 			case 3:
9033 				*data = (v32 >> 16);
9034 				data--;
9035 			case 2:
9036 				*data = (v32 >> 8);
9037 				data--;
9038 			case 1:
9039 				*data = v32;
9040 			}
9041 		}
9042 	} else {
9043 		siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9044 		    prq->prq_base + BWN_PIO_RXDATA);
9045 		if (totlen & 1) {
9046 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9047 			mp[totlen - 1] = v16;
9048 		}
9049 	}
9050 
9051 	m->m_pkthdr.rcvif = ifp;
9052 	m->m_len = m->m_pkthdr.len = totlen;
9053 
9054 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
9055 
9056 	return (1);
9057 error:
9058 	if (prq->prq_rev >= 8)
9059 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9060 		    BWN_PIO8_RXCTL_DATAREADY);
9061 	else
9062 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9063 	return (1);
9064 }
9065 
9066 static int
9067 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9068     struct bwn_dmadesc_meta *meta, int init)
9069 {
9070 	struct bwn_mac *mac = dr->dr_mac;
9071 	struct bwn_dma *dma = &mac->mac_method.dma;
9072 	struct bwn_rxhdr4 *hdr;
9073 	bus_dmamap_t map;
9074 	bus_addr_t paddr;
9075 	struct mbuf *m;
9076 	int error;
9077 
9078 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9079 	if (m == NULL) {
9080 		error = ENOBUFS;
9081 
9082 		/*
9083 		 * If the NIC is up and running, we need to:
9084 		 * - Clear RX buffer's header.
9085 		 * - Restore RX descriptor settings.
9086 		 */
9087 		if (init)
9088 			return (error);
9089 		else
9090 			goto back;
9091 	}
9092 	m->m_len = m->m_pkthdr.len = MCLBYTES;
9093 
9094 	bwn_dma_set_redzone(dr, m);
9095 
9096 	/*
9097 	 * Try to load RX buf into temporary DMA map
9098 	 */
9099 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9100 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9101 	if (error) {
9102 		m_freem(m);
9103 
9104 		/*
9105 		 * See the comment above
9106 		 */
9107 		if (init)
9108 			return (error);
9109 		else
9110 			goto back;
9111 	}
9112 
9113 	if (!init)
9114 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9115 	meta->mt_m = m;
9116 	meta->mt_paddr = paddr;
9117 
9118 	/*
9119 	 * Swap RX buf's DMA map with the loaded temporary one
9120 	 */
9121 	map = meta->mt_dmap;
9122 	meta->mt_dmap = dr->dr_spare_dmap;
9123 	dr->dr_spare_dmap = map;
9124 
9125 back:
9126 	/*
9127 	 * Clear RX buf header
9128 	 */
9129 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9130 	bzero(hdr, sizeof(*hdr));
9131 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9132 	    BUS_DMASYNC_PREWRITE);
9133 
9134 	/*
9135 	 * Setup RX buf descriptor
9136 	 */
9137 	dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9138 	    sizeof(*hdr), 0, 0, 0);
9139 	return (error);
9140 }
9141 
9142 static void
9143 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9144 		 bus_size_t mapsz __unused, int error)
9145 {
9146 
9147 	if (!error) {
9148 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9149 		*((bus_addr_t *)arg) = seg->ds_addr;
9150 	}
9151 }
9152 
9153 static int
9154 bwn_hwrate2ieeerate(int rate)
9155 {
9156 
9157 	switch (rate) {
9158 	case BWN_CCK_RATE_1MB:
9159 		return (2);
9160 	case BWN_CCK_RATE_2MB:
9161 		return (4);
9162 	case BWN_CCK_RATE_5MB:
9163 		return (11);
9164 	case BWN_CCK_RATE_11MB:
9165 		return (22);
9166 	case BWN_OFDM_RATE_6MB:
9167 		return (12);
9168 	case BWN_OFDM_RATE_9MB:
9169 		return (18);
9170 	case BWN_OFDM_RATE_12MB:
9171 		return (24);
9172 	case BWN_OFDM_RATE_18MB:
9173 		return (36);
9174 	case BWN_OFDM_RATE_24MB:
9175 		return (48);
9176 	case BWN_OFDM_RATE_36MB:
9177 		return (72);
9178 	case BWN_OFDM_RATE_48MB:
9179 		return (96);
9180 	case BWN_OFDM_RATE_54MB:
9181 		return (108);
9182 	default:
9183 		kprintf("Ooops\n");
9184 		return (0);
9185 	}
9186 }
9187 
9188 static void
9189 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9190 {
9191 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9192 	struct bwn_plcp6 *plcp;
9193 	struct bwn_softc *sc = mac->mac_sc;
9194 	struct ieee80211_frame_min *wh;
9195 	struct ieee80211_node *ni;
9196 	struct ifnet *ifp = sc->sc_ifp;
9197 	struct ieee80211com *ic = ifp->if_l2com;
9198 	uint32_t macstat;
9199 	int padding, rate, rssi = 0, noise = 0, type;
9200 	uint16_t phytype, phystat0, phystat3, chanstat;
9201 	unsigned char *mp = mtod(m, unsigned char *);
9202 	static int rx_mac_dec_rpt = 0;
9203 
9204 	phystat0 = le16toh(rxhdr->phy_status0);
9205 	phystat3 = le16toh(rxhdr->phy_status3);
9206 	macstat = le32toh(rxhdr->mac_status);
9207 	chanstat = le16toh(rxhdr->channel);
9208 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9209 
9210 	if (macstat & BWN_RX_MAC_FCSERR)
9211 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9212 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9213 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9214 	if (macstat & BWN_RX_MAC_DECERR)
9215 		goto drop;
9216 
9217 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9218 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9219 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9220 		    m->m_pkthdr.len);
9221 		goto drop;
9222 	}
9223 	plcp = (struct bwn_plcp6 *)(mp + padding);
9224 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
9225 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9226 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9227 		    m->m_pkthdr.len);
9228 		goto drop;
9229 	}
9230 	wh = mtod(m, struct ieee80211_frame_min *);
9231 
9232 	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9233 		device_printf(sc->sc_dev,
9234 		    "RX decryption attempted (old %d keyidx %#x)\n",
9235 		    BWN_ISOLDFMT(mac),
9236 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9237 
9238 	/* XXX calculating RSSI & noise & antenna */
9239 
9240 	if (phystat0 & BWN_RX_PHYST0_OFDM)
9241 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
9242 		    phytype == BWN_PHYTYPE_A);
9243 	else
9244 		rate = bwn_plcp_get_cckrate(mac, plcp);
9245 	if (rate == -1) {
9246 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9247 			goto drop;
9248 	}
9249 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9250 
9251 	/* RX radio tap */
9252 	if (ieee80211_radiotap_active(ic))
9253 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9254 	m_adj(m, -IEEE80211_CRC_LEN);
9255 
9256 	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
9257 	noise = mac->mac_stats.link_noise;
9258 
9259 	ifp->if_ipackets++;
9260 
9261 	ni = ieee80211_find_rxnode(ic, wh);
9262 	if (ni != NULL) {
9263 		type = ieee80211_input(ni, m, rssi, noise);
9264 		ieee80211_free_node(ni);
9265 	} else
9266 		type = ieee80211_input_all(ic, m, rssi, noise);
9267 
9268 	return;
9269 drop:
9270 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9271 }
9272 
9273 static void
9274 bwn_dma_handle_txeof(struct bwn_mac *mac,
9275     const struct bwn_txstatus *status)
9276 {
9277 	struct bwn_dma *dma = &mac->mac_method.dma;
9278 	struct bwn_dma_ring *dr;
9279 	struct bwn_dmadesc_generic *desc;
9280 	struct bwn_dmadesc_meta *meta;
9281 	struct bwn_softc *sc = mac->mac_sc;
9282 	struct ieee80211_node *ni;
9283 	struct ifnet *ifp = sc->sc_ifp;
9284 	struct mbuf *m;
9285 	int slot;
9286 
9287 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9288 	if (dr == NULL) {
9289 		device_printf(sc->sc_dev, "failed to parse cookie\n");
9290 		return;
9291 	}
9292 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9293 
9294 	while (1) {
9295 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
9296 		    ("%s:%d: fail", __func__, __LINE__));
9297 		dr->getdesc(dr, slot, &desc, &meta);
9298 
9299 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
9300 			bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap,
9301 			    BUS_DMASYNC_POSTWRITE);
9302 		} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
9303 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9304 		}
9305 
9306 		if (meta->mt_islast) {
9307 			KASSERT(meta->mt_m != NULL,
9308 			    ("%s:%d: fail", __func__, __LINE__));
9309 
9310 			ni = meta->mt_ni;
9311 			m = meta->mt_m;
9312 			if (ni != NULL) {
9313 				/*
9314 				 * Do any tx complete callback. Note this must
9315 				 * be done before releasing the node reference.
9316 				 */
9317 				if (m->m_flags & M_TXCB)
9318 					ieee80211_process_callback(ni, m, 0);
9319 				ieee80211_free_node(ni);
9320 				meta->mt_ni = NULL;
9321 			}
9322 			m_freem(m);
9323 			meta->mt_m = NULL;
9324 		} else {
9325 			KASSERT(meta->mt_m == NULL,
9326 			    ("%s:%d: fail", __func__, __LINE__));
9327 		}
9328 
9329 		dr->dr_usedslot--;
9330 		if (meta->mt_islast) {
9331 			ifp->if_opackets++;
9332 			break;
9333 		}
9334 		slot = bwn_dma_nextslot(dr, slot);
9335 	}
9336 	sc->sc_watchdog_timer = 0;
9337 	if (dr->dr_stop) {
9338 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9339 		    ("%s:%d: fail", __func__, __LINE__));
9340 		ifq_clr_oactive(&ifp->if_snd);
9341 		dr->dr_stop = 0;
9342 	}
9343 }
9344 
9345 static void
9346 bwn_pio_handle_txeof(struct bwn_mac *mac,
9347     const struct bwn_txstatus *status)
9348 {
9349 	struct bwn_pio_txqueue *tq;
9350 	struct bwn_pio_txpkt *tp = NULL;
9351 	struct bwn_softc *sc = mac->mac_sc;
9352 	struct ifnet *ifp = sc->sc_ifp;
9353 
9354 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9355 	if (tq == NULL)
9356 		return;
9357 
9358 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9359 	tq->tq_free++;
9360 
9361 	if (tp->tp_ni != NULL) {
9362 		/*
9363 		 * Do any tx complete callback.  Note this must
9364 		 * be done before releasing the node reference.
9365 		 */
9366 		if (tp->tp_m->m_flags & M_TXCB)
9367 			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9368 		ieee80211_free_node(tp->tp_ni);
9369 		tp->tp_ni = NULL;
9370 	}
9371 	m_freem(tp->tp_m);
9372 	tp->tp_m = NULL;
9373 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9374 
9375 	ifp->if_opackets++;
9376 
9377 	sc->sc_watchdog_timer = 0;
9378 	if (tq->tq_stop) {
9379 		ifq_clr_oactive(&ifp->if_snd);
9380 		tq->tq_stop = 0;
9381 	}
9382 }
9383 
9384 static void
9385 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9386 {
9387 	struct bwn_softc *sc = mac->mac_sc;
9388 	struct bwn_phy *phy = &mac->mac_phy;
9389 	struct ifnet *ifp = sc->sc_ifp;
9390 	struct ieee80211com *ic = ifp->if_l2com;
9391 	unsigned long now;
9392 	int result;
9393 
9394 	BWN_GETTIME(now);
9395 
9396 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9397 		return;
9398 	phy->nexttime = now + 2 * 1000;
9399 
9400 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9401 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9402 		return;
9403 
9404 	if (phy->recalc_txpwr != NULL) {
9405 		result = phy->recalc_txpwr(mac,
9406 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9407 		if (result == BWN_TXPWR_RES_DONE)
9408 			return;
9409 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9410 		    ("%s: fail", __func__));
9411 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9412 
9413 		ieee80211_runtask(ic, &mac->mac_txpower);
9414 	}
9415 }
9416 
9417 static uint16_t
9418 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9419 {
9420 
9421 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9422 }
9423 
9424 static uint32_t
9425 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9426 {
9427 
9428 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9429 }
9430 
9431 static void
9432 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9433 {
9434 
9435 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9436 }
9437 
9438 static void
9439 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9440 {
9441 
9442 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9443 }
9444 
9445 static int
9446 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9447 {
9448 
9449 	switch (rate) {
9450 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9451 	case 12:
9452 		return (BWN_OFDM_RATE_6MB);
9453 	case 18:
9454 		return (BWN_OFDM_RATE_9MB);
9455 	case 24:
9456 		return (BWN_OFDM_RATE_12MB);
9457 	case 36:
9458 		return (BWN_OFDM_RATE_18MB);
9459 	case 48:
9460 		return (BWN_OFDM_RATE_24MB);
9461 	case 72:
9462 		return (BWN_OFDM_RATE_36MB);
9463 	case 96:
9464 		return (BWN_OFDM_RATE_48MB);
9465 	case 108:
9466 		return (BWN_OFDM_RATE_54MB);
9467 	/* CCK rates (NB: not IEEE std, device-specific) */
9468 	case 2:
9469 		return (BWN_CCK_RATE_1MB);
9470 	case 4:
9471 		return (BWN_CCK_RATE_2MB);
9472 	case 11:
9473 		return (BWN_CCK_RATE_5MB);
9474 	case 22:
9475 		return (BWN_CCK_RATE_11MB);
9476 	}
9477 
9478 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9479 	return (BWN_CCK_RATE_1MB);
9480 }
9481 
9482 static int
9483 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9484     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9485 {
9486 	const struct bwn_phy *phy = &mac->mac_phy;
9487 	struct bwn_softc *sc = mac->mac_sc;
9488 	struct ieee80211_frame *wh;
9489 	struct ieee80211_frame *protwh;
9490 	struct ieee80211_frame_cts *cts;
9491 	struct ieee80211_frame_rts *rts;
9492 	const struct ieee80211_txparam *tp;
9493 	struct ieee80211vap *vap = ni->ni_vap;
9494 	struct ifnet *ifp = sc->sc_ifp;
9495 	struct ieee80211com *ic = ifp->if_l2com;
9496 	struct mbuf *mprot;
9497 	unsigned int len;
9498 	uint32_t macctl = 0;
9499 	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9500 	uint16_t phyctl = 0;
9501 	uint8_t rate, rate_fb;
9502 
9503 	wh = mtod(m, struct ieee80211_frame *);
9504 	memset(txhdr, 0, sizeof(*txhdr));
9505 
9506 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9507 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9508 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9509 
9510 	/*
9511 	 * Find TX rate
9512 	 */
9513 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9514 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9515 		rate = rate_fb = tp->mgmtrate;
9516 	else if (ismcast)
9517 		rate = rate_fb = tp->mcastrate;
9518 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9519 		rate = rate_fb = tp->ucastrate;
9520 	else {
9521 		rix = ieee80211_ratectl_rate(ni, NULL, 0);
9522 		rate = ni->ni_txrate;
9523 
9524 		if (rix > 0)
9525 			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9526 			    IEEE80211_RATE_VAL;
9527 		else
9528 			rate_fb = rate;
9529 	}
9530 
9531 	sc->sc_tx_rate = rate;
9532 
9533 	rate = bwn_ieeerate2hwrate(sc, rate);
9534 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9535 
9536 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9537 	    bwn_plcp_getcck(rate);
9538 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9539 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9540 
9541 	if ((rate_fb == rate) ||
9542 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9543 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
9544 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9545 	else
9546 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9547 		    m->m_pkthdr.len, rate, isshort);
9548 
9549 	/* XXX TX encryption */
9550 	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9551 	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9552 	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9553 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9554 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9555 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9556 
9557 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9558 	    BWN_TX_EFT_FB_CCK;
9559 	txhdr->chan = phy->chan;
9560 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9561 	    BWN_TX_PHY_ENC_CCK;
9562 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9563 	     rate == BWN_CCK_RATE_11MB))
9564 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
9565 
9566 	/* XXX TX antenna selection */
9567 
9568 	switch (bwn_antenna_sanitize(mac, 0)) {
9569 	case 0:
9570 		phyctl |= BWN_TX_PHY_ANT01AUTO;
9571 		break;
9572 	case 1:
9573 		phyctl |= BWN_TX_PHY_ANT0;
9574 		break;
9575 	case 2:
9576 		phyctl |= BWN_TX_PHY_ANT1;
9577 		break;
9578 	case 3:
9579 		phyctl |= BWN_TX_PHY_ANT2;
9580 		break;
9581 	case 4:
9582 		phyctl |= BWN_TX_PHY_ANT3;
9583 		break;
9584 	default:
9585 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9586 	}
9587 
9588 	if (!ismcast)
9589 		macctl |= BWN_TX_MAC_ACK;
9590 
9591 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9592 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9593 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9594 		macctl |= BWN_TX_MAC_LONGFRAME;
9595 
9596 	if (ic->ic_flags & IEEE80211_F_USEPROT) {
9597 		/* XXX RTS rate is always 1MB??? */
9598 		rts_rate = BWN_CCK_RATE_1MB;
9599 		rts_rate_fb = bwn_get_fbrate(rts_rate);
9600 
9601 		protdur = ieee80211_compute_duration(ic->ic_rt,
9602 		    m->m_pkthdr.len, rate, isshort) +
9603 		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9604 
9605 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9606 			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9607 			    (txhdr->body.old.rts_frame) :
9608 			    (txhdr->body.new.rts_frame));
9609 			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9610 			    protdur);
9611 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9612 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9613 			    mprot->m_pkthdr.len);
9614 			m_freem(mprot);
9615 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9616 			len = sizeof(struct ieee80211_frame_cts);
9617 		} else {
9618 			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9619 			    (txhdr->body.old.rts_frame) :
9620 			    (txhdr->body.new.rts_frame));
9621 			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9622 			    isshort);
9623 			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9624 			    wh->i_addr2, protdur);
9625 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9626 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9627 			    mprot->m_pkthdr.len);
9628 			m_freem(mprot);
9629 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
9630 			len = sizeof(struct ieee80211_frame_rts);
9631 		}
9632 		len += IEEE80211_CRC_LEN;
9633 		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9634 		    &txhdr->body.old.rts_plcp :
9635 		    &txhdr->body.new.rts_plcp), len, rts_rate);
9636 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9637 		    rts_rate_fb);
9638 
9639 		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9640 		    (&txhdr->body.old.rts_frame) :
9641 		    (&txhdr->body.new.rts_frame));
9642 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9643 
9644 		if (BWN_ISOFDMRATE(rts_rate)) {
9645 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9646 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9647 		} else {
9648 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9649 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9650 		}
9651 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9652 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9653 	}
9654 
9655 	if (BWN_ISOLDFMT(mac))
9656 		txhdr->body.old.cookie = htole16(cookie);
9657 	else
9658 		txhdr->body.new.cookie = htole16(cookie);
9659 
9660 	txhdr->macctl = htole32(macctl);
9661 	txhdr->phyctl = htole16(phyctl);
9662 
9663 	/*
9664 	 * TX radio tap
9665 	 */
9666 	if (ieee80211_radiotap_active_vap(vap)) {
9667 		sc->sc_tx_th.wt_flags = 0;
9668 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9669 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9670 		if (isshort &&
9671 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9672 		     rate == BWN_CCK_RATE_11MB))
9673 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9674 		sc->sc_tx_th.wt_rate = rate;
9675 
9676 		ieee80211_radiotap_tx(vap, m);
9677 	}
9678 
9679 	return (0);
9680 }
9681 
9682 static void
9683 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9684     const uint8_t rate)
9685 {
9686 	uint32_t d, plen;
9687 	uint8_t *raw = plcp->o.raw;
9688 
9689 	if (BWN_ISOFDMRATE(rate)) {
9690 		d = bwn_plcp_getofdm(rate);
9691 		KASSERT(!(octets & 0xf000),
9692 		    ("%s:%d: fail", __func__, __LINE__));
9693 		d |= (octets << 5);
9694 		plcp->o.data = htole32(d);
9695 	} else {
9696 		plen = octets * 16 / rate;
9697 		if ((octets * 16 % rate) > 0) {
9698 			plen++;
9699 			if ((rate == BWN_CCK_RATE_11MB)
9700 			    && ((octets * 8 % 11) < 4)) {
9701 				raw[1] = 0x84;
9702 			} else
9703 				raw[1] = 0x04;
9704 		} else
9705 			raw[1] = 0x04;
9706 		plcp->o.data |= htole32(plen << 16);
9707 		raw[0] = bwn_plcp_getcck(rate);
9708 	}
9709 }
9710 
9711 static uint8_t
9712 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9713 {
9714 	struct bwn_softc *sc = mac->mac_sc;
9715 	uint8_t mask;
9716 
9717 	if (n == 0)
9718 		return (0);
9719 	if (mac->mac_phy.gmode)
9720 		mask = siba_sprom_get_ant_bg(sc->sc_dev);
9721 	else
9722 		mask = siba_sprom_get_ant_a(sc->sc_dev);
9723 	if (!(mask & (1 << (n - 1))))
9724 		return (0);
9725 	return (n);
9726 }
9727 
9728 static uint8_t
9729 bwn_get_fbrate(uint8_t bitrate)
9730 {
9731 	switch (bitrate) {
9732 	case BWN_CCK_RATE_1MB:
9733 		return (BWN_CCK_RATE_1MB);
9734 	case BWN_CCK_RATE_2MB:
9735 		return (BWN_CCK_RATE_1MB);
9736 	case BWN_CCK_RATE_5MB:
9737 		return (BWN_CCK_RATE_2MB);
9738 	case BWN_CCK_RATE_11MB:
9739 		return (BWN_CCK_RATE_5MB);
9740 	case BWN_OFDM_RATE_6MB:
9741 		return (BWN_CCK_RATE_5MB);
9742 	case BWN_OFDM_RATE_9MB:
9743 		return (BWN_OFDM_RATE_6MB);
9744 	case BWN_OFDM_RATE_12MB:
9745 		return (BWN_OFDM_RATE_9MB);
9746 	case BWN_OFDM_RATE_18MB:
9747 		return (BWN_OFDM_RATE_12MB);
9748 	case BWN_OFDM_RATE_24MB:
9749 		return (BWN_OFDM_RATE_18MB);
9750 	case BWN_OFDM_RATE_36MB:
9751 		return (BWN_OFDM_RATE_24MB);
9752 	case BWN_OFDM_RATE_48MB:
9753 		return (BWN_OFDM_RATE_36MB);
9754 	case BWN_OFDM_RATE_54MB:
9755 		return (BWN_OFDM_RATE_48MB);
9756 	}
9757 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9758 	return (0);
9759 }
9760 
9761 static uint32_t
9762 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9763     uint32_t ctl, const void *_data, int len)
9764 {
9765 	struct bwn_softc *sc = mac->mac_sc;
9766 	uint32_t value = 0;
9767 	const uint8_t *data = _data;
9768 
9769 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9770 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9771 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9772 
9773 	siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9774 	    tq->tq_base + BWN_PIO8_TXDATA);
9775 	if (len & 3) {
9776 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9777 		    BWN_PIO8_TXCTL_24_31);
9778 		data = &(data[len - 1]);
9779 		switch (len & 3) {
9780 		case 3:
9781 			ctl |= BWN_PIO8_TXCTL_16_23;
9782 			value |= (uint32_t)(*data) << 16;
9783 			data--;
9784 		case 2:
9785 			ctl |= BWN_PIO8_TXCTL_8_15;
9786 			value |= (uint32_t)(*data) << 8;
9787 			data--;
9788 		case 1:
9789 			value |= (uint32_t)(*data);
9790 		}
9791 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9792 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9793 	}
9794 
9795 	return (ctl);
9796 }
9797 
9798 static void
9799 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9800     uint16_t offset, uint32_t value)
9801 {
9802 
9803 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
9804 }
9805 
9806 static uint16_t
9807 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9808     uint16_t ctl, const void *_data, int len)
9809 {
9810 	struct bwn_softc *sc = mac->mac_sc;
9811 	const uint8_t *data = _data;
9812 
9813 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9814 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9815 
9816 	siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9817 	    tq->tq_base + BWN_PIO_TXDATA);
9818 	if (len & 1) {
9819 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9820 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9821 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9822 	}
9823 
9824 	return (ctl);
9825 }
9826 
9827 static uint16_t
9828 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9829     uint16_t ctl, struct mbuf *m0)
9830 {
9831 	int i, j = 0;
9832 	uint16_t data = 0;
9833 	const uint8_t *buf;
9834 	struct mbuf *m = m0;
9835 
9836 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9837 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9838 
9839 	for (; m != NULL; m = m->m_next) {
9840 		buf = mtod(m, const uint8_t *);
9841 		for (i = 0; i < m->m_len; i++) {
9842 			if (!((j++) % 2))
9843 				data |= buf[i];
9844 			else {
9845 				data |= (buf[i] << 8);
9846 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9847 				data = 0;
9848 			}
9849 		}
9850 	}
9851 	if (m0->m_pkthdr.len % 2) {
9852 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9853 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9854 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9855 	}
9856 
9857 	return (ctl);
9858 }
9859 
9860 static void
9861 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9862 {
9863 
9864 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
9865 		return;
9866 	BWN_WRITE_2(mac, 0x684, 510 + time);
9867 
9868 	/*
9869 	 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a
9870 	 *              a severe performance penalty (especially when sending).
9871 	 */
9872 #if 0
9873 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9874 #endif
9875 }
9876 
9877 static struct bwn_dma_ring *
9878 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9879 {
9880 
9881 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9882 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9883 
9884 	switch (prio) {
9885 	case 3:
9886 		return (mac->mac_method.dma.wme[WME_AC_VO]);
9887 	case 2:
9888 		return (mac->mac_method.dma.wme[WME_AC_VI]);
9889 	case 0:
9890 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9891 	case 1:
9892 		return (mac->mac_method.dma.wme[WME_AC_BK]);
9893 	}
9894 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9895 	return (NULL);
9896 }
9897 
9898 static int
9899 bwn_dma_getslot(struct bwn_dma_ring *dr)
9900 {
9901 	int slot;
9902 
9903 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9904 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9905 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9906 
9907 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9908 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9909 	dr->dr_curslot = slot;
9910 	dr->dr_usedslot++;
9911 
9912 	return (slot);
9913 }
9914 
9915 static int
9916 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9917 {
9918 	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9919 	unsigned int a, b, c, d;
9920 	unsigned int avg;
9921 	uint32_t tmp;
9922 
9923 	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9924 	a = tmp & 0xff;
9925 	b = (tmp >> 8) & 0xff;
9926 	c = (tmp >> 16) & 0xff;
9927 	d = (tmp >> 24) & 0xff;
9928 	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9929 	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9930 		return (ENOENT);
9931 	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9932 	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9933 	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9934 
9935 	if (ofdm) {
9936 		a = (a + 32) & 0x3f;
9937 		b = (b + 32) & 0x3f;
9938 		c = (c + 32) & 0x3f;
9939 		d = (d + 32) & 0x3f;
9940 	}
9941 
9942 	avg = (a + b + c + d + 2) / 4;
9943 	if (ofdm) {
9944 		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9945 		    & BWN_HF_4DB_CCK_POWERBOOST)
9946 			avg = (avg >= 13) ? (avg - 13) : 0;
9947 	}
9948 	return (avg);
9949 }
9950 
9951 static void
9952 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9953 {
9954 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9955 	int rfatt = *rfattp;
9956 	int bbatt = *bbattp;
9957 
9958 	while (1) {
9959 		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9960 			break;
9961 		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9962 			break;
9963 		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9964 			break;
9965 		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9966 			break;
9967 		if (bbatt > lo->bbatt.max) {
9968 			bbatt -= 4;
9969 			rfatt += 1;
9970 			continue;
9971 		}
9972 		if (bbatt < lo->bbatt.min) {
9973 			bbatt += 4;
9974 			rfatt -= 1;
9975 			continue;
9976 		}
9977 		if (rfatt > lo->rfatt.max) {
9978 			rfatt -= 1;
9979 			bbatt += 4;
9980 			continue;
9981 		}
9982 		if (rfatt < lo->rfatt.min) {
9983 			rfatt += 1;
9984 			bbatt -= 4;
9985 			continue;
9986 		}
9987 		break;
9988 	}
9989 
9990 	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9991 	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9992 }
9993 
9994 static void
9995 bwn_phy_lock(struct bwn_mac *mac)
9996 {
9997 	struct bwn_softc *sc = mac->mac_sc;
9998 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
9999 
10000 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10001 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10002 
10003 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10004 		bwn_psctl(mac, BWN_PS_AWAKE);
10005 }
10006 
10007 static void
10008 bwn_phy_unlock(struct bwn_mac *mac)
10009 {
10010 	struct bwn_softc *sc = mac->mac_sc;
10011 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10012 
10013 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10014 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10015 
10016 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10017 		bwn_psctl(mac, 0);
10018 }
10019 
10020 static void
10021 bwn_rf_lock(struct bwn_mac *mac)
10022 {
10023 
10024 	BWN_WRITE_4(mac, BWN_MACCTL,
10025 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10026 	BWN_READ_4(mac, BWN_MACCTL);
10027 	DELAY(10);
10028 }
10029 
10030 static void
10031 bwn_rf_unlock(struct bwn_mac *mac)
10032 {
10033 
10034 	BWN_READ_2(mac, BWN_PHYVER);
10035 	BWN_WRITE_4(mac, BWN_MACCTL,
10036 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10037 }
10038 
10039 static struct bwn_pio_txqueue *
10040 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10041     struct bwn_pio_txpkt **pack)
10042 {
10043 	struct bwn_pio *pio = &mac->mac_method.pio;
10044 	struct bwn_pio_txqueue *tq = NULL;
10045 	unsigned int index;
10046 
10047 	switch (cookie & 0xf000) {
10048 	case 0x1000:
10049 		tq = &pio->wme[WME_AC_BK];
10050 		break;
10051 	case 0x2000:
10052 		tq = &pio->wme[WME_AC_BE];
10053 		break;
10054 	case 0x3000:
10055 		tq = &pio->wme[WME_AC_VI];
10056 		break;
10057 	case 0x4000:
10058 		tq = &pio->wme[WME_AC_VO];
10059 		break;
10060 	case 0x5000:
10061 		tq = &pio->mcast;
10062 		break;
10063 	}
10064 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10065 	if (tq == NULL)
10066 		return (NULL);
10067 	index = (cookie & 0x0fff);
10068 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10069 	if (index >= N(tq->tq_pkts))
10070 		return (NULL);
10071 	*pack = &tq->tq_pkts[index];
10072 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10073 	return (tq);
10074 }
10075 
10076 static void
10077 bwn_txpwr(void *arg, int npending)
10078 {
10079 	struct bwn_mac *mac = arg;
10080 
10081 	wlan_serialize_enter();
10082 	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10083 	    mac->mac_phy.set_txpwr != NULL)
10084 		mac->mac_phy.set_txpwr(mac);
10085 	wlan_serialize_exit();
10086 }
10087 
10088 static void
10089 bwn_task_15s(struct bwn_mac *mac)
10090 {
10091 	uint16_t reg;
10092 
10093 	if (mac->mac_fw.opensource) {
10094 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10095 		if (reg) {
10096 			bwn_restart(mac, "fw watchdog");
10097 			return;
10098 		}
10099 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10100 	}
10101 	if (mac->mac_phy.task_15s)
10102 		mac->mac_phy.task_15s(mac);
10103 
10104 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10105 }
10106 
10107 static void
10108 bwn_task_30s(struct bwn_mac *mac)
10109 {
10110 
10111 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10112 		return;
10113 	mac->mac_noise.noi_running = 1;
10114 	mac->mac_noise.noi_nsamples = 0;
10115 
10116 	bwn_noise_gensample(mac);
10117 }
10118 
10119 static void
10120 bwn_task_60s(struct bwn_mac *mac)
10121 {
10122 
10123 	if (mac->mac_phy.task_60s)
10124 		mac->mac_phy.task_60s(mac);
10125 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10126 }
10127 
10128 static void
10129 bwn_tasks(void *arg)
10130 {
10131 	struct bwn_mac *mac = arg;
10132 	struct bwn_softc *sc = mac->mac_sc;
10133 
10134 	wlan_serialize_enter();
10135 
10136 	if (mac->mac_status != BWN_MAC_STATUS_STARTED) {
10137 		wlan_serialize_exit();
10138 		return;
10139 	}
10140 
10141 	if (mac->mac_task_state % 4 == 0)
10142 		bwn_task_60s(mac);
10143 	if (mac->mac_task_state % 2 == 0)
10144 		bwn_task_30s(mac);
10145 	bwn_task_15s(mac);
10146 
10147 	mac->mac_task_state++;
10148 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10149 	wlan_serialize_exit();
10150 }
10151 
10152 static int
10153 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10154 {
10155 	struct bwn_softc *sc = mac->mac_sc;
10156 
10157 	KASSERT(a == 0, ("not support APHY\n"));
10158 
10159 	switch (plcp->o.raw[0] & 0xf) {
10160 	case 0xb:
10161 		return (BWN_OFDM_RATE_6MB);
10162 	case 0xf:
10163 		return (BWN_OFDM_RATE_9MB);
10164 	case 0xa:
10165 		return (BWN_OFDM_RATE_12MB);
10166 	case 0xe:
10167 		return (BWN_OFDM_RATE_18MB);
10168 	case 0x9:
10169 		return (BWN_OFDM_RATE_24MB);
10170 	case 0xd:
10171 		return (BWN_OFDM_RATE_36MB);
10172 	case 0x8:
10173 		return (BWN_OFDM_RATE_48MB);
10174 	case 0xc:
10175 		return (BWN_OFDM_RATE_54MB);
10176 	}
10177 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10178 	    plcp->o.raw[0] & 0xf);
10179 	return (-1);
10180 }
10181 
10182 static int
10183 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10184 {
10185 	struct bwn_softc *sc = mac->mac_sc;
10186 
10187 	switch (plcp->o.raw[0]) {
10188 	case 0x0a:
10189 		return (BWN_CCK_RATE_1MB);
10190 	case 0x14:
10191 		return (BWN_CCK_RATE_2MB);
10192 	case 0x37:
10193 		return (BWN_CCK_RATE_5MB);
10194 	case 0x6e:
10195 		return (BWN_CCK_RATE_11MB);
10196 	}
10197 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10198 	return (-1);
10199 }
10200 
10201 static void
10202 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10203     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10204     int rssi, int noise)
10205 {
10206 	struct bwn_softc *sc = mac->mac_sc;
10207 	const struct ieee80211_frame_min *wh;
10208 	uint64_t tsf;
10209 	uint16_t low_mactime_now;
10210 
10211 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10212 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10213 
10214 	wh = mtod(m, const struct ieee80211_frame_min *);
10215 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10216 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10217 
10218 	bwn_tsf_read(mac, &tsf);
10219 	low_mactime_now = tsf;
10220 	tsf = tsf & ~0xffffULL;
10221 	tsf += le16toh(rxhdr->mac_time);
10222 	if (low_mactime_now < le16toh(rxhdr->mac_time))
10223 		tsf -= 0x10000;
10224 
10225 	sc->sc_rx_th.wr_tsf = tsf;
10226 	sc->sc_rx_th.wr_rate = rate;
10227 	sc->sc_rx_th.wr_antsignal = rssi;
10228 	sc->sc_rx_th.wr_antnoise = noise;
10229 }
10230 
10231 static void
10232 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10233 {
10234 	uint32_t low, high;
10235 
10236 	KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10237 	    ("%s:%d: fail", __func__, __LINE__));
10238 
10239 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10240 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10241 	*tsf = high;
10242 	*tsf <<= 32;
10243 	*tsf |= low;
10244 }
10245 
10246 static int
10247 bwn_dma_attach(struct bwn_mac *mac)
10248 {
10249 	struct bwn_dma *dma = &mac->mac_method.dma;
10250 	struct bwn_softc *sc = mac->mac_sc;
10251 	bus_addr_t lowaddr = 0;
10252 	int error;
10253 
10254 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10255 		return (0);
10256 
10257 	KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10258 
10259 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
10260 
10261 	dma->dmatype = bwn_dma_gettype(mac);
10262 	if (dma->dmatype == BWN_DMA_30BIT)
10263 		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10264 	else if (dma->dmatype == BWN_DMA_32BIT)
10265 		lowaddr = BUS_SPACE_MAXADDR_32BIT;
10266 	else
10267 		lowaddr = BUS_SPACE_MAXADDR;
10268 
10269 	/*
10270 	 * Create top level DMA tag
10271 	 */
10272 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
10273 			       BWN_ALIGN, 0,		/* alignment, bounds */
10274 			       lowaddr,			/* lowaddr */
10275 			       BUS_SPACE_MAXADDR,	/* highaddr */
10276 			       NULL, NULL,		/* filter, filterarg */
10277 			       MAXBSIZE,		/* maxsize */
10278 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
10279 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
10280 			       0,			/* flags */
10281 			       &dma->parent_dtag);
10282 	if (error) {
10283 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10284 		return (error);
10285 	}
10286 
10287 	/*
10288 	 * Create TX/RX mbuf DMA tag
10289 	 */
10290 	error = bus_dma_tag_create(dma->parent_dtag,
10291 				4,
10292 				0,
10293 				BUS_SPACE_MAXADDR,
10294 				BUS_SPACE_MAXADDR,
10295 				NULL, NULL,
10296 				MCLBYTES,
10297 				1,
10298 				BUS_SPACE_MAXSIZE_32BIT,
10299 				0,
10300 				&dma->rxbuf_dtag);
10301 	if (error) {
10302 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10303 		goto fail0;
10304 	}
10305 	error = bus_dma_tag_create(dma->parent_dtag,
10306 				4,
10307 				0,
10308 				BUS_SPACE_MAXADDR,
10309 				BUS_SPACE_MAXADDR,
10310 				NULL, NULL,
10311 				MCLBYTES,
10312 				1,
10313 				BUS_SPACE_MAXSIZE_32BIT,
10314 				0,
10315 				&dma->txbuf_dtag);
10316 	if (error) {
10317 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10318 		goto fail1;
10319 	}
10320 
10321 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10322 	if (dma->wme[WME_AC_BK] == NULL)
10323 		goto fail2;
10324 
10325 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10326 	if (dma->wme[WME_AC_BE] == NULL)
10327 		goto fail3;
10328 
10329 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10330 	if (dma->wme[WME_AC_VI] == NULL)
10331 		goto fail4;
10332 
10333 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10334 	if (dma->wme[WME_AC_VO] == NULL)
10335 		goto fail5;
10336 
10337 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10338 	if (dma->mcast == NULL)
10339 		goto fail6;
10340 	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10341 	if (dma->rx == NULL)
10342 		goto fail7;
10343 
10344 	return (error);
10345 
10346 fail7:	bwn_dma_ringfree(&dma->mcast);
10347 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10348 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10349 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10350 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10351 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
10352 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
10353 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
10354 	return (error);
10355 }
10356 
10357 static struct bwn_dma_ring *
10358 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10359     uint16_t cookie, int *slot)
10360 {
10361 	struct bwn_dma *dma = &mac->mac_method.dma;
10362 	struct bwn_dma_ring *dr;
10363 	struct bwn_softc *sc = mac->mac_sc;
10364 
10365 	switch (cookie & 0xf000) {
10366 	case 0x1000:
10367 		dr = dma->wme[WME_AC_BK];
10368 		break;
10369 	case 0x2000:
10370 		dr = dma->wme[WME_AC_BE];
10371 		break;
10372 	case 0x3000:
10373 		dr = dma->wme[WME_AC_VI];
10374 		break;
10375 	case 0x4000:
10376 		dr = dma->wme[WME_AC_VO];
10377 		break;
10378 	case 0x5000:
10379 		dr = dma->mcast;
10380 		break;
10381 	default:
10382 		dr = NULL;
10383 		KASSERT(0 == 1,
10384 		    ("invalid cookie value %d", cookie & 0xf000));
10385 	}
10386 	*slot = (cookie & 0x0fff);
10387 	if (*slot < 0 || *slot >= dr->dr_numslots) {
10388 		/*
10389 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10390 		 * that it occurs events which have same H/W sequence numbers.
10391 		 * When it's occurred just prints a WARNING msgs and ignores.
10392 		 */
10393 		KASSERT(status->seq == dma->lastseq,
10394 		    ("%s:%d: fail", __func__, __LINE__));
10395 		device_printf(sc->sc_dev,
10396 		    "out of slot ranges (0 < %d < %d)\n", *slot,
10397 		    dr->dr_numslots);
10398 		return (NULL);
10399 	}
10400 	dma->lastseq = status->seq;
10401 	return (dr);
10402 }
10403 
10404 static void
10405 bwn_dma_stop(struct bwn_mac *mac)
10406 {
10407 	struct bwn_dma *dma;
10408 
10409 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10410 		return;
10411 	dma = &mac->mac_method.dma;
10412 
10413 	bwn_dma_ringstop(&dma->rx);
10414 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10415 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10416 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10417 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10418 	bwn_dma_ringstop(&dma->mcast);
10419 }
10420 
10421 static void
10422 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10423 {
10424 
10425 	if (dr == NULL)
10426 		return;
10427 
10428 	bwn_dma_cleanup(*dr);
10429 }
10430 
10431 static void
10432 bwn_pio_stop(struct bwn_mac *mac)
10433 {
10434 	struct bwn_pio *pio;
10435 
10436 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10437 		return;
10438 	pio = &mac->mac_method.pio;
10439 
10440 	bwn_destroy_queue_tx(&pio->mcast);
10441 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10442 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10443 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10444 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10445 }
10446 
10447 static void
10448 bwn_led_attach(struct bwn_mac *mac)
10449 {
10450 	struct bwn_softc *sc = mac->mac_sc;
10451 	const uint8_t *led_act = NULL;
10452 	uint16_t val[BWN_LED_MAX];
10453 	int i;
10454 
10455 	sc->sc_led_idle = (2350 * hz) / 1000;
10456 	sc->sc_led_blink = 1;
10457 
10458 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10459 		if (siba_get_pci_subvendor(sc->sc_dev) ==
10460 		    bwn_vendor_led_act[i].vid) {
10461 			led_act = bwn_vendor_led_act[i].led_act;
10462 			break;
10463 		}
10464 	}
10465 	if (led_act == NULL)
10466 		led_act = bwn_default_led_act;
10467 
10468 	val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10469 	val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10470 	val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10471 	val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10472 
10473 	for (i = 0; i < BWN_LED_MAX; ++i) {
10474 		struct bwn_led *led = &sc->sc_leds[i];
10475 
10476 		if (val[i] == 0xff) {
10477 			led->led_act = led_act[i];
10478 		} else {
10479 			if (val[i] & BWN_LED_ACT_LOW)
10480 				led->led_flags |= BWN_LED_F_ACTLOW;
10481 			led->led_act = val[i] & BWN_LED_ACT_MASK;
10482 		}
10483 		led->led_mask = (1 << i);
10484 
10485 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10486 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
10487 		    led->led_act == BWN_LED_ACT_BLINK) {
10488 			led->led_flags |= BWN_LED_F_BLINK;
10489 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10490 				led->led_flags |= BWN_LED_F_POLLABLE;
10491 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10492 				led->led_flags |= BWN_LED_F_SLOW;
10493 
10494 			if (sc->sc_blink_led == NULL) {
10495 				sc->sc_blink_led = led;
10496 				if (led->led_flags & BWN_LED_F_SLOW)
10497 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
10498 			}
10499 		}
10500 
10501 		DPRINTF(sc, BWN_DEBUG_LED,
10502 		    "%dth led, act %d, lowact %d\n", i,
10503 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10504 	}
10505 	callout_init(&sc->sc_led_blink_ch);
10506 }
10507 
10508 static __inline uint16_t
10509 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10510 {
10511 
10512 	if (led->led_flags & BWN_LED_F_ACTLOW)
10513 		on = !on;
10514 	if (on)
10515 		val |= led->led_mask;
10516 	else
10517 		val &= ~led->led_mask;
10518 	return val;
10519 }
10520 
10521 static void
10522 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10523 {
10524 	struct bwn_softc *sc = mac->mac_sc;
10525 	struct ifnet *ifp = sc->sc_ifp;
10526 	struct ieee80211com *ic = ifp->if_l2com;
10527 	uint16_t val;
10528 	int i;
10529 
10530 	if (nstate == IEEE80211_S_INIT) {
10531 		callout_stop(&sc->sc_led_blink_ch);
10532 		sc->sc_led_blinking = 0;
10533 	}
10534 
10535 	if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0)
10536 		return;
10537 
10538 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10539 	for (i = 0; i < BWN_LED_MAX; ++i) {
10540 		struct bwn_led *led = &sc->sc_leds[i];
10541 		int on;
10542 
10543 		if (led->led_act == BWN_LED_ACT_UNKN ||
10544 		    led->led_act == BWN_LED_ACT_NULL)
10545 			continue;
10546 
10547 		if ((led->led_flags & BWN_LED_F_BLINK) &&
10548 		    nstate != IEEE80211_S_INIT)
10549 			continue;
10550 
10551 		switch (led->led_act) {
10552 		case BWN_LED_ACT_ON:    /* Always on */
10553 			on = 1;
10554 			break;
10555 		case BWN_LED_ACT_OFF:   /* Always off */
10556 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10557 			on = 0;
10558 			break;
10559 		default:
10560 			on = 1;
10561 			switch (nstate) {
10562 			case IEEE80211_S_INIT:
10563 				on = 0;
10564 				break;
10565 			case IEEE80211_S_RUN:
10566 				if (led->led_act == BWN_LED_ACT_11G &&
10567 				    ic->ic_curmode != IEEE80211_MODE_11G)
10568 					on = 0;
10569 				break;
10570 			default:
10571 				if (led->led_act == BWN_LED_ACT_ASSOC)
10572 					on = 0;
10573 				break;
10574 			}
10575 			break;
10576 		}
10577 
10578 		val = bwn_led_onoff(led, val, on);
10579 	}
10580 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10581 }
10582 
10583 static void
10584 bwn_led_event(struct bwn_mac *mac, int event)
10585 {
10586 	struct bwn_softc *sc = mac->mac_sc;
10587 	struct bwn_led *led = sc->sc_blink_led;
10588 	int rate;
10589 
10590 	if (event == BWN_LED_EVENT_POLL) {
10591 		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10592 			return;
10593 		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10594 			return;
10595 	}
10596 
10597 	sc->sc_led_ticks = ticks;
10598 	if (sc->sc_led_blinking)
10599 		return;
10600 
10601 	switch (event) {
10602 	case BWN_LED_EVENT_RX:
10603 		rate = sc->sc_rx_rate;
10604 		break;
10605 	case BWN_LED_EVENT_TX:
10606 		rate = sc->sc_tx_rate;
10607 		break;
10608 	case BWN_LED_EVENT_POLL:
10609 		rate = 0;
10610 		break;
10611 	default:
10612 		panic("unknown LED event %d\n", event);
10613 		break;
10614 	}
10615 	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10616 	    bwn_led_duration[rate].off_dur);
10617 }
10618 
10619 static void
10620 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10621 {
10622 	struct bwn_softc *sc = mac->mac_sc;
10623 	struct bwn_led *led = sc->sc_blink_led;
10624 	uint16_t val;
10625 
10626 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10627 	val = bwn_led_onoff(led, val, 1);
10628 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10629 
10630 	if (led->led_flags & BWN_LED_F_SLOW) {
10631 		BWN_LED_SLOWDOWN(on_dur);
10632 		BWN_LED_SLOWDOWN(off_dur);
10633 	}
10634 
10635 	sc->sc_led_blinking = 1;
10636 	sc->sc_led_blink_offdur = off_dur;
10637 
10638 	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10639 }
10640 
10641 static void
10642 bwn_led_blink_next(void *arg)
10643 {
10644 	struct bwn_mac *mac = arg;
10645 	struct bwn_softc *sc = mac->mac_sc;
10646 	uint16_t val;
10647 
10648 	wlan_serialize_enter();
10649 
10650 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10651 	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10652 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10653 
10654 	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10655 	    bwn_led_blink_end, mac);
10656 	wlan_serialize_exit();
10657 }
10658 
10659 static void
10660 bwn_led_blink_end(void *arg)
10661 {
10662 	struct bwn_mac *mac = arg;
10663 	struct bwn_softc *sc = mac->mac_sc;
10664 
10665 	sc->sc_led_blinking = 0;
10666 }
10667 
10668 static int
10669 bwn_suspend(device_t dev)
10670 {
10671 	struct bwn_softc *sc = device_get_softc(dev);
10672 
10673 	wlan_serialize_enter();
10674 	bwn_stop(sc, 1);
10675 	wlan_serialize_exit();
10676 
10677 	return (0);
10678 }
10679 
10680 static int
10681 bwn_resume(device_t dev)
10682 {
10683 	struct bwn_softc *sc = device_get_softc(dev);
10684 	struct ifnet *ifp = sc->sc_ifp;
10685 
10686 	wlan_serialize_enter();
10687 	if (ifp->if_flags & IFF_UP)
10688 		bwn_init(sc);
10689 	wlan_serialize_exit();
10690 	return (0);
10691 }
10692 
10693 static void
10694 bwn_rfswitch(void *arg)
10695 {
10696 	struct bwn_softc *sc = arg;
10697 	struct bwn_mac *mac = sc->sc_curmac;
10698 	int cur = 0, prev = 0;
10699 
10700 	wlan_serialize_enter();
10701 
10702 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10703 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
10704 
10705 	if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10706 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10707 			& BWN_RF_HWENABLED_HI_MASK))
10708 			cur = 1;
10709 	} else {
10710 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10711 		    & BWN_RF_HWENABLED_LO_MASK)
10712 			cur = 1;
10713 	}
10714 
10715 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10716 		prev = 1;
10717 
10718 	if (cur != prev) {
10719 		if (cur)
10720 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10721 		else
10722 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10723 
10724 		device_printf(sc->sc_dev,
10725 		    "status of RF switch is changed to %s\n",
10726 		    cur ? "ON" : "OFF");
10727 		if (cur != mac->mac_phy.rf_on) {
10728 			if (cur)
10729 				bwn_rf_turnon(mac);
10730 			else
10731 				bwn_rf_turnoff(mac);
10732 		}
10733 	}
10734 
10735 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
10736 	wlan_serialize_exit();
10737 }
10738 
10739 static void
10740 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10741 {
10742 	struct bwn_phy *phy = &mac->mac_phy;
10743 	struct bwn_phy_lp *plp = &phy->phy_lp;
10744 
10745 	plp->plp_antenna = BWN_ANT_DEFAULT;
10746 }
10747 
10748 static int
10749 bwn_phy_lp_init(struct bwn_mac *mac)
10750 {
10751 	static const struct bwn_stxtable tables[] = {
10752 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10753 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10754 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10755 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10756 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10757 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10758 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10759 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10760 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10761 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10762 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10763 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10764 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10765 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10766 		{ 2, 11, 0x40, 0, 0x0f }
10767 	};
10768 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10769 	struct bwn_softc *sc = mac->mac_sc;
10770 	const struct bwn_stxtable *st;
10771 	struct ifnet *ifp = sc->sc_ifp;
10772 	struct ieee80211com *ic = ifp->if_l2com;
10773 	int i, error;
10774 	uint16_t tmp;
10775 
10776 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
10777 	bwn_phy_lp_bbinit(mac);
10778 
10779 	/* initialize RF */
10780 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10781 	DELAY(1);
10782 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10783 	DELAY(1);
10784 
10785 	if (mac->mac_phy.rf_ver == 0x2062)
10786 		bwn_phy_lp_b2062_init(mac);
10787 	else {
10788 		bwn_phy_lp_b2063_init(mac);
10789 
10790 		/* synchronize stx table. */
10791 		for (i = 0; i < N(tables); i++) {
10792 			st = &tables[i];
10793 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
10794 			tmp >>= st->st_rfshift;
10795 			tmp <<= st->st_physhift;
10796 			BWN_PHY_SETMASK(mac,
10797 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10798 			    ~(st->st_mask << st->st_physhift), tmp);
10799 		}
10800 
10801 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10802 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10803 	}
10804 
10805 	/* calibrate RC */
10806 	if (mac->mac_phy.rev >= 2)
10807 		bwn_phy_lp_rxcal_r2(mac);
10808 	else if (!plp->plp_rccap) {
10809 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10810 			bwn_phy_lp_rccal_r12(mac);
10811 	} else
10812 		bwn_phy_lp_set_rccap(mac);
10813 
10814 	error = bwn_phy_lp_switch_channel(mac, 7);
10815 	if (error)
10816 		device_printf(sc->sc_dev,
10817 		    "failed to change channel 7 (%d)\n", error);
10818 	bwn_phy_lp_txpctl_init(mac);
10819 	bwn_phy_lp_calib(mac);
10820 	return (0);
10821 }
10822 
10823 static uint16_t
10824 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10825 {
10826 
10827 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10828 	return (BWN_READ_2(mac, BWN_PHYDATA));
10829 }
10830 
10831 static void
10832 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10833 {
10834 
10835 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10836 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
10837 }
10838 
10839 static void
10840 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10841     uint16_t set)
10842 {
10843 
10844 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10845 	BWN_WRITE_2(mac, BWN_PHYDATA,
10846 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10847 }
10848 
10849 static uint16_t
10850 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10851 {
10852 
10853 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10854 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
10855 		reg |= 0x100;
10856 	if (mac->mac_phy.rev >= 2)
10857 		reg |= 0x200;
10858 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10859 	return BWN_READ_2(mac, BWN_RFDATALO);
10860 }
10861 
10862 static void
10863 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10864 {
10865 
10866 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10867 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10868 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
10869 }
10870 
10871 static void
10872 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10873 {
10874 
10875 	if (on) {
10876 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10877 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10878 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10879 		return;
10880 	}
10881 
10882 	if (mac->mac_phy.rev >= 2) {
10883 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10884 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10885 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10886 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10887 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10888 		return;
10889 	}
10890 
10891 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10892 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10893 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10894 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10895 }
10896 
10897 static int
10898 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10899 {
10900 	struct bwn_phy *phy = &mac->mac_phy;
10901 	struct bwn_phy_lp *plp = &phy->phy_lp;
10902 	int error;
10903 
10904 	if (phy->rf_ver == 0x2063) {
10905 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10906 		if (error)
10907 			return (error);
10908 	} else {
10909 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10910 		if (error)
10911 			return (error);
10912 		bwn_phy_lp_set_anafilter(mac, chan);
10913 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10914 	}
10915 
10916 	plp->plp_chan = chan;
10917 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10918 	return (0);
10919 }
10920 
10921 static uint32_t
10922 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10923 {
10924 	struct bwn_softc *sc = mac->mac_sc;
10925 	struct ifnet *ifp = sc->sc_ifp;
10926 	struct ieee80211com *ic = ifp->if_l2com;
10927 
10928 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10929 }
10930 
10931 static void
10932 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10933 {
10934 	struct bwn_phy *phy = &mac->mac_phy;
10935 	struct bwn_phy_lp *plp = &phy->phy_lp;
10936 
10937 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10938 		return;
10939 
10940 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10941 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10942 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10943 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10944 	plp->plp_antenna = antenna;
10945 }
10946 
10947 static void
10948 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10949 {
10950 
10951 	bwn_phy_lp_calib(mac);
10952 }
10953 
10954 static void
10955 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10956 {
10957 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10958 	struct bwn_softc *sc = mac->mac_sc;
10959 	struct ifnet *ifp = sc->sc_ifp;
10960 	struct ieee80211com *ic = ifp->if_l2com;
10961 
10962 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10963 		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10964 		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10965 		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10966 		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10967 		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10968 		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10969 		return;
10970 	}
10971 
10972 	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10973 	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10974 	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10975 	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10976 	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10977 	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10978 	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10979 	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10980 }
10981 
10982 static void
10983 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10984 {
10985 
10986 	bwn_phy_lp_tblinit(mac);
10987 	if (mac->mac_phy.rev >= 2)
10988 		bwn_phy_lp_bbinit_r2(mac);
10989 	else
10990 		bwn_phy_lp_bbinit_r01(mac);
10991 }
10992 
10993 static void
10994 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10995 {
10996 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
10997 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
10998 	struct bwn_softc *sc = mac->mac_sc;
10999 	struct ifnet *ifp = sc->sc_ifp;
11000 	struct ieee80211com *ic = ifp->if_l2com;
11001 
11002 	bwn_phy_lp_set_txgain(mac,
11003 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11004 	bwn_phy_lp_set_bbmult(mac, 150);
11005 }
11006 
11007 static void
11008 bwn_phy_lp_calib(struct bwn_mac *mac)
11009 {
11010 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11011 	struct bwn_softc *sc = mac->mac_sc;
11012 	struct ifnet *ifp = sc->sc_ifp;
11013 	struct ieee80211com *ic = ifp->if_l2com;
11014 	const struct bwn_rxcompco *rc = NULL;
11015 	struct bwn_txgain ogain;
11016 	int i, omode, oafeovr, orf, obbmult;
11017 	uint8_t mode, fc = 0;
11018 
11019 	if (plp->plp_chanfullcal != plp->plp_chan) {
11020 		plp->plp_chanfullcal = plp->plp_chan;
11021 		fc = 1;
11022 	}
11023 
11024 	bwn_mac_suspend(mac);
11025 
11026 	/* BlueTooth Coexistance Override */
11027 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11028 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11029 
11030 	if (mac->mac_phy.rev >= 2)
11031 		bwn_phy_lp_digflt_save(mac);
11032 	bwn_phy_lp_get_txpctlmode(mac);
11033 	mode = plp->plp_txpctlmode;
11034 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11035 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11036 		bwn_phy_lp_bugfix(mac);
11037 	if (mac->mac_phy.rev >= 2 && fc == 1) {
11038 		bwn_phy_lp_get_txpctlmode(mac);
11039 		omode = plp->plp_txpctlmode;
11040 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11041 		if (oafeovr)
11042 			ogain = bwn_phy_lp_get_txgain(mac);
11043 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11044 		obbmult = bwn_phy_lp_get_bbmult(mac);
11045 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11046 		if (oafeovr)
11047 			bwn_phy_lp_set_txgain(mac, &ogain);
11048 		bwn_phy_lp_set_bbmult(mac, obbmult);
11049 		bwn_phy_lp_set_txpctlmode(mac, omode);
11050 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11051 	}
11052 	bwn_phy_lp_set_txpctlmode(mac, mode);
11053 	if (mac->mac_phy.rev >= 2)
11054 		bwn_phy_lp_digflt_restore(mac);
11055 
11056 	/* do RX IQ Calculation; assumes that noise is true. */
11057 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11058 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11059 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11060 				rc = &bwn_rxcompco_5354[i];
11061 		}
11062 	} else if (mac->mac_phy.rev >= 2)
11063 		rc = &bwn_rxcompco_r2;
11064 	else {
11065 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11066 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11067 				rc = &bwn_rxcompco_r12[i];
11068 		}
11069 	}
11070 	if (rc == NULL)
11071 		goto fail;
11072 
11073 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11074 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11075 
11076 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11077 
11078 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11079 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11080 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11081 	} else {
11082 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11083 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11084 	}
11085 
11086 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11087 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11088 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11089 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11090 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11091 	bwn_phy_lp_set_deaf(mac, 0);
11092 	/* XXX no checking return value? */
11093 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11094 	bwn_phy_lp_clear_deaf(mac, 0);
11095 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11096 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11097 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11098 
11099 	/* disable RX GAIN override. */
11100 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11101 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11102 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11103 	if (mac->mac_phy.rev >= 2) {
11104 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11105 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11106 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11107 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11108 		}
11109 	} else {
11110 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11111 	}
11112 
11113 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11114 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11115 fail:
11116 	bwn_mac_enable(mac);
11117 }
11118 
11119 static void
11120 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11121 {
11122 
11123 	if (on) {
11124 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11125 		return;
11126 	}
11127 
11128 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11129 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11130 }
11131 
11132 static int
11133 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11134 {
11135 	static const struct bwn_b206x_chan *bc = NULL;
11136 	struct bwn_softc *sc = mac->mac_sc;
11137 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11138 	    tmp[6];
11139 	uint16_t old, scale, tmp16;
11140 	int i, div;
11141 
11142 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
11143 		if (bwn_b2063_chantable[i].bc_chan == chan) {
11144 			bc = &bwn_b2063_chantable[i];
11145 			break;
11146 		}
11147 	}
11148 	if (bc == NULL)
11149 		return (EINVAL);
11150 
11151 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11152 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11153 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11154 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11155 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11156 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11157 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11158 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11159 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11160 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11161 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11162 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11163 
11164 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
11165 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11166 
11167 	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11168 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11169 	freqref = freqxtal * 3;
11170 	div = (freqxtal <= 26000000 ? 1 : 2);
11171 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11172 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11173 		999999) / 1000000) + 1;
11174 
11175 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11176 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11177 	    0xfff8, timeout >> 2);
11178 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11179 	    0xff9f,timeout << 5);
11180 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11181 
11182 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11183 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11184 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11185 
11186 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11187 	    (timeoutref + 1)) - 1;
11188 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11189 	    0xf0, count >> 8);
11190 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11191 
11192 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
11193 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
11194 	while (tmp[1] >= freqref) {
11195 		tmp[0]++;
11196 		tmp[1] -= freqref;
11197 	}
11198 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11199 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11200 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11201 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11202 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11203 
11204 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11205 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11206 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11207 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11208 
11209 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11210 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11211 
11212 	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11213 		scale = 1;
11214 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11215 	} else {
11216 		scale = 0;
11217 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11218 	}
11219 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11220 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11221 
11222 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11223 	    (scale + 1);
11224 	if (tmp[5] > 150)
11225 		tmp[5] = 0;
11226 
11227 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11228 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11229 
11230 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11231 	if (freqxtal > 26000000)
11232 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11233 	else
11234 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11235 
11236 	if (val[0] == 45)
11237 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11238 	else
11239 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11240 
11241 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11242 	DELAY(1);
11243 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11244 
11245 	/* VCO Calibration */
11246 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11247 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11248 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11249 	DELAY(1);
11250 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11251 	DELAY(1);
11252 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11253 	DELAY(1);
11254 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11255 	DELAY(300);
11256 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11257 
11258 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11259 	return (0);
11260 }
11261 
11262 static int
11263 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11264 {
11265 	struct bwn_softc *sc = mac->mac_sc;
11266 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11267 	const struct bwn_b206x_chan *bc = NULL;
11268 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11269 	uint32_t tmp[9];
11270 	int i;
11271 
11272 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
11273 		if (bwn_b2062_chantable[i].bc_chan == chan) {
11274 			bc = &bwn_b2062_chantable[i];
11275 			break;
11276 		}
11277 	}
11278 
11279 	if (bc == NULL)
11280 		return (EINVAL);
11281 
11282 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11283 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11284 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11285 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11286 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11287 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11288 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11289 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11290 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11291 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11292 
11293 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11294 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11295 	bwn_phy_lp_b2062_reset_pllbias(mac);
11296 	tmp[0] = freqxtal / 1000;
11297 	tmp[1] = plp->plp_div * 1000;
11298 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11299 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
11300 		tmp[2] *= 2;
11301 	tmp[3] = 48 * tmp[0];
11302 	tmp[5] = tmp[2] / tmp[3];
11303 	tmp[6] = tmp[2] % tmp[3];
11304 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11305 	tmp[4] = tmp[6] * 0x100;
11306 	tmp[5] = tmp[4] / tmp[3];
11307 	tmp[6] = tmp[4] % tmp[3];
11308 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11309 	tmp[4] = tmp[6] * 0x100;
11310 	tmp[5] = tmp[4] / tmp[3];
11311 	tmp[6] = tmp[4] % tmp[3];
11312 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11313 	tmp[4] = tmp[6] * 0x100;
11314 	tmp[5] = tmp[4] / tmp[3];
11315 	tmp[6] = tmp[4] % tmp[3];
11316 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11317 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
11318 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11319 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11320 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11321 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11322 
11323 	bwn_phy_lp_b2062_vco_calib(mac);
11324 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11325 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11326 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11327 		bwn_phy_lp_b2062_reset_pllbias(mac);
11328 		bwn_phy_lp_b2062_vco_calib(mac);
11329 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11330 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11331 			return (EIO);
11332 		}
11333 	}
11334 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11335 	return (0);
11336 }
11337 
11338 static void
11339 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11340 {
11341 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11342 	uint16_t tmp = (channel == 14);
11343 
11344 	if (mac->mac_phy.rev < 2) {
11345 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11346 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11347 			bwn_phy_lp_set_rccap(mac);
11348 		return;
11349 	}
11350 
11351 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11352 }
11353 
11354 static void
11355 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11356 {
11357 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11358 	struct bwn_softc *sc = mac->mac_sc;
11359 	struct ifnet *ifp = sc->sc_ifp;
11360 	struct ieee80211com *ic = ifp->if_l2com;
11361 	uint16_t iso, tmp[3];
11362 
11363 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11364 
11365 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11366 		iso = plp->plp_txisoband_m;
11367 	else if (freq <= 5320)
11368 		iso = plp->plp_txisoband_l;
11369 	else if (freq <= 5700)
11370 		iso = plp->plp_txisoband_m;
11371 	else
11372 		iso = plp->plp_txisoband_h;
11373 
11374 	tmp[0] = ((iso - 26) / 12) << 12;
11375 	tmp[1] = tmp[0] + 0x1000;
11376 	tmp[2] = tmp[0] + 0x2000;
11377 
11378 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11379 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11380 }
11381 
11382 static void
11383 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11384 {
11385 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11386 	int i;
11387 	static const uint16_t addr[] = {
11388 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11389 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11390 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11391 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11392 		BWN_PHY_OFDM(0xcf),
11393 	};
11394 	static const uint16_t val[] = {
11395 		0xde5e, 0xe832, 0xe331, 0x4d26,
11396 		0x0026, 0x1420, 0x0020, 0xfe08,
11397 		0x0008,
11398 	};
11399 
11400 	for (i = 0; i < N(addr); i++) {
11401 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11402 		BWN_PHY_WRITE(mac, addr[i], val[i]);
11403 	}
11404 }
11405 
11406 static void
11407 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11408 {
11409 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11410 	struct bwn_softc *sc = mac->mac_sc;
11411 	uint16_t ctl;
11412 
11413 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11414 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11415 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11416 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11417 		break;
11418 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11419 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11420 		break;
11421 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11422 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11423 		break;
11424 	default:
11425 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11426 		device_printf(sc->sc_dev, "unknown command mode\n");
11427 		break;
11428 	}
11429 }
11430 
11431 static void
11432 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11433 {
11434 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11435 	uint16_t ctl;
11436 	uint8_t old;
11437 
11438 	bwn_phy_lp_get_txpctlmode(mac);
11439 	old = plp->plp_txpctlmode;
11440 	if (old == mode)
11441 		return;
11442 	plp->plp_txpctlmode = mode;
11443 
11444 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11445 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11446 		    plp->plp_tssiidx);
11447 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11448 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11449 
11450 		/* disable TX GAIN override */
11451 		if (mac->mac_phy.rev < 2)
11452 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11453 		else {
11454 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11455 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11456 		}
11457 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11458 
11459 		plp->plp_txpwridx = -1;
11460 	}
11461 	if (mac->mac_phy.rev >= 2) {
11462 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11463 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11464 		else
11465 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11466 	}
11467 
11468 	/* writes TX Power Control mode */
11469 	switch (plp->plp_txpctlmode) {
11470 	case BWN_PHYLP_TXPCTL_OFF:
11471 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11472 		break;
11473 	case BWN_PHYLP_TXPCTL_ON_HW:
11474 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11475 		break;
11476 	case BWN_PHYLP_TXPCTL_ON_SW:
11477 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11478 		break;
11479 	default:
11480 		ctl = 0;
11481 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11482 	}
11483 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11484 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11485 }
11486 
11487 static void
11488 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11489 {
11490 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11491 	const unsigned int size = 256;
11492 	struct bwn_txgain tg;
11493 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11494 	uint16_t tssinpt, tssiidx, value[2];
11495 	uint8_t mode;
11496 	int8_t txpwridx;
11497 
11498 	tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF,
11499 	    M_INTWAIT | M_ZERO);
11500 
11501 	bwn_phy_lp_get_txpctlmode(mac);
11502 	mode = plp->plp_txpctlmode;
11503 	txpwridx = plp->plp_txpwridx;
11504 	tssinpt = plp->plp_tssinpt;
11505 	tssiidx = plp->plp_tssiidx;
11506 
11507 	bwn_tab_read_multi(mac,
11508 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11509 	    BWN_TAB_4(7, 0x140), size, tabs);
11510 
11511 	bwn_phy_lp_tblinit(mac);
11512 	bwn_phy_lp_bbinit(mac);
11513 	bwn_phy_lp_txpctl_init(mac);
11514 	bwn_phy_lp_rf_onoff(mac, 1);
11515 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11516 
11517 	bwn_tab_write_multi(mac,
11518 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11519 	    BWN_TAB_4(7, 0x140), size, tabs);
11520 
11521 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11522 	plp->plp_tssinpt = tssinpt;
11523 	plp->plp_tssiidx = tssiidx;
11524 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11525 	if (txpwridx != -1) {
11526 		/* set TX power by index */
11527 		plp->plp_txpwridx = txpwridx;
11528 		bwn_phy_lp_get_txpctlmode(mac);
11529 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11530 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11531 		if (mac->mac_phy.rev >= 2) {
11532 			rxcomp = bwn_tab_read(mac,
11533 			    BWN_TAB_4(7, txpwridx + 320));
11534 			txgain = bwn_tab_read(mac,
11535 			    BWN_TAB_4(7, txpwridx + 192));
11536 			tg.tg_pad = (txgain >> 16) & 0xff;
11537 			tg.tg_gm = txgain & 0xff;
11538 			tg.tg_pga = (txgain >> 8) & 0xff;
11539 			tg.tg_dac = (rxcomp >> 28) & 0xff;
11540 			bwn_phy_lp_set_txgain(mac, &tg);
11541 		} else {
11542 			rxcomp = bwn_tab_read(mac,
11543 			    BWN_TAB_4(10, txpwridx + 320));
11544 			txgain = bwn_tab_read(mac,
11545 			    BWN_TAB_4(10, txpwridx + 192));
11546 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11547 			    0xf800, (txgain >> 4) & 0x7fff);
11548 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11549 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11550 		}
11551 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11552 
11553 		/* set TX IQCC */
11554 		value[0] = (rxcomp >> 10) & 0x3ff;
11555 		value[1] = rxcomp & 0x3ff;
11556 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11557 
11558 		coeff = bwn_tab_read(mac,
11559 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11560 		    BWN_TAB_4(10, txpwridx + 448));
11561 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11562 		if (mac->mac_phy.rev >= 2) {
11563 			rfpwr = bwn_tab_read(mac,
11564 			    BWN_TAB_4(7, txpwridx + 576));
11565 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11566 			    rfpwr & 0xffff);
11567 		}
11568 		bwn_phy_lp_set_txgain_override(mac);
11569 	}
11570 	if (plp->plp_rccap)
11571 		bwn_phy_lp_set_rccap(mac);
11572 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11573 	bwn_phy_lp_set_txpctlmode(mac, mode);
11574 	kfree(tabs, M_DEVBUF);
11575 }
11576 
11577 static void
11578 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11579 {
11580 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11581 	int i;
11582 	static const uint16_t addr[] = {
11583 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11584 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11585 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11586 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11587 		BWN_PHY_OFDM(0xcf),
11588 	};
11589 
11590 	for (i = 0; i < N(addr); i++)
11591 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11592 }
11593 
11594 static void
11595 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11596 {
11597 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11598 
11599 	if (mac->mac_phy.rev < 2) {
11600 		bwn_phy_lp_tblinit_r01(mac);
11601 		bwn_phy_lp_tblinit_txgain(mac);
11602 		bwn_phy_lp_set_gaintbl(mac, freq);
11603 		return;
11604 	}
11605 
11606 	bwn_phy_lp_tblinit_r2(mac);
11607 	bwn_phy_lp_tblinit_txgain(mac);
11608 }
11609 
11610 struct bwn_wpair {
11611 	uint16_t		reg;
11612 	uint16_t		value;
11613 };
11614 
11615 struct bwn_smpair {
11616 	uint16_t		offset;
11617 	uint16_t		mask;
11618 	uint16_t		set;
11619 };
11620 
11621 static void
11622 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11623 {
11624 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11625 	struct bwn_softc *sc = mac->mac_sc;
11626 	struct ifnet *ifp = sc->sc_ifp;
11627 	struct ieee80211com *ic = ifp->if_l2com;
11628 	static const struct bwn_wpair v1[] = {
11629 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
11630 		{ BWN_PHY_AFE_CTL, 0x8800 },
11631 		{ BWN_PHY_AFE_CTL_OVR, 0 },
11632 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
11633 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
11634 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
11635 		{ BWN_PHY_OFDM(0xf9), 0 },
11636 		{ BWN_PHY_TR_LOOKUP_1, 0 }
11637 	};
11638 	static const struct bwn_smpair v2[] = {
11639 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11640 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11641 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11642 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11643 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11644 	};
11645 	static const struct bwn_smpair v3[] = {
11646 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11647 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11648 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11649 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11650 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11651 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11652 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11653 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11654 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11655 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11656 
11657 	};
11658 	int i;
11659 
11660 	for (i = 0; i < N(v1); i++)
11661 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11662 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11663 	for (i = 0; i < N(v2); i++)
11664 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11665 
11666 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11667 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11668 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11669 	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11670 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11671 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11672 	} else {
11673 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11674 	}
11675 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11676 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11677 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11678 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11679 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11680 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11681 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11682 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11683 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11684 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11685 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11686 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11687 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11688 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11689 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11690 	} else {
11691 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11692 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11693 	}
11694 	for (i = 0; i < N(v3); i++)
11695 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11696 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11697 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11698 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11699 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11700 	}
11701 
11702 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11703 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11704 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11705 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11706 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11707 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11708 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11709 	} else
11710 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11711 
11712 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11713 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11714 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11715 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11716 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11717 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11718 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11719 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11720 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11721 
11722 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11723 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11724 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11725 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11726 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11727 	}
11728 
11729 	bwn_phy_lp_digflt_save(mac);
11730 }
11731 
11732 static void
11733 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11734 {
11735 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11736 	struct bwn_softc *sc = mac->mac_sc;
11737 	struct ifnet *ifp = sc->sc_ifp;
11738 	struct ieee80211com *ic = ifp->if_l2com;
11739 	static const struct bwn_smpair v1[] = {
11740 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11741 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11742 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11743 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11744 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11745 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11746 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11747 	};
11748 	static const struct bwn_smpair v2[] = {
11749 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11750 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11751 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11752 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11753 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11754 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11755 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11756 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11757 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11758 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11759 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11760 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11761 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11762 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11763 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11764 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11765 	};
11766 	static const struct bwn_smpair v3[] = {
11767 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11768 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11769 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11770 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11771 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11772 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11773 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11774 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11775 	};
11776 	static const struct bwn_smpair v4[] = {
11777 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11778 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11779 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11780 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11781 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11782 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11783 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11784 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11785 	};
11786 	static const struct bwn_smpair v5[] = {
11787 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11788 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11789 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11790 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11791 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11792 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11793 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11794 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11795 	};
11796 	int i;
11797 	uint16_t tmp, tmp2;
11798 
11799 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11800 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11801 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11802 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11803 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11804 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11805 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11806 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11807 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11808 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11809 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11810 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11811 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11812 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11813 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11814 	for (i = 0; i < N(v1); i++)
11815 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11816 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11817 	    0xff00, plp->plp_rxpwroffset);
11818 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11819 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11820 	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11821 		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11822 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11823 		if (mac->mac_phy.rev == 0)
11824 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11825 			    0xffcf, 0x0010);
11826 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11827 	} else {
11828 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11829 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11830 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11831 	}
11832 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11833 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11834 	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11835 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11836 	else
11837 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11838 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11839 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11840 	    0xfff9, (plp->plp_bxarch << 1));
11841 	if (mac->mac_phy.rev == 1 &&
11842 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11843 		for (i = 0; i < N(v2); i++)
11844 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11845 			    v2[i].set);
11846 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11847 	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11848 	    ((mac->mac_phy.rev == 0) &&
11849 	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11850 		for (i = 0; i < N(v3); i++)
11851 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11852 			    v3[i].set);
11853 	} else if (mac->mac_phy.rev == 1 ||
11854 		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11855 		for (i = 0; i < N(v4); i++)
11856 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11857 			    v4[i].set);
11858 	} else {
11859 		for (i = 0; i < N(v5); i++)
11860 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11861 			    v5[i].set);
11862 	}
11863 	if (mac->mac_phy.rev == 1 &&
11864 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11865 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11866 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11867 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11868 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11869 	}
11870 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11871 	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11872 	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11873 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11874 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11875 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11876 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11877 	}
11878 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11879 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11880 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11881 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11882 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11883 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11884 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11885 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11886 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11887 	} else {
11888 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11889 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11890 	}
11891 	if (mac->mac_phy.rev == 1) {
11892 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11893 		tmp2 = (tmp & 0x03e0) >> 5;
11894 		tmp2 |= tmp2 << 5;
11895 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11896 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11897 		tmp2 = (tmp & 0x1f00) >> 8;
11898 		tmp2 |= tmp2 << 5;
11899 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11900 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11901 		tmp2 = tmp & 0x00ff;
11902 		tmp2 |= tmp << 8;
11903 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11904 	}
11905 }
11906 
11907 struct bwn_b2062_freq {
11908 	uint16_t		freq;
11909 	uint8_t			value[6];
11910 };
11911 
11912 static void
11913 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11914 {
11915 #define	CALC_CTL7(freq, div)						\
11916 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11917 #define	CALC_CTL18(freq, div)						\
11918 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11919 #define	CALC_CTL19(freq, div)						\
11920 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11921 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11922 	struct bwn_softc *sc = mac->mac_sc;
11923 	struct ifnet *ifp = sc->sc_ifp;
11924 	struct ieee80211com *ic = ifp->if_l2com;
11925 	static const struct bwn_b2062_freq freqdata_tab[] = {
11926 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
11927 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
11928 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
11929 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
11930 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
11931 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
11932 	};
11933 	static const struct bwn_wpair v1[] = {
11934 		{ BWN_B2062_N_TXCTL3, 0 },
11935 		{ BWN_B2062_N_TXCTL4, 0 },
11936 		{ BWN_B2062_N_TXCTL5, 0 },
11937 		{ BWN_B2062_N_TXCTL6, 0 },
11938 		{ BWN_B2062_N_PDNCTL0, 0x40 },
11939 		{ BWN_B2062_N_PDNCTL0, 0 },
11940 		{ BWN_B2062_N_CALIB_TS, 0x10 },
11941 		{ BWN_B2062_N_CALIB_TS, 0 }
11942 	};
11943 	const struct bwn_b2062_freq *f = NULL;
11944 	uint32_t xtalfreq, ref;
11945 	unsigned int i;
11946 
11947 	bwn_phy_lp_b2062_tblinit(mac);
11948 
11949 	for (i = 0; i < N(v1); i++)
11950 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11951 	if (mac->mac_phy.rev > 0)
11952 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11953 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11954 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11955 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11956 	else
11957 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11958 
11959 	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11960 	    ("%s:%d: fail", __func__, __LINE__));
11961 	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11962 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11963 
11964 	if (xtalfreq <= 30000000) {
11965 		plp->plp_div = 1;
11966 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11967 	} else {
11968 		plp->plp_div = 2;
11969 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11970 	}
11971 
11972 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11973 	    CALC_CTL7(xtalfreq, plp->plp_div));
11974 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11975 	    CALC_CTL18(xtalfreq, plp->plp_div));
11976 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11977 	    CALC_CTL19(xtalfreq, plp->plp_div));
11978 
11979 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11980 	ref &= 0xffff;
11981 	for (i = 0; i < N(freqdata_tab); i++) {
11982 		if (ref < freqdata_tab[i].freq) {
11983 			f = &freqdata_tab[i];
11984 			break;
11985 		}
11986 	}
11987 	if (f == NULL)
11988 		f = &freqdata_tab[N(freqdata_tab) - 1];
11989 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11990 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11991 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11992 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11993 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11994 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11995 #undef CALC_CTL7
11996 #undef CALC_CTL18
11997 #undef CALC_CTL19
11998 }
11999 
12000 static void
12001 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12002 {
12003 
12004 	bwn_phy_lp_b2063_tblinit(mac);
12005 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12006 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12007 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12008 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12009 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12010 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12011 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12012 	if (mac->mac_phy.rev == 2) {
12013 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12014 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12015 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12016 	} else {
12017 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12018 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12019 	}
12020 }
12021 
12022 static void
12023 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12024 {
12025 	struct bwn_softc *sc = mac->mac_sc;
12026 	static const struct bwn_wpair v1[] = {
12027 		{ BWN_B2063_RX_BB_SP8, 0x0 },
12028 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12029 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12030 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
12031 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
12032 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
12033 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
12034 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
12035 	};
12036 	static const struct bwn_wpair v2[] = {
12037 		{ BWN_B2063_TX_BB_SP3, 0x0 },
12038 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12039 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12040 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
12041 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
12042 	};
12043 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12044 	int i;
12045 	uint8_t tmp;
12046 
12047 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12048 
12049 	for (i = 0; i < 2; i++)
12050 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12051 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12052 	for (i = 2; i < N(v1); i++)
12053 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12054 	for (i = 0; i < 10000; i++) {
12055 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12056 			break;
12057 		DELAY(1000);
12058 	}
12059 
12060 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12061 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12062 
12063 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12064 
12065 	for (i = 0; i < N(v2); i++)
12066 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12067 	if (freqxtal == 24000000) {
12068 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12069 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12070 	} else {
12071 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12072 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12073 	}
12074 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12075 	for (i = 0; i < 10000; i++) {
12076 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12077 			break;
12078 		DELAY(1000);
12079 	}
12080 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12081 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12082 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12083 }
12084 
12085 static void
12086 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12087 {
12088 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12089 	struct bwn_softc *sc = mac->mac_sc;
12090 	struct bwn_phy_lp_iq_est ie;
12091 	struct bwn_txgain tx_gains;
12092 	static const uint32_t pwrtbl[21] = {
12093 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12094 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12095 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12096 		0x0004c, 0x0002c, 0x0001a,
12097 	};
12098 	uint32_t npwr, ipwr, sqpwr, tmp;
12099 	int loopback, i, j, sum, error;
12100 	uint16_t save[7];
12101 	uint8_t txo, bbmult, txpctlmode;
12102 
12103 	error = bwn_phy_lp_switch_channel(mac, 7);
12104 	if (error)
12105 		device_printf(sc->sc_dev,
12106 		    "failed to change channel to 7 (%d)\n", error);
12107 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12108 	bbmult = bwn_phy_lp_get_bbmult(mac);
12109 	if (txo)
12110 		tx_gains = bwn_phy_lp_get_txgain(mac);
12111 
12112 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12113 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12114 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12115 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12116 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12117 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12118 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12119 
12120 	bwn_phy_lp_get_txpctlmode(mac);
12121 	txpctlmode = plp->plp_txpctlmode;
12122 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12123 
12124 	/* disable CRS */
12125 	bwn_phy_lp_set_deaf(mac, 1);
12126 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
12127 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12128 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12129 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12130 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12131 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12132 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12133 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12134 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12135 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12136 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12137 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12138 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12139 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12140 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12141 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12142 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12143 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12144 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12145 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12146 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12147 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12148 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12149 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12150 
12151 	loopback = bwn_phy_lp_loopback(mac);
12152 	if (loopback == -1)
12153 		goto done;
12154 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
12155 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12156 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12157 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12158 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12159 
12160 	tmp = 0;
12161 	memset(&ie, 0, sizeof(ie));
12162 	for (i = 128; i <= 159; i++) {
12163 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12164 		sum = 0;
12165 		for (j = 5; j <= 25; j++) {
12166 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12167 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12168 				goto done;
12169 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12170 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12171 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12172 			    12);
12173 			sum += ((ipwr - npwr) * (ipwr - npwr));
12174 			if ((i == 128) || (sum < tmp)) {
12175 				plp->plp_rccap = i;
12176 				tmp = sum;
12177 			}
12178 		}
12179 	}
12180 	bwn_phy_lp_ddfs_turnoff(mac);
12181 done:
12182 	/* restore CRS */
12183 	bwn_phy_lp_clear_deaf(mac, 1);
12184 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12185 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12186 
12187 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12188 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12189 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12190 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12191 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12192 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12193 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12194 
12195 	bwn_phy_lp_set_bbmult(mac, bbmult);
12196 	if (txo)
12197 		bwn_phy_lp_set_txgain(mac, &tx_gains);
12198 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12199 	if (plp->plp_rccap)
12200 		bwn_phy_lp_set_rccap(mac);
12201 }
12202 
12203 static void
12204 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12205 {
12206 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12207 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12208 
12209 	if (mac->mac_phy.rev == 1)
12210 		rc_cap = MIN(rc_cap + 5, 15);
12211 
12212 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12213 	    MAX(plp->plp_rccap - 4, 0x80));
12214 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12215 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12216 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12217 }
12218 
12219 static uint32_t
12220 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12221 {
12222 	uint32_t i, q, r;
12223 
12224 	if (div == 0)
12225 		return (0);
12226 
12227 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12228 		q <<= 1;
12229 		if (r << 1 >= div) {
12230 			q++;
12231 			r = (r << 1) - div;
12232 		}
12233 	}
12234 	if (r << 1 >= div)
12235 		q++;
12236 	return (q);
12237 }
12238 
12239 static void
12240 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12241 {
12242 	struct bwn_softc *sc = mac->mac_sc;
12243 
12244 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12245 	DELAY(20);
12246 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12247 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12248 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12249 	} else {
12250 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12251 	}
12252 	DELAY(5);
12253 }
12254 
12255 static void
12256 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12257 {
12258 
12259 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12260 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12261 	DELAY(200);
12262 }
12263 
12264 static void
12265 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12266 {
12267 #define	FLAG_A	0x01
12268 #define	FLAG_G	0x02
12269 	struct bwn_softc *sc = mac->mac_sc;
12270 	struct ifnet *ifp = sc->sc_ifp;
12271 	struct ieee80211com *ic = ifp->if_l2com;
12272 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12273 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12274 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12275 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12276 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12277 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12278 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12279 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12280 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12281 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12282 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12283 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12284 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12285 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12286 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12287 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12288 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12289 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12290 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12291 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12292 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12293 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12294 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12295 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12296 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12297 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12298 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12299 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12300 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12301 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12302 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12303 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12304 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12305 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12306 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12307 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12308 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12309 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12310 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12311 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12312 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12313 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12314 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12315 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12316 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12317 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12318 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12319 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12320 	};
12321 	const struct bwn_b206x_rfinit_entry *br;
12322 	unsigned int i;
12323 
12324 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12325 		br = &bwn_b2062_init_tab[i];
12326 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12327 			if (br->br_flags & FLAG_G)
12328 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12329 		} else {
12330 			if (br->br_flags & FLAG_A)
12331 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12332 		}
12333 	}
12334 #undef FLAG_A
12335 #undef FLAG_B
12336 }
12337 
12338 static void
12339 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12340 {
12341 #define	FLAG_A	0x01
12342 #define	FLAG_G	0x02
12343 	struct bwn_softc *sc = mac->mac_sc;
12344 	struct ifnet *ifp = sc->sc_ifp;
12345 	struct ieee80211com *ic = ifp->if_l2com;
12346 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12347 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12348 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12349 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12350 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12351 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12352 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12353 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12354 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12355 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12356 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12357 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12358 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12359 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12360 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12361 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12362 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12363 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12364 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12365 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12366 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12367 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12368 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12369 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12370 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12371 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12372 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12373 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12374 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12375 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12376 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12377 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12378 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12379 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12380 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12381 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12382 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12383 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12384 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12385 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12386 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12387 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12388 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12389 	};
12390 	const struct bwn_b206x_rfinit_entry *br;
12391 	unsigned int i;
12392 
12393 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12394 		br = &bwn_b2063_init_tab[i];
12395 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12396 			if (br->br_flags & FLAG_G)
12397 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12398 		} else {
12399 			if (br->br_flags & FLAG_A)
12400 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12401 		}
12402 	}
12403 #undef FLAG_A
12404 #undef FLAG_B
12405 }
12406 
12407 static void
12408 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12409     int count, void *_data)
12410 {
12411 	unsigned int i;
12412 	uint32_t offset, type;
12413 	uint8_t *data = _data;
12414 
12415 	type = BWN_TAB_GETTYPE(typenoffset);
12416 	offset = BWN_TAB_GETOFFSET(typenoffset);
12417 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12418 
12419 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12420 
12421 	for (i = 0; i < count; i++) {
12422 		switch (type) {
12423 		case BWN_TAB_8BIT:
12424 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12425 			data++;
12426 			break;
12427 		case BWN_TAB_16BIT:
12428 			*((uint16_t *)data) = BWN_PHY_READ(mac,
12429 			    BWN_PHY_TABLEDATALO);
12430 			data += 2;
12431 			break;
12432 		case BWN_TAB_32BIT:
12433 			*((uint32_t *)data) = BWN_PHY_READ(mac,
12434 			    BWN_PHY_TABLEDATAHI);
12435 			*((uint32_t *)data) <<= 16;
12436 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
12437 			    BWN_PHY_TABLEDATALO);
12438 			data += 4;
12439 			break;
12440 		default:
12441 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12442 		}
12443 	}
12444 }
12445 
12446 static void
12447 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12448     int count, const void *_data)
12449 {
12450 	uint32_t offset, type, value;
12451 	const uint8_t *data = _data;
12452 	unsigned int i;
12453 
12454 	type = BWN_TAB_GETTYPE(typenoffset);
12455 	offset = BWN_TAB_GETOFFSET(typenoffset);
12456 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12457 
12458 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12459 
12460 	for (i = 0; i < count; i++) {
12461 		switch (type) {
12462 		case BWN_TAB_8BIT:
12463 			value = *data;
12464 			data++;
12465 			KASSERT(!(value & ~0xff),
12466 			    ("%s:%d: fail", __func__, __LINE__));
12467 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12468 			break;
12469 		case BWN_TAB_16BIT:
12470 			value = *((const uint16_t *)data);
12471 			data += 2;
12472 			KASSERT(!(value & ~0xffff),
12473 			    ("%s:%d: fail", __func__, __LINE__));
12474 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12475 			break;
12476 		case BWN_TAB_32BIT:
12477 			value = *((const uint32_t *)data);
12478 			data += 4;
12479 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12480 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12481 			break;
12482 		default:
12483 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12484 		}
12485 	}
12486 }
12487 
12488 static struct bwn_txgain
12489 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12490 {
12491 	struct bwn_txgain tg;
12492 	uint16_t tmp;
12493 
12494 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12495 	if (mac->mac_phy.rev < 2) {
12496 		tmp = BWN_PHY_READ(mac,
12497 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12498 		tg.tg_gm = tmp & 0x0007;
12499 		tg.tg_pga = (tmp & 0x0078) >> 3;
12500 		tg.tg_pad = (tmp & 0x780) >> 7;
12501 		return (tg);
12502 	}
12503 
12504 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12505 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12506 	tg.tg_gm = tmp & 0xff;
12507 	tg.tg_pga = (tmp >> 8) & 0xff;
12508 	return (tg);
12509 }
12510 
12511 static uint8_t
12512 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12513 {
12514 
12515 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12516 }
12517 
12518 static void
12519 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12520 {
12521 	uint16_t pa;
12522 
12523 	if (mac->mac_phy.rev < 2) {
12524 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12525 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12526 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12527 		bwn_phy_lp_set_txgain_override(mac);
12528 		return;
12529 	}
12530 
12531 	pa = bwn_phy_lp_get_pa_gain(mac);
12532 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12533 	    (tg->tg_pga << 8) | tg->tg_gm);
12534 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12535 	    tg->tg_pad | (pa << 6));
12536 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12537 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12538 	    tg->tg_pad | (pa << 8));
12539 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12540 	bwn_phy_lp_set_txgain_override(mac);
12541 }
12542 
12543 static void
12544 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12545 {
12546 
12547 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12548 }
12549 
12550 static void
12551 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12552 {
12553 	uint16_t trsw = (tx << 1) | rx;
12554 
12555 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12556 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12557 }
12558 
12559 static void
12560 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12561 {
12562 	struct bwn_softc *sc = mac->mac_sc;
12563 	struct ifnet *ifp = sc->sc_ifp;
12564 	struct ieee80211com *ic = ifp->if_l2com;
12565 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12566 
12567 	if (mac->mac_phy.rev < 2) {
12568 		trsw = gain & 0x1;
12569 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12570 		ext_lna = (gain & 2) >> 1;
12571 
12572 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12573 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12574 		    0xfbff, ext_lna << 10);
12575 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12576 		    0xf7ff, ext_lna << 11);
12577 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12578 	} else {
12579 		low_gain = gain & 0xffff;
12580 		high_gain = (gain >> 16) & 0xf;
12581 		ext_lna = (gain >> 21) & 0x1;
12582 		trsw = ~(gain >> 20) & 0x1;
12583 
12584 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12585 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12586 		    0xfdff, ext_lna << 9);
12587 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12588 		    0xfbff, ext_lna << 10);
12589 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12590 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12591 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12592 			tmp = (gain >> 2) & 0x3;
12593 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12594 			    0xe7ff, tmp<<11);
12595 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12596 			    tmp << 3);
12597 		}
12598 	}
12599 
12600 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12601 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12602 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12603 	if (mac->mac_phy.rev >= 2) {
12604 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12605 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12606 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12607 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12608 		}
12609 		return;
12610 	}
12611 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12612 }
12613 
12614 static void
12615 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12616 {
12617 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12618 
12619 	if (user)
12620 		plp->plp_crsusr_off = 1;
12621 	else
12622 		plp->plp_crssys_off = 1;
12623 
12624 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12625 }
12626 
12627 static void
12628 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12629 {
12630 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12631 	struct bwn_softc *sc = mac->mac_sc;
12632 	struct ifnet *ifp = sc->sc_ifp;
12633 	struct ieee80211com *ic = ifp->if_l2com;
12634 
12635 	if (user)
12636 		plp->plp_crsusr_off = 0;
12637 	else
12638 		plp->plp_crssys_off = 0;
12639 
12640 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
12641 		return;
12642 
12643 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12644 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12645 	else
12646 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12647 }
12648 
12649 static unsigned int
12650 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12651 {
12652 	/* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12653 	static uint8_t sqrt_table[256] = {
12654 		10, 14, 17, 20, 22, 24, 26, 28,
12655 		30, 31, 33, 34, 36, 37, 38, 40,
12656 		41, 42, 43, 44, 45, 46, 47, 48,
12657 		50, 50, 51, 52, 53, 54, 55, 56,
12658 		57, 58, 59, 60, 60, 61, 62, 63,
12659 		64, 64, 65, 66, 67, 67, 68, 69,
12660 		70, 70, 71, 72, 72, 73, 74, 74,
12661 		75, 76, 76, 77, 78, 78, 79, 80,
12662 		80, 81, 81, 82, 83, 83, 84, 84,
12663 		85, 86, 86, 87, 87, 88, 88, 89,
12664 		90, 90, 91, 91, 92, 92, 93, 93,
12665 		94, 94, 95, 95, 96, 96, 97, 97,
12666 		98, 98, 99, 100, 100, 100, 101, 101,
12667 		102, 102, 103, 103, 104, 104, 105, 105,
12668 		106, 106, 107, 107, 108, 108, 109, 109,
12669 		110, 110, 110, 111, 111, 112, 112, 113,
12670 		113, 114, 114, 114, 115, 115, 116, 116,
12671 		117, 117, 117, 118, 118, 119, 119, 120,
12672 		120, 120, 121, 121, 122, 122, 122, 123,
12673 		123, 124, 124, 124, 125, 125, 126, 126,
12674 		126, 127, 127, 128, 128, 128, 129, 129,
12675 		130, 130, 130, 131, 131, 131, 132, 132,
12676 		133, 133, 133, 134, 134, 134, 135, 135,
12677 		136, 136, 136, 137, 137, 137, 138, 138,
12678 		138, 139, 139, 140, 140, 140, 141, 141,
12679 		141, 142, 142, 142, 143, 143, 143, 144,
12680 		144, 144, 145, 145, 145, 146, 146, 146,
12681 		147, 147, 147, 148, 148, 148, 149, 149,
12682 		150, 150, 150, 150, 151, 151, 151, 152,
12683 		152, 152, 153, 153, 153, 154, 154, 154,
12684 		155, 155, 155, 156, 156, 156, 157, 157,
12685 		157, 158, 158, 158, 159, 159, 159, 160
12686 	};
12687 
12688 	if (x == 0)
12689 		return (0);
12690 	if (x >= 256) {
12691 		unsigned int tmp;
12692 
12693 		for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12694 			/* do nothing */ ;
12695 		return (tmp);
12696 	}
12697 	return (sqrt_table[x - 1] / 10);
12698 }
12699 
12700 static int
12701 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12702 {
12703 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
12704 	int _t;								\
12705 	_t = _x - 20;							\
12706 	if (_t >= 0) {							\
12707 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12708 	} else {							\
12709 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12710 	}								\
12711 } while (0)
12712 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
12713 	int _t;								\
12714 	_t = _x - 11;							\
12715 	if (_t >= 0)							\
12716 		_v = (_y << (31 - _x)) / (_z >> _t);			\
12717 	else								\
12718 		_v = (_y << (31 - _x)) / (_z << -_t);			\
12719 } while (0)
12720 	struct bwn_phy_lp_iq_est ie;
12721 	uint16_t v0, v1;
12722 	int tmp[2], ret;
12723 
12724 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12725 	v0 = v1 >> 8;
12726 	v1 |= 0xff;
12727 
12728 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12729 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12730 
12731 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12732 	if (ret == 0)
12733 		goto done;
12734 
12735 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12736 		ret = 0;
12737 		goto done;
12738 	}
12739 
12740 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12741 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12742 
12743 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12744 	v0 = tmp[0] >> 3;
12745 	v1 = tmp[1] >> 4;
12746 done:
12747 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12748 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12749 	return ret;
12750 #undef CALC_COEFF
12751 #undef CALC_COEFF2
12752 }
12753 
12754 static void
12755 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12756 {
12757 	static const uint16_t noisescale[] = {
12758 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12759 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12760 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12761 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12762 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12763 	};
12764 	static const uint16_t crsgainnft[] = {
12765 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12766 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12767 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12768 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12769 		0x013d,
12770 	};
12771 	static const uint16_t filterctl[] = {
12772 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12773 		0xff53, 0x0127,
12774 	};
12775 	static const uint32_t psctl[] = {
12776 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12777 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12778 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12779 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12780 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12781 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12782 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12783 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12784 	};
12785 	static const uint16_t ofdmcckgain_r0[] = {
12786 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12787 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12788 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12789 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12790 		0x755d,
12791 	};
12792 	static const uint16_t ofdmcckgain_r1[] = {
12793 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12794 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12795 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12796 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12797 		0x755d,
12798 	};
12799 	static const uint16_t gaindelta[] = {
12800 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12801 		0x0000,
12802 	};
12803 	static const uint32_t txpwrctl[] = {
12804 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12805 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12806 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12807 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12808 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12809 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12810 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12811 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12812 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12813 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12814 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12815 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12816 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12817 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12818 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12819 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12820 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12821 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12822 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12823 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12824 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12825 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12826 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12827 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12828 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12829 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12830 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12831 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12832 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12833 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12834 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12835 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12836 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12837 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12838 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12839 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12840 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12841 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12842 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12843 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12844 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12845 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12846 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12847 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12848 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12849 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12850 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12851 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12852 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12853 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12854 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12855 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12856 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12857 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12858 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12859 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12860 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12861 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12862 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12863 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12864 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12865 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12866 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12867 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12868 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12869 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12870 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12871 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12872 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12873 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12874 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12875 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12876 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12877 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12878 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12879 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12880 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12881 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12882 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12883 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12884 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12885 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12886 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12887 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12888 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12889 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12890 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12891 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12892 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12893 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12894 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12895 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12896 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12897 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12898 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12899 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12900 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12901 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12902 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12903 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12904 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12905 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12906 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12907 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12908 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12909 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12910 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12911 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12912 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12913 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12914 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12915 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12916 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12917 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12918 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12919 		0x00000702,
12920 	};
12921 
12922 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12923 
12924 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12925 	    bwn_tab_sigsq_tbl);
12926 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12927 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12928 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12929 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12930 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12931 	    bwn_tab_pllfrac_tbl);
12932 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12933 	    bwn_tabl_iqlocal_tbl);
12934 	if (mac->mac_phy.rev == 0) {
12935 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12936 		    ofdmcckgain_r0);
12937 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12938 		    ofdmcckgain_r0);
12939 	} else {
12940 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12941 		    ofdmcckgain_r1);
12942 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12943 		    ofdmcckgain_r1);
12944 	}
12945 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12946 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12947 }
12948 
12949 static void
12950 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12951 {
12952 	struct bwn_softc *sc = mac->mac_sc;
12953 	int i;
12954 	static const uint16_t noisescale[] = {
12955 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12956 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12957 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12958 		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12959 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12960 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12961 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12962 	};
12963 	static const uint32_t filterctl[] = {
12964 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12965 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12966 	};
12967 	static const uint32_t psctl[] = {
12968 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12969 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12970 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12971 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12972 	};
12973 	static const uint32_t gainidx[] = {
12974 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12975 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12976 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12977 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12978 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12979 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12980 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12981 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12982 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12983 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12984 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12985 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12986 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12987 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12988 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12989 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12990 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12992 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12993 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12994 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12995 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12996 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
12997 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
12998 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
12999 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13000 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13001 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13002 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13003 		0x0000001a, 0x64ca55ad, 0x0000001a
13004 	};
13005 	static const uint16_t auxgainidx[] = {
13006 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13007 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13008 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13009 		0x0004, 0x0016
13010 	};
13011 	static const uint16_t swctl[] = {
13012 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13013 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13014 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13015 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13016 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13017 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13018 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13019 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13020 	};
13021 	static const uint8_t hf[] = {
13022 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13023 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13024 	};
13025 	static const uint32_t gainval[] = {
13026 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13027 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13028 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13029 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13030 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13031 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13032 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13033 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13034 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13035 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13036 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13037 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13038 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13039 		0x000000f1, 0x00000000, 0x00000000
13040 	};
13041 	static const uint16_t gain[] = {
13042 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13043 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13044 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13045 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13046 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13047 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13048 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13049 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13050 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13051 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13052 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13053 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13054 	};
13055 	static const uint32_t papdeps[] = {
13056 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13057 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13058 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13059 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13060 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13061 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13062 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13063 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13064 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13065 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13066 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13067 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13068 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13069 	};
13070 	static const uint32_t papdmult[] = {
13071 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13072 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13073 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13074 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13075 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13076 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13077 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13078 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13079 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13080 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13081 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13082 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13083 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13084 	};
13085 	static const uint32_t gainidx_a0[] = {
13086 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13087 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13088 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13089 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13090 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13091 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13092 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13093 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13094 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13095 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13096 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13097 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13098 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13099 	};
13100 	static const uint16_t auxgainidx_a0[] = {
13101 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13102 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13103 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13104 		0x0002, 0x0014
13105 	};
13106 	static const uint32_t gainval_a0[] = {
13107 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13108 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13109 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13110 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13111 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13112 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13113 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13114 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13115 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13116 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13117 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13118 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13119 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13120 		0x000000f7, 0x00000000, 0x00000000
13121 	};
13122 	static const uint16_t gain_a0[] = {
13123 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13124 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13125 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13126 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13127 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13128 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13129 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13130 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13131 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13132 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13133 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13134 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13135 	};
13136 
13137 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13138 
13139 	for (i = 0; i < 704; i++)
13140 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13141 
13142 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13143 	    bwn_tab_sigsq_tbl);
13144 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13145 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13146 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13147 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13148 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13149 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13150 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13151 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13152 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13153 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13154 	    bwn_tab_pllfrac_tbl);
13155 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13156 	    bwn_tabl_iqlocal_tbl);
13157 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13158 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13159 
13160 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13161 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
13162 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13163 		    gainidx_a0);
13164 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13165 		    auxgainidx_a0);
13166 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13167 		    gainval_a0);
13168 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13169 	}
13170 }
13171 
13172 static void
13173 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13174 {
13175 	struct bwn_softc *sc = mac->mac_sc;
13176 	struct ifnet *ifp = sc->sc_ifp;
13177 	struct ieee80211com *ic = ifp->if_l2com;
13178 	static struct bwn_txgain_entry txgain_r2[] = {
13179 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13180 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13181 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13182 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13183 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13184 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13185 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13186 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13187 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13188 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13189 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13190 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13191 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13192 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13193 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13194 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13195 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13196 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13197 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13198 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13199 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13200 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13201 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13202 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13203 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13204 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13205 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13206 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13207 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13208 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13209 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13210 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13211 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13212 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13213 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13214 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13215 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13216 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13217 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13218 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13219 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13220 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13221 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13222 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13223 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13224 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13225 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13226 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13227 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13228 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13229 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13230 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13231 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13232 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13233 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13234 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13235 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13236 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13237 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13238 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13239 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13240 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13241 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13242 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13243 	};
13244 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13245 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13246 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13247 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13248 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13249 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13250 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13251 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13252 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13253 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13254 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13255 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13256 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13257 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13258 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13259 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13260 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13261 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13262 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13263 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13264 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13265 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13266 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13267 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13268 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13269 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13270 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13271 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13272 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13273 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13274 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13275 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13276 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13277 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13278 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13279 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13280 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13281 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13282 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13283 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13284 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13285 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13286 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13287 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13288 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13289 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13290 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13291 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13292 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13293 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13294 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13295 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13296 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13297 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13298 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13299 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13300 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13301 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13302 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13303 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13304 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13305 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13306 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13307 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13308 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13309 	};
13310 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13311 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13312 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13313 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13314 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13315 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13316 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13317 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13318 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13319 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13320 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13321 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13322 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13323 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13324 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13325 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13326 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13327 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13328 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13329 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13330 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13331 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13332 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13333 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13334 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13335 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13336 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13337 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13338 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13339 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13340 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13341 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13342 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13343 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13344 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13345 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13346 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13347 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13348 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13349 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13350 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13351 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13352 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13353 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13354 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13355 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13356 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13357 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13358 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13359 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13360 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13361 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13362 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13363 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13364 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13365 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13366 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13367 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13368 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13369 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13370 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13371 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13372 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13373 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13374 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13375 	};
13376 	static struct bwn_txgain_entry txgain_r0[] = {
13377 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13378 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13379 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13380 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13381 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13382 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13383 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13384 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13385 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13386 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13387 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13388 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13389 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13390 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13391 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13392 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13393 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13394 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13395 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13396 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13397 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13398 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13399 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13400 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13401 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13402 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13403 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13404 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13405 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13406 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13407 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13408 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13409 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13410 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13411 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13412 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13413 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13414 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13415 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13416 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13417 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13418 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13419 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13420 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13421 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13422 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13423 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13424 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13425 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13426 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13427 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13428 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13429 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13430 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13431 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13432 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13433 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13434 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13435 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13436 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13437 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13438 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13439 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13440 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13441 	};
13442 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13443 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13444 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13445 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13446 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13447 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13448 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13449 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13450 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13451 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13452 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13453 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13454 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13455 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13456 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13457 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13458 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13459 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13460 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13461 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13462 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13463 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13464 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13465 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13466 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13467 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13468 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13469 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13470 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13471 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13472 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13473 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13474 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13475 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13476 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13477 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13478 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13479 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13480 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13481 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13482 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13483 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13484 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13485 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13486 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13487 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13488 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13489 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13490 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13491 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13492 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13493 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13494 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13495 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13496 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13497 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13498 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13499 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13500 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13501 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13502 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13503 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13504 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13505 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13506 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13507 	};
13508 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13509 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13510 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13511 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13512 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13513 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13514 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13515 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13516 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13517 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13518 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13519 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13520 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13521 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13522 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13523 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13524 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13525 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13526 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13527 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13528 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13529 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13530 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13531 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13532 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13533 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13534 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13535 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13536 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13537 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13538 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13539 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13540 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13541 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13542 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13543 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13544 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13545 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13546 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13547 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13548 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13549 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13550 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13551 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13552 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13553 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13554 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13555 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13556 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13557 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13558 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13559 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13560 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13561 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13562 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13563 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13564 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13565 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13566 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13567 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13568 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13569 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13570 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13571 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13572 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13573 	};
13574 	static struct bwn_txgain_entry txgain_r1[] = {
13575 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13576 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13577 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13578 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13579 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13580 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13581 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13582 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13583 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13584 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13585 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13586 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13587 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13588 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13589 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13590 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13591 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13592 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13593 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13594 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13595 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13596 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13597 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13598 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13599 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13600 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13601 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13602 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13603 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13604 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13605 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13606 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13607 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13608 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13609 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13610 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13611 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13612 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13613 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13614 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13615 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13616 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13617 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13618 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13619 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13620 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13621 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13622 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13623 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13624 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13625 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13626 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13627 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13628 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13629 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13630 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13631 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13632 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13633 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13634 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13635 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13636 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13637 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13638 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13639 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13640 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13641 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13642 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13643 		{ 7, 11, 6, 0, 71 }
13644 	};
13645 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13646 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13647 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13648 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13649 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13650 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13651 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13652 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13653 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13654 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13655 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13656 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13657 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13658 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13659 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13660 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13661 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13662 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13663 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13664 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13665 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13666 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13667 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13668 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13669 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13670 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13671 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13672 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13673 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13674 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13675 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13676 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13677 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13678 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13679 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13680 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13681 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13682 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13683 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13684 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13685 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13686 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13687 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13688 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13689 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13690 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13691 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13692 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13693 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13694 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13695 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13696 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13697 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13698 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13699 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13700 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13701 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13702 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13703 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13704 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13705 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13706 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13707 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13708 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13709 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13710 	};
13711 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13712 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13713 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13714 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13715 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13716 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13717 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13718 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13719 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13720 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13721 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13722 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13723 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13724 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13725 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13726 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13727 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13728 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13729 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13730 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13731 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13732 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13733 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13734 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13735 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13736 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13737 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13738 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13739 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13740 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13741 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13742 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13743 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13744 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13745 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13746 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13747 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13748 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13749 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13750 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13751 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13752 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13753 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13754 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13755 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13756 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13757 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13758 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13759 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13760 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13761 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13762 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13763 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13764 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13765 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13766 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13767 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13768 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13769 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13770 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13771 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13772 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13773 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13774 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13775 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13776 	};
13777 
13778 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13779 		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13780 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13781 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13782 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13783 			    txgain_2ghz_r2);
13784 		else
13785 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13786 			    txgain_5ghz_r2);
13787 		return;
13788 	}
13789 
13790 	if (mac->mac_phy.rev == 0) {
13791 		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13792 		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13793 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13794 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13795 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13796 			    txgain_2ghz_r0);
13797 		else
13798 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13799 			    txgain_5ghz_r0);
13800 		return;
13801 	}
13802 
13803 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13804 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13805 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13806 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13807 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13808 	else
13809 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13810 }
13811 
13812 static void
13813 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13814 {
13815 	uint32_t offset, type;
13816 
13817 	type = BWN_TAB_GETTYPE(typeoffset);
13818 	offset = BWN_TAB_GETOFFSET(typeoffset);
13819 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13820 
13821 	switch (type) {
13822 	case BWN_TAB_8BIT:
13823 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13824 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13825 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13826 		break;
13827 	case BWN_TAB_16BIT:
13828 		KASSERT(!(value & ~0xffff),
13829 		    ("%s:%d: fail", __func__, __LINE__));
13830 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13831 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13832 		break;
13833 	case BWN_TAB_32BIT:
13834 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13835 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13836 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13837 		break;
13838 	default:
13839 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13840 	}
13841 }
13842 
13843 static int
13844 bwn_phy_lp_loopback(struct bwn_mac *mac)
13845 {
13846 	struct bwn_phy_lp_iq_est ie;
13847 	int i, index = -1;
13848 	uint32_t tmp;
13849 
13850 	memset(&ie, 0, sizeof(ie));
13851 
13852 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
13853 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13854 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13855 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13856 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13857 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13858 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13859 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13860 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13861 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13862 	for (i = 0; i < 32; i++) {
13863 		bwn_phy_lp_set_rxgain_idx(mac, i);
13864 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13865 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13866 			continue;
13867 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13868 		if ((tmp > 4000) && (tmp < 10000)) {
13869 			index = i;
13870 			break;
13871 		}
13872 	}
13873 	bwn_phy_lp_ddfs_turnoff(mac);
13874 	return (index);
13875 }
13876 
13877 static void
13878 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13879 {
13880 
13881 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13882 }
13883 
13884 static void
13885 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13886     int incr1, int incr2, int scale_idx)
13887 {
13888 
13889 	bwn_phy_lp_ddfs_turnoff(mac);
13890 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13891 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13892 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13893 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13894 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13895 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13896 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13897 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13898 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13899 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13900 }
13901 
13902 static uint8_t
13903 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13904     struct bwn_phy_lp_iq_est *ie)
13905 {
13906 	int i;
13907 
13908 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13909 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13910 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13911 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13912 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13913 
13914 	for (i = 0; i < 500; i++) {
13915 		if (!(BWN_PHY_READ(mac,
13916 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13917 			break;
13918 		DELAY(1000);
13919 	}
13920 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13921 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13922 		return 0;
13923 	}
13924 
13925 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13926 	ie->ie_iqprod <<= 16;
13927 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13928 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13929 	ie->ie_ipwr <<= 16;
13930 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13931 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13932 	ie->ie_qpwr <<= 16;
13933 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13934 
13935 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13936 	return 1;
13937 }
13938 
13939 static uint32_t
13940 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13941 {
13942 	uint32_t offset, type, value;
13943 
13944 	type = BWN_TAB_GETTYPE(typeoffset);
13945 	offset = BWN_TAB_GETOFFSET(typeoffset);
13946 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13947 
13948 	switch (type) {
13949 	case BWN_TAB_8BIT:
13950 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13951 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13952 		break;
13953 	case BWN_TAB_16BIT:
13954 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13955 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13956 		break;
13957 	case BWN_TAB_32BIT:
13958 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13959 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13960 		value <<= 16;
13961 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13962 		break;
13963 	default:
13964 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13965 		value = 0;
13966 	}
13967 
13968 	return (value);
13969 }
13970 
13971 static void
13972 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13973 {
13974 
13975 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13976 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13977 }
13978 
13979 static void
13980 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13981 {
13982 	uint16_t ctl;
13983 
13984 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13985 	ctl |= dac << 7;
13986 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13987 }
13988 
13989 static void
13990 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13991 {
13992 
13993 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13994 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13995 }
13996 
13997 static void
13998 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
13999 {
14000 
14001 	if (mac->mac_phy.rev < 2)
14002 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14003 	else {
14004 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14005 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14006 	}
14007 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14008 }
14009 
14010 static uint16_t
14011 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14012 {
14013 
14014 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14015 }
14016 
14017 static uint8_t
14018 bwn_nbits(int32_t val)
14019 {
14020 	uint32_t tmp;
14021 	uint8_t nbits = 0;
14022 
14023 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
14024 		nbits++;
14025 	return (nbits);
14026 }
14027 
14028 static void
14029 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14030     struct bwn_txgain_entry *table)
14031 {
14032 	int i;
14033 
14034 	for (i = offset; i < count; i++)
14035 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14036 }
14037 
14038 static void
14039 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14040     struct bwn_txgain_entry data)
14041 {
14042 
14043 	if (mac->mac_phy.rev >= 2)
14044 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14045 	else
14046 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14047 }
14048 
14049 static void
14050 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14051     struct bwn_txgain_entry te)
14052 {
14053 	struct bwn_softc *sc = mac->mac_sc;
14054 	struct ifnet *ifp = sc->sc_ifp;
14055 	struct ieee80211com *ic = ifp->if_l2com;
14056 	uint32_t tmp;
14057 
14058 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14059 
14060 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14061 	if (mac->mac_phy.rev >= 3) {
14062 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14063 		    (0x10 << 24) : (0x70 << 24));
14064 	} else {
14065 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14066 		    (0x14 << 24) : (0x7f << 24));
14067 	}
14068 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14069 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14070 	    te.te_bbmult << 20 | te.te_dac << 28);
14071 }
14072 
14073 static void
14074 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14075     struct bwn_txgain_entry te)
14076 {
14077 
14078 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14079 
14080 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14081 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14082 	    te.te_dac);
14083 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14084 }
14085 
14086 static void
14087 bwn_sysctl_node(struct bwn_softc *sc)
14088 {
14089 	struct bwn_mac *mac;
14090 	struct bwn_stats *stats;
14091 	struct sysctl_ctx_list *ctx;
14092 	struct sysctl_oid *tree;
14093 
14094 	/* XXX assume that count of MAC is only 1. */
14095 
14096 	if ((mac = sc->sc_curmac) == NULL)
14097 		return;
14098 	stats = &mac->mac_stats;
14099 
14100 	ctx = device_get_sysctl_ctx(sc->sc_dev);
14101 	tree = device_get_sysctl_tree(sc->sc_dev);
14102 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14103 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14104 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14105 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14106 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14107 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14108 
14109 #ifdef BWN_DEBUG
14110 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14111 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14112 #endif
14113 }
14114 
14115 static device_method_t bwn_methods[] = {
14116 	/* Device interface */
14117 	DEVMETHOD(device_probe,		bwn_probe),
14118 	DEVMETHOD(device_attach,	bwn_attach),
14119 	DEVMETHOD(device_detach,	bwn_detach),
14120 	DEVMETHOD(device_suspend,	bwn_suspend),
14121 	DEVMETHOD(device_resume,	bwn_resume),
14122 	DEVMETHOD_END
14123 };
14124 static driver_t bwn_driver = {
14125 	"bwn",
14126 	bwn_methods,
14127 	sizeof(struct bwn_softc)
14128 };
14129 static devclass_t bwn_devclass;
14130 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL);
14131 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14132 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
14133 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
14134 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
14135