xref: /dragonfly/sys/dev/netif/bwn/bwn/if_bwn.c (revision 0ca59c34)
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 ifnet *);
187 static void	bwn_update_promisc(struct ifnet *);
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 	/* XXX not right but it's not used anywhere important */
1036 	ic->ic_phytype = IEEE80211_T_OFDM;
1037 	ic->ic_opmode = IEEE80211_M_STA;
1038 	ic->ic_caps =
1039 		  IEEE80211_C_STA		/* station mode supported */
1040 		| IEEE80211_C_MONITOR		/* monitor mode */
1041 		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
1042 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
1043 		| IEEE80211_C_SHSLOT		/* short slot time supported */
1044 		| IEEE80211_C_WME		/* WME/WMM supported */
1045 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
1046 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
1047 		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
1048 		;
1049 
1050 	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;	/* s/w bmiss */
1051 
1052 	/* call MI attach routine. */
1053 	ieee80211_ifattach(ic,
1054 	    bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1055 	    siba_sprom_get_mac_80211a(sc->sc_dev) :
1056 	    siba_sprom_get_mac_80211bg(sc->sc_dev));
1057 
1058 	ic->ic_headroom = sizeof(struct bwn_txhdr);
1059 
1060 	/* override default methods */
1061 	ic->ic_raw_xmit = bwn_raw_xmit;
1062 	ic->ic_updateslot = bwn_updateslot;
1063 	ic->ic_update_promisc = bwn_update_promisc;
1064 	ic->ic_wme.wme_update = bwn_wme_update;
1065 
1066 	ic->ic_scan_start = bwn_scan_start;
1067 	ic->ic_scan_end = bwn_scan_end;
1068 	ic->ic_set_channel = bwn_set_channel;
1069 
1070 	ic->ic_vap_create = bwn_vap_create;
1071 	ic->ic_vap_delete = bwn_vap_delete;
1072 
1073 	ieee80211_radiotap_attach(ic,
1074 	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1075 	    BWN_TX_RADIOTAP_PRESENT,
1076 	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1077 	    BWN_RX_RADIOTAP_PRESENT);
1078 
1079 	bwn_sysctl_node(sc);
1080 
1081 	if (bootverbose)
1082 		ieee80211_announce(ic);
1083 	return (0);
1084 }
1085 
1086 static void
1087 bwn_phy_detach(struct bwn_mac *mac)
1088 {
1089 
1090 	if (mac->mac_phy.detach != NULL)
1091 		mac->mac_phy.detach(mac);
1092 }
1093 
1094 static int
1095 bwn_detach(device_t dev)
1096 {
1097 	struct bwn_softc *sc = device_get_softc(dev);
1098 	struct bwn_mac *mac = sc->sc_curmac;
1099 	struct ifnet *ifp = sc->sc_ifp;
1100 	struct ieee80211com *ic = ifp->if_l2com;
1101 
1102 	wlan_serialize_enter();
1103 
1104 	sc->sc_flags |= BWN_FLAG_INVALID;
1105 
1106 	if (device_is_attached(sc->sc_dev)) {
1107 		bwn_stop(sc, 1);
1108 		bwn_dma_free(mac);
1109 		callout_stop_sync(&sc->sc_led_blink_ch);
1110 		callout_stop_sync(&sc->sc_rfswitch_ch);
1111 		callout_stop_sync(&sc->sc_task_ch);
1112 		callout_stop_sync(&sc->sc_watchdog_ch);
1113 		bwn_phy_detach(mac);
1114 		if (ifp != NULL) {
1115 			wlan_serialize_exit();
1116 			ieee80211_draintask(ic, &mac->mac_hwreset);
1117 			ieee80211_draintask(ic, &mac->mac_txpower);
1118 			wlan_serialize_enter();
1119 			ieee80211_ifdetach(ic);
1120 			if_free(ifp);
1121 		}
1122 	}
1123 	wlan_serialize_exit();
1124 	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1125 	taskqueue_free(sc->sc_tq);
1126 	wlan_serialize_enter();
1127 
1128 	if (sc->bwn_intr)
1129 		bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr);
1130 	if (sc->bwn_irq != NULL)
1131 		bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid,
1132 		    sc->bwn_irq);
1133 
1134 	if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1135 		pci_release_msi(dev);
1136 
1137 	wlan_serialize_exit();
1138 	return (0);
1139 }
1140 
1141 static int
1142 bwn_attach_pre(struct bwn_softc *sc)
1143 {
1144 	struct ifnet *ifp;
1145 	int error = 0;
1146 
1147 	TAILQ_INIT(&sc->sc_maclist);
1148 	callout_init(&sc->sc_rfswitch_ch);
1149 	callout_init(&sc->sc_task_ch);
1150 	callout_init(&sc->sc_watchdog_ch);
1151 
1152 	sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK,
1153 		taskqueue_thread_enqueue, &sc->sc_tq);
1154 	taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
1155 		"%s taskq", device_get_nameunit(sc->sc_dev));
1156 
1157 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1158 	if (ifp == NULL) {
1159 		device_printf(sc->sc_dev, "can not if_alloc()\n");
1160 		error = ENOSPC;
1161 		goto fail;
1162 	}
1163 
1164 	/* set these up early for if_printf use */
1165 	if_initname(ifp, device_get_name(sc->sc_dev),
1166 	    device_get_unit(sc->sc_dev));
1167 
1168 	ifp->if_softc = sc;
1169 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1170 	ifp->if_init = bwn_init;
1171 	ifp->if_ioctl = bwn_ioctl;
1172 	ifp->if_start = bwn_start;
1173 	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
1174 
1175 	return (0);
1176 
1177 fail:
1178 	return (error);
1179 }
1180 
1181 static void
1182 bwn_sprom_bugfixes(device_t dev)
1183 {
1184 #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
1185 	((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&		\
1186 	 (siba_get_pci_device(dev) == _device) &&			\
1187 	 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&	\
1188 	 (siba_get_pci_subdevice(dev) == _subdevice))
1189 
1190 	if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1191 	    siba_get_pci_subdevice(dev) == 0x4e &&
1192 	    siba_get_pci_revid(dev) > 0x40)
1193 		siba_sprom_set_bf_lo(dev,
1194 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1195 	if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1196 	    siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1197 		siba_sprom_set_bf_lo(dev,
1198 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1199 	if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1200 		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1201 		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1202 		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1203 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1204 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1205 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1206 		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1207 			siba_sprom_set_bf_lo(dev,
1208 			    siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1209 	}
1210 #undef	BWN_ISDEV
1211 }
1212 
1213 static int
1214 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
1215 	  struct ucred *cr __unused)
1216 {
1217 #define IS_RUNNING(ifp) \
1218         ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1219 	struct bwn_softc *sc = ifp->if_softc;
1220 	struct ieee80211com *ic = ifp->if_l2com;
1221 	struct ifreq *ifr = (struct ifreq *)data;
1222 	int error = 0;
1223 
1224 	switch (cmd) {
1225 	case SIOCSIFFLAGS:
1226 		if (IS_RUNNING(ifp)) {
1227 			bwn_update_promisc(ifp);
1228 		} else if (ifp->if_flags & IFF_UP) {
1229 			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1230 				bwn_init(sc);
1231 			}
1232 		} else
1233 			bwn_stop(sc, 1);
1234 		break;
1235 	case SIOCGIFMEDIA:
1236 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1237 		break;
1238 	case SIOCGIFADDR:
1239 		error = ether_ioctl(ifp, cmd, data);
1240 		break;
1241 	default:
1242 		error = EINVAL;
1243 		break;
1244 	}
1245 	return (error);
1246 }
1247 
1248 static void
1249 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1250 {
1251 	wlan_assert_serialized();
1252 	bwn_start_locked(ifp);
1253 }
1254 
1255 static void
1256 bwn_start_locked(struct ifnet *ifp)
1257 {
1258 	struct bwn_softc *sc = ifp->if_softc;
1259 	struct bwn_mac *mac = sc->sc_curmac;
1260 	struct ieee80211_frame *wh;
1261 	struct ieee80211_node *ni;
1262 	struct ieee80211_key *k;
1263 	struct mbuf *m;
1264 
1265 	wlan_assert_serialized();
1266 
1267 	if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL ||
1268 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
1269 		return;
1270 
1271 	for (;;) {
1272 		m = ifq_dequeue(&ifp->if_snd);	/* XXX: LOCK */
1273 		if (m == NULL)
1274 			break;
1275 
1276 		if (bwn_tx_isfull(sc, m))
1277 			break;
1278 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1279 		if (ni == NULL) {
1280 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
1281 			m_freem(m);
1282 			ifp->if_oerrors++;
1283 			continue;
1284 		}
1285 		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1286 		wh = mtod(m, struct ieee80211_frame *);
1287 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1288 			k = ieee80211_crypto_encap(ni, m);
1289 			if (k == NULL) {
1290 				ieee80211_free_node(ni);
1291 				m_freem(m);
1292 				ifp->if_oerrors++;
1293 				continue;
1294 			}
1295 		}
1296 		wh = NULL;	/* Catch any invalid use */
1297 
1298 		if (bwn_tx_start(sc, ni, m) != 0) {
1299 			if (ni != NULL)
1300 				ieee80211_free_node(ni);
1301 			ifp->if_oerrors++;
1302 			continue;
1303 		}
1304 
1305 		sc->sc_watchdog_timer = 5;
1306 	}
1307 }
1308 
1309 static int
1310 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1311 {
1312 	struct bwn_dma_ring *dr;
1313 	struct bwn_mac *mac = sc->sc_curmac;
1314 	struct bwn_pio_txqueue *tq;
1315 	struct ifnet *ifp = sc->sc_ifp;
1316 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1317 
1318 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1319 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1320 		if (dr->dr_stop == 1 ||
1321 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1322 			dr->dr_stop = 1;
1323 			goto full;
1324 		}
1325 	} else {
1326 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1327 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1328 		    pktlen > (tq->tq_size - tq->tq_used)) {
1329 			tq->tq_stop = 1;
1330 			goto full;
1331 		}
1332 	}
1333 	return (0);
1334 full:
1335 	ifq_prepend(&ifp->if_snd, m);
1336 	ifq_set_oactive(&ifp->if_snd);
1337 	return (1);
1338 }
1339 
1340 static int
1341 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1342 {
1343 	struct bwn_mac *mac = sc->sc_curmac;
1344 	int error;
1345 
1346 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1347 		m_freem(m);
1348 		return (ENXIO);
1349 	}
1350 
1351 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1352 	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1353 	if (error) {
1354 		m_freem(m);
1355 		return (error);
1356 	}
1357 	return (0);
1358 }
1359 
1360 static int
1361 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1362 {
1363 	struct bwn_pio_txpkt *tp;
1364 	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1365 	struct bwn_softc *sc = mac->mac_sc;
1366 	struct bwn_txhdr txhdr;
1367 	struct mbuf *m_new;
1368 	uint32_t ctl32;
1369 	int error;
1370 	uint16_t ctl16;
1371 
1372 	/* XXX TODO send packets after DTIM */
1373 
1374 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1375 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1376 	tp->tp_ni = ni;
1377 	tp->tp_m = m;
1378 
1379 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1380 	if (error) {
1381 		device_printf(sc->sc_dev, "tx fail\n");
1382 		return (error);
1383 	}
1384 
1385 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1386 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1387 	tq->tq_free--;
1388 
1389 	if (siba_get_revid(sc->sc_dev) >= 8) {
1390 		/*
1391 		 * XXX please removes m_defrag(9)
1392 		 */
1393 		m_new = m_defrag(m, M_NOWAIT);
1394 		if (m_new == NULL) {
1395 			device_printf(sc->sc_dev,
1396 			    "%s: can't defrag TX buffer\n",
1397 			    __func__);
1398 			return (ENOBUFS);
1399 		}
1400 		if (m_new->m_next != NULL)
1401 			device_printf(sc->sc_dev,
1402 			    "TODO: fragmented packets for PIO\n");
1403 		tp->tp_m = m_new;
1404 
1405 		/* send HEADER */
1406 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1407 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1408 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1409 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1410 		/* send BODY */
1411 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1412 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1413 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1414 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1415 	} else {
1416 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1417 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1418 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1419 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1420 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1421 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1422 		    ctl16 | BWN_PIO_TXCTL_EOF);
1423 	}
1424 
1425 	return (0);
1426 }
1427 
1428 static struct bwn_pio_txqueue *
1429 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1430 {
1431 
1432 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1433 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1434 
1435 	switch (prio) {
1436 	case 0:
1437 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1438 	case 1:
1439 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1440 	case 2:
1441 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1442 	case 3:
1443 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1444 	}
1445 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1446 	return (NULL);
1447 }
1448 
1449 static int
1450 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1451 {
1452 #define	BWN_GET_TXHDRCACHE(slot)					\
1453 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)])
1454 	struct bwn_dma *dma = &mac->mac_method.dma;
1455 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1456 	struct bwn_dmadesc_generic *desc;
1457 	struct bwn_dmadesc_meta *mt;
1458 	struct bwn_softc *sc = mac->mac_sc;
1459 	struct ifnet *ifp = sc->sc_ifp;
1460 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1461 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1462 
1463 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1464 
1465 	/* XXX send after DTIM */
1466 
1467 	slot = bwn_dma_getslot(dr);
1468 	dr->getdesc(dr, slot, &desc, &mt);
1469 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1470 	    ("%s:%d: fail", __func__, __LINE__));
1471 
1472 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1473 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1474 	    BWN_DMA_COOKIE(dr, slot));
1475 	if (error)
1476 		goto fail;
1477 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1478 	    BUS_DMASYNC_PREWRITE);
1479 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1480 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1481 	    BUS_DMASYNC_PREWRITE);
1482 
1483 	slot = bwn_dma_getslot(dr);
1484 	dr->getdesc(dr, slot, &desc, &mt);
1485 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1486 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1487 	mt->mt_m = m;
1488 	mt->mt_ni = ni;
1489 
1490 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1491 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1492 	if (error && error != EFBIG) {
1493 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1494 		    __func__, error);
1495 		goto fail;
1496 	}
1497 	if (error) {    /* error == EFBIG */
1498 		struct mbuf *m_new;
1499 
1500 		m_new = m_defrag(m, M_NOWAIT);
1501 		if (m_new == NULL) {
1502 			if_printf(ifp, "%s: can't defrag TX buffer\n",
1503 			    __func__);
1504 			error = ENOBUFS;
1505 			goto fail;
1506 		} else {
1507 			m = m_new;
1508 		}
1509 
1510 		mt->mt_m = m;
1511 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1512 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1513 		if (error) {
1514 			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1515 			    __func__, error);
1516 			goto fail;
1517 		}
1518 	}
1519 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1520 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1521 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1522 	    BUS_DMASYNC_PREWRITE);
1523 
1524 	/* XXX send after DTIM */
1525 
1526 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1527 	return (0);
1528 fail:
1529 	dr->dr_curslot = backup[0];
1530 	dr->dr_usedslot = backup[1];
1531 	return (error);
1532 #undef BWN_GET_TXHDRCACHE
1533 }
1534 
1535 static void
1536 bwn_watchdog(void *arg)
1537 {
1538 	struct bwn_softc *sc = arg;
1539 	struct ifnet *ifp = sc->sc_ifp;
1540 
1541 	wlan_serialize_enter();
1542 
1543 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1544 		if_printf(ifp, "device timeout\n");
1545 		ifp->if_oerrors++;
1546 	}
1547 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
1548 	wlan_serialize_exit();
1549 }
1550 
1551 static int
1552 bwn_attach_core(struct bwn_mac *mac)
1553 {
1554 	struct bwn_softc *sc = mac->mac_sc;
1555 	int error, have_bg = 0, have_a = 0;
1556 	uint32_t high;
1557 
1558 	KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1559 	    ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1560 
1561 	siba_powerup(sc->sc_dev, 0);
1562 
1563 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1564 	bwn_reset_core(mac,
1565 	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1566 	error = bwn_phy_getinfo(mac, high);
1567 	if (error)
1568 		goto fail;
1569 
1570 	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1571 	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1572 	if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1573 	    siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1574 	    siba_get_pci_device(sc->sc_dev) != 0x4324) {
1575 		have_a = have_bg = 0;
1576 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1577 			have_a = 1;
1578 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1579 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1580 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1581 			have_bg = 1;
1582 		else
1583 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1584 			    mac->mac_phy.type));
1585 	}
1586 	/* XXX turns off PHY A because it's not supported */
1587 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1588 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1589 		have_a = 0;
1590 		have_bg = 1;
1591 	}
1592 
1593 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1594 		mac->mac_phy.attach = bwn_phy_g_attach;
1595 		mac->mac_phy.detach = bwn_phy_g_detach;
1596 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1597 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1598 		mac->mac_phy.init = bwn_phy_g_init;
1599 		mac->mac_phy.exit = bwn_phy_g_exit;
1600 		mac->mac_phy.phy_read = bwn_phy_g_read;
1601 		mac->mac_phy.phy_write = bwn_phy_g_write;
1602 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1603 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1604 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1605 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1606 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1607 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1608 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1609 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1610 		mac->mac_phy.set_im = bwn_phy_g_im;
1611 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1612 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1613 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1614 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1615 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1616 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1617 		mac->mac_phy.init = bwn_phy_lp_init;
1618 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1619 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1620 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1621 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1622 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1623 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1624 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1625 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1626 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1627 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1628 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1629 	} else {
1630 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1631 		    mac->mac_phy.type);
1632 		error = ENXIO;
1633 		goto fail;
1634 	}
1635 
1636 	mac->mac_phy.gmode = have_bg;
1637 	if (mac->mac_phy.attach != NULL) {
1638 		error = mac->mac_phy.attach(mac);
1639 		if (error) {
1640 			device_printf(sc->sc_dev, "failed\n");
1641 			goto fail;
1642 		}
1643 	}
1644 
1645 	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1646 
1647 	error = bwn_chiptest(mac);
1648 	if (error)
1649 		goto fail;
1650 	error = bwn_setup_channels(mac, have_bg, have_a);
1651 	if (error) {
1652 		device_printf(sc->sc_dev, "failed to setup channels\n");
1653 		goto fail;
1654 	}
1655 
1656 	if (sc->sc_curmac == NULL)
1657 		sc->sc_curmac = mac;
1658 
1659 	wlan_assert_serialized();
1660 	wlan_serialize_exit();
1661 	error = bwn_dma_attach(mac);
1662 	wlan_serialize_enter();
1663 	if (error != 0) {
1664 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1665 		goto fail;
1666 	}
1667 
1668 	mac->mac_phy.switch_analog(mac, 0);
1669 
1670 	siba_dev_down(sc->sc_dev, 0);
1671 fail:
1672 	siba_powerdown(sc->sc_dev);
1673 	return (error);
1674 }
1675 
1676 static void
1677 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1678 {
1679 	struct bwn_softc *sc = mac->mac_sc;
1680 	uint32_t low, ctl;
1681 
1682 	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1683 
1684 	siba_dev_up(sc->sc_dev, flags);
1685 	DELAY(2000);
1686 
1687 	low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1688 	    ~BWN_TGSLOW_PHYRESET;
1689 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1690 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1691 	DELAY(1000);
1692 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1693 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1694 	DELAY(1000);
1695 
1696 	if (mac->mac_phy.switch_analog != NULL)
1697 		mac->mac_phy.switch_analog(mac, 1);
1698 
1699 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1700 	if (flags & BWN_TGSLOW_SUPPORT_G)
1701 		ctl |= BWN_MACCTL_GMODE;
1702 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1703 }
1704 
1705 static int
1706 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1707 {
1708 	struct bwn_phy *phy = &mac->mac_phy;
1709 	struct bwn_softc *sc = mac->mac_sc;
1710 	uint32_t tmp;
1711 
1712 	/* PHY */
1713 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1714 	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1715 	phy->rf_on = 1;
1716 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1717 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1718 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1719 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1720 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1721 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1722 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1723 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1724 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1725 		goto unsupphy;
1726 
1727 	/* RADIO */
1728 	if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1729 		if (siba_get_chiprev(sc->sc_dev) == 0)
1730 			tmp = 0x3205017f;
1731 		else if (siba_get_chiprev(sc->sc_dev) == 1)
1732 			tmp = 0x4205017f;
1733 		else
1734 			tmp = 0x5205017f;
1735 	} else {
1736 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1737 		tmp = BWN_READ_2(mac, BWN_RFDATALO);
1738 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1739 		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1740 	}
1741 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1742 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1743 	phy->rf_manuf = (tmp & 0x00000fff);
1744 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1745 		goto unsupradio;
1746 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1747 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1748 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1749 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1750 	    (phy->type == BWN_PHYTYPE_N &&
1751 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1752 	    (phy->type == BWN_PHYTYPE_LP &&
1753 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1754 		goto unsupradio;
1755 
1756 	return (0);
1757 unsupphy:
1758 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1759 	    "analog %#x)\n",
1760 	    phy->type, phy->rev, phy->analog);
1761 	return (ENXIO);
1762 unsupradio:
1763 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1764 	    "rev %#x)\n",
1765 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1766 	return (ENXIO);
1767 }
1768 
1769 static int
1770 bwn_chiptest(struct bwn_mac *mac)
1771 {
1772 #define	TESTVAL0	0x55aaaa55
1773 #define	TESTVAL1	0xaa5555aa
1774 	struct bwn_softc *sc = mac->mac_sc;
1775 	uint32_t v, backup;
1776 
1777 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1778 
1779 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1780 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1781 		goto error;
1782 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1783 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1784 		goto error;
1785 
1786 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1787 
1788 	if ((siba_get_revid(sc->sc_dev) >= 3) &&
1789 	    (siba_get_revid(sc->sc_dev) <= 10)) {
1790 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1791 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1792 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1793 			goto error;
1794 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1795 			goto error;
1796 	}
1797 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1798 
1799 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1800 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1801 		goto error;
1802 
1803 	return (0);
1804 error:
1805 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1806 	return (ENODEV);
1807 }
1808 
1809 #define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1810 #define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1811 
1812 static int
1813 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1814 {
1815 	struct bwn_softc *sc = mac->mac_sc;
1816 	struct ifnet *ifp = sc->sc_ifp;
1817 	struct ieee80211com *ic = ifp->if_l2com;
1818 
1819 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1820 	ic->ic_nchans = 0;
1821 
1822 	if (have_bg)
1823 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1824 		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1825 	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1826 		if (have_a)
1827 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1828 			    &ic->ic_nchans, &bwn_chantable_n,
1829 			    IEEE80211_CHAN_HTA);
1830 	} else {
1831 		if (have_a)
1832 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1833 			    &ic->ic_nchans, &bwn_chantable_a,
1834 			    IEEE80211_CHAN_A);
1835 	}
1836 
1837 	mac->mac_phy.supports_2ghz = have_bg;
1838 	mac->mac_phy.supports_5ghz = have_a;
1839 
1840 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1841 }
1842 
1843 static uint32_t
1844 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1845 {
1846 	uint32_t ret;
1847 
1848 	if (way == BWN_SHARED) {
1849 		KASSERT((offset & 0x0001) == 0,
1850 		    ("%s:%d warn", __func__, __LINE__));
1851 		if (offset & 0x0003) {
1852 			bwn_shm_ctlword(mac, way, offset >> 2);
1853 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1854 			ret <<= 16;
1855 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1856 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1857 			goto out;
1858 		}
1859 		offset >>= 2;
1860 	}
1861 	bwn_shm_ctlword(mac, way, offset);
1862 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1863 out:
1864 	return (ret);
1865 }
1866 
1867 static uint16_t
1868 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1869 {
1870 	uint16_t ret;
1871 
1872 	if (way == BWN_SHARED) {
1873 		KASSERT((offset & 0x0001) == 0,
1874 		    ("%s:%d warn", __func__, __LINE__));
1875 		if (offset & 0x0003) {
1876 			bwn_shm_ctlword(mac, way, offset >> 2);
1877 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1878 			goto out;
1879 		}
1880 		offset >>= 2;
1881 	}
1882 	bwn_shm_ctlword(mac, way, offset);
1883 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1884 out:
1885 
1886 	return (ret);
1887 }
1888 
1889 static void
1890 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1891     uint16_t offset)
1892 {
1893 	uint32_t control;
1894 
1895 	control = way;
1896 	control <<= 16;
1897 	control |= offset;
1898 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1899 }
1900 
1901 static void
1902 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1903     uint32_t value)
1904 {
1905 	if (way == BWN_SHARED) {
1906 		KASSERT((offset & 0x0001) == 0,
1907 		    ("%s:%d warn", __func__, __LINE__));
1908 		if (offset & 0x0003) {
1909 			bwn_shm_ctlword(mac, way, offset >> 2);
1910 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911 				    (value >> 16) & 0xffff);
1912 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1914 			return;
1915 		}
1916 		offset >>= 2;
1917 	}
1918 	bwn_shm_ctlword(mac, way, offset);
1919 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1920 }
1921 
1922 static void
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1924     uint16_t value)
1925 {
1926 	if (way == BWN_SHARED) {
1927 		KASSERT((offset & 0x0001) == 0,
1928 		    ("%s:%d warn", __func__, __LINE__));
1929 		if (offset & 0x0003) {
1930 			bwn_shm_ctlword(mac, way, offset >> 2);
1931 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1932 			return;
1933 		}
1934 		offset >>= 2;
1935 	}
1936 	bwn_shm_ctlword(mac, way, offset);
1937 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1938 }
1939 
1940 static void
1941 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1942     int txpow)
1943 {
1944 
1945 	c->ic_freq = freq;
1946 	c->ic_flags = flags;
1947 	c->ic_ieee = ieee;
1948 	c->ic_minpower = 0;
1949 	c->ic_maxpower = 2 * txpow;
1950 	c->ic_maxregpower = txpow;
1951 }
1952 
1953 static void
1954 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1955     const struct bwn_channelinfo *ci, int flags)
1956 {
1957 	struct ieee80211_channel *c;
1958 	int i;
1959 
1960 	c = &chans[*nchans];
1961 
1962 	for (i = 0; i < ci->nchannels; i++) {
1963 		const struct bwn_channel *hc;
1964 
1965 		hc = &ci->channels[i];
1966 		if (*nchans >= maxchans)
1967 			break;
1968 		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1969 		c++, (*nchans)++;
1970 		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1971 			/* g channel have a separate b-only entry */
1972 			if (*nchans >= maxchans)
1973 				break;
1974 			c[0] = c[-1];
1975 			c[-1].ic_flags = IEEE80211_CHAN_B;
1976 			c++, (*nchans)++;
1977 		}
1978 		if (flags == IEEE80211_CHAN_HTG) {
1979 			/* HT g channel have a separate g-only entry */
1980 			if (*nchans >= maxchans)
1981 				break;
1982 			c[-1].ic_flags = IEEE80211_CHAN_G;
1983 			c[0] = c[-1];
1984 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1985 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
1986 			c++, (*nchans)++;
1987 		}
1988 		if (flags == IEEE80211_CHAN_HTA) {
1989 			/* HT a channel have a separate a-only entry */
1990 			if (*nchans >= maxchans)
1991 				break;
1992 			c[-1].ic_flags = IEEE80211_CHAN_A;
1993 			c[0] = c[-1];
1994 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1995 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
1996 			c++, (*nchans)++;
1997 		}
1998 	}
1999 }
2000 
2001 static int
2002 bwn_phy_g_attach(struct bwn_mac *mac)
2003 {
2004 	struct bwn_softc *sc = mac->mac_sc;
2005 	struct bwn_phy *phy = &mac->mac_phy;
2006 	struct bwn_phy_g *pg = &phy->phy_g;
2007 	unsigned int i;
2008 	int16_t pab0, pab1, pab2;
2009 	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2010 	int8_t bg;
2011 
2012 	bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2013 	pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2014 	pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2015 	pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2016 
2017 	if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2018 		device_printf(sc->sc_dev, "not supported anymore\n");
2019 
2020 	pg->pg_flags = 0;
2021 	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2022 	    pab2 == -1) {
2023 		pg->pg_idletssi = 52;
2024 		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2025 		return (0);
2026 	}
2027 
2028 	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2029 	pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO);
2030 	for (i = 0; i < 64; i++) {
2031 		int32_t m1, m2, f, q, delta;
2032 		int8_t j = 0;
2033 
2034 		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2035 		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2036 		f = 256;
2037 
2038 		do {
2039 			if (j > 15) {
2040 				device_printf(sc->sc_dev,
2041 				    "failed to generate tssi2dBm\n");
2042 				kfree(pg->pg_tssi2dbm, M_DEVBUF);
2043 				return (ENOMEM);
2044 			}
2045 			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2046 			    f, 2048);
2047 			delta = abs(q - f);
2048 			f = q;
2049 			j++;
2050 		} while (delta >= 2);
2051 
2052 		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2053 		    128);
2054 	}
2055 
2056 	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2057 	return (0);
2058 }
2059 
2060 static void
2061 bwn_phy_g_detach(struct bwn_mac *mac)
2062 {
2063 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2064 
2065 	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2066 		kfree(pg->pg_tssi2dbm, M_DEVBUF);
2067 		pg->pg_tssi2dbm = NULL;
2068 	}
2069 	pg->pg_flags = 0;
2070 }
2071 
2072 static void
2073 bwn_phy_g_init_pre(struct bwn_mac *mac)
2074 {
2075 	struct bwn_phy *phy = &mac->mac_phy;
2076 	struct bwn_phy_g *pg = &phy->phy_g;
2077 	void *tssi2dbm;
2078 	int idletssi;
2079 	unsigned int i;
2080 
2081 	tssi2dbm = pg->pg_tssi2dbm;
2082 	idletssi = pg->pg_idletssi;
2083 
2084 	memset(pg, 0, sizeof(*pg));
2085 
2086 	pg->pg_tssi2dbm = tssi2dbm;
2087 	pg->pg_idletssi = idletssi;
2088 
2089 	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2090 
2091 	for (i = 0; i < N(pg->pg_nrssi); i++)
2092 		pg->pg_nrssi[i] = -1000;
2093 	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2094 		pg->pg_nrssi_lt[i] = i;
2095 	pg->pg_lofcal = 0xffff;
2096 	pg->pg_initval = 0xffff;
2097 	pg->pg_immode = BWN_IMMODE_NONE;
2098 	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2099 	pg->pg_avgtssi = 0xff;
2100 
2101 	pg->pg_loctl.tx_bias = 0xff;
2102 	TAILQ_INIT(&pg->pg_loctl.calib_list);
2103 }
2104 
2105 static int
2106 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2107 {
2108 	struct bwn_phy *phy = &mac->mac_phy;
2109 	struct bwn_phy_g *pg = &phy->phy_g;
2110 	struct bwn_softc *sc = mac->mac_sc;
2111 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2112 	static const struct bwn_rfatt rfatt0[] = {
2113 		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
2114 		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2115 		{ 3, 1 }, { 4, 1 }
2116 	};
2117 	static const struct bwn_rfatt rfatt1[] = {
2118 		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2119 		{ 14, 1 }
2120 	};
2121 	static const struct bwn_rfatt rfatt2[] = {
2122 		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2123 		{ 9, 1 }
2124 	};
2125 	static const struct bwn_bbatt bbatt_0[] = {
2126 		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2127 	};
2128 
2129 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2130 
2131 	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2132 		pg->pg_bbatt.att = 0;
2133 	else
2134 		pg->pg_bbatt.att = 2;
2135 
2136 	/* prepare Radio Attenuation */
2137 	pg->pg_rfatt.padmix = 0;
2138 
2139 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2140 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2141 		if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2142 			pg->pg_rfatt.att = 2;
2143 			goto done;
2144 		} else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2145 			pg->pg_rfatt.att = 3;
2146 			goto done;
2147 		}
2148 	}
2149 
2150 	if (phy->type == BWN_PHYTYPE_A) {
2151 		pg->pg_rfatt.att = 0x60;
2152 		goto done;
2153 	}
2154 
2155 	switch (phy->rf_ver) {
2156 	case 0x2050:
2157 		switch (phy->rf_rev) {
2158 		case 0:
2159 			pg->pg_rfatt.att = 5;
2160 			goto done;
2161 		case 1:
2162 			if (phy->type == BWN_PHYTYPE_G) {
2163 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2164 				    SIBA_BOARDVENDOR_BCM &&
2165 				    siba_get_pci_subdevice(sc->sc_dev) ==
2166 				    SIBA_BOARD_BCM4309G &&
2167 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2168 					pg->pg_rfatt.att = 3;
2169 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2170 				    SIBA_BOARDVENDOR_BCM &&
2171 				    siba_get_pci_subdevice(sc->sc_dev) ==
2172 				    SIBA_BOARD_BU4306)
2173 					pg->pg_rfatt.att = 3;
2174 				else
2175 					pg->pg_rfatt.att = 1;
2176 			} else {
2177 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2178 				    SIBA_BOARDVENDOR_BCM &&
2179 				    siba_get_pci_subdevice(sc->sc_dev) ==
2180 				    SIBA_BOARD_BCM4309G &&
2181 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2182 					pg->pg_rfatt.att = 7;
2183 				else
2184 					pg->pg_rfatt.att = 6;
2185 			}
2186 			goto done;
2187 		case 2:
2188 			if (phy->type == BWN_PHYTYPE_G) {
2189 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2190 				    SIBA_BOARDVENDOR_BCM &&
2191 				    siba_get_pci_subdevice(sc->sc_dev) ==
2192 				    SIBA_BOARD_BCM4309G &&
2193 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2194 					pg->pg_rfatt.att = 3;
2195 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2196 				    SIBA_BOARDVENDOR_BCM &&
2197 				    siba_get_pci_subdevice(sc->sc_dev) ==
2198 				    SIBA_BOARD_BU4306)
2199 					pg->pg_rfatt.att = 5;
2200 				else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2201 					pg->pg_rfatt.att = 4;
2202 				else
2203 					pg->pg_rfatt.att = 3;
2204 			} else
2205 				pg->pg_rfatt.att = 6;
2206 			goto done;
2207 		case 3:
2208 			pg->pg_rfatt.att = 5;
2209 			goto done;
2210 		case 4:
2211 		case 5:
2212 			pg->pg_rfatt.att = 1;
2213 			goto done;
2214 		case 6:
2215 		case 7:
2216 			pg->pg_rfatt.att = 5;
2217 			goto done;
2218 		case 8:
2219 			pg->pg_rfatt.att = 0xa;
2220 			pg->pg_rfatt.padmix = 1;
2221 			goto done;
2222 		case 9:
2223 		default:
2224 			pg->pg_rfatt.att = 5;
2225 			goto done;
2226 		}
2227 		break;
2228 	case 0x2053:
2229 		switch (phy->rf_rev) {
2230 		case 1:
2231 			pg->pg_rfatt.att = 6;
2232 			goto done;
2233 		}
2234 		break;
2235 	}
2236 	pg->pg_rfatt.att = 5;
2237 done:
2238 	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2239 
2240 	if (!bwn_has_hwpctl(mac)) {
2241 		lo->rfatt.array = rfatt0;
2242 		lo->rfatt.len = N(rfatt0);
2243 		lo->rfatt.min = 0;
2244 		lo->rfatt.max = 9;
2245 		goto genbbatt;
2246 	}
2247 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2248 		lo->rfatt.array = rfatt1;
2249 		lo->rfatt.len = N(rfatt1);
2250 		lo->rfatt.min = 0;
2251 		lo->rfatt.max = 14;
2252 		goto genbbatt;
2253 	}
2254 	lo->rfatt.array = rfatt2;
2255 	lo->rfatt.len = N(rfatt2);
2256 	lo->rfatt.min = 0;
2257 	lo->rfatt.max = 9;
2258 genbbatt:
2259 	lo->bbatt.array = bbatt_0;
2260 	lo->bbatt.len = N(bbatt_0);
2261 	lo->bbatt.min = 0;
2262 	lo->bbatt.max = 8;
2263 
2264 	BWN_READ_4(mac, BWN_MACCTL);
2265 	if (phy->rev == 1) {
2266 		phy->gmode = 0;
2267 		bwn_reset_core(mac, 0);
2268 		bwn_phy_g_init_sub(mac);
2269 		phy->gmode = 1;
2270 		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2271 	}
2272 	return (0);
2273 }
2274 
2275 static uint16_t
2276 bwn_phy_g_txctl(struct bwn_mac *mac)
2277 {
2278 	struct bwn_phy *phy = &mac->mac_phy;
2279 
2280 	if (phy->rf_ver != 0x2050)
2281 		return (0);
2282 	if (phy->rf_rev == 1)
2283 		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2284 	if (phy->rf_rev < 6)
2285 		return (BWN_TXCTL_PA2DB);
2286 	if (phy->rf_rev == 8)
2287 		return (BWN_TXCTL_TXMIX);
2288 	return (0);
2289 }
2290 
2291 static int
2292 bwn_phy_g_init(struct bwn_mac *mac)
2293 {
2294 
2295 	bwn_phy_g_init_sub(mac);
2296 	return (0);
2297 }
2298 
2299 static void
2300 bwn_phy_g_exit(struct bwn_mac *mac)
2301 {
2302 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2303 	struct bwn_lo_calib *cal, *tmp;
2304 
2305 	if (lo == NULL)
2306 		return;
2307 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2308 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2309 		kfree(cal, M_DEVBUF);
2310 	}
2311 }
2312 
2313 static uint16_t
2314 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2315 {
2316 
2317 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2318 	return (BWN_READ_2(mac, BWN_PHYDATA));
2319 }
2320 
2321 static void
2322 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2323 {
2324 
2325 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2326 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
2327 }
2328 
2329 static uint16_t
2330 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2331 {
2332 
2333 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2334 	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2335 	return (BWN_READ_2(mac, BWN_RFDATALO));
2336 }
2337 
2338 static void
2339 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2340 {
2341 
2342 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2343 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
2344 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
2345 }
2346 
2347 static int
2348 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2349 {
2350 
2351 	return (mac->mac_phy.rev >= 6);
2352 }
2353 
2354 static void
2355 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2356 {
2357 	struct bwn_phy *phy = &mac->mac_phy;
2358 	struct bwn_phy_g *pg = &phy->phy_g;
2359 	unsigned int channel;
2360 	uint16_t rfover, rfoverval;
2361 
2362 	if (on) {
2363 		if (phy->rf_on)
2364 			return;
2365 
2366 		BWN_PHY_WRITE(mac, 0x15, 0x8000);
2367 		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2368 		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2369 		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2370 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2371 			    pg->pg_radioctx_over);
2372 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2373 			    pg->pg_radioctx_overval);
2374 			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2375 		}
2376 		channel = phy->chan;
2377 		bwn_phy_g_switch_chan(mac, 6, 1);
2378 		bwn_phy_g_switch_chan(mac, channel, 0);
2379 		return;
2380 	}
2381 
2382 	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2383 	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2384 	pg->pg_radioctx_over = rfover;
2385 	pg->pg_radioctx_overval = rfoverval;
2386 	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2387 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2388 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2389 }
2390 
2391 static int
2392 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2393 {
2394 
2395 	if ((newchan < 1) || (newchan > 14))
2396 		return (EINVAL);
2397 	bwn_phy_g_switch_chan(mac, newchan, 0);
2398 
2399 	return (0);
2400 }
2401 
2402 static uint32_t
2403 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2404 {
2405 
2406 	return (1);
2407 }
2408 
2409 static void
2410 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2411 {
2412 	struct bwn_phy *phy = &mac->mac_phy;
2413 	uint64_t hf;
2414 	int autodiv = 0;
2415 	uint16_t tmp;
2416 
2417 	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2418 		autodiv = 1;
2419 
2420 	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2421 	bwn_hf_write(mac, hf);
2422 
2423 	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2424 	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2425 	    ((autodiv ? BWN_ANTAUTO1 : antenna)
2426 		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
2427 
2428 	if (autodiv) {
2429 		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2430 		if (antenna == BWN_ANTAUTO1)
2431 			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2432 		else
2433 			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2434 		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2435 	}
2436 	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2437 	if (autodiv)
2438 		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2439 	else
2440 		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2441 	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2442 	if (phy->rev >= 2) {
2443 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2444 		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2445 		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2446 		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2447 		    0x15);
2448 		if (phy->rev == 2)
2449 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2450 		else
2451 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2452 			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2453 			    8);
2454 	}
2455 	if (phy->rev >= 6)
2456 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2457 
2458 	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2459 	bwn_hf_write(mac, hf);
2460 }
2461 
2462 static int
2463 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2464 {
2465 	struct bwn_phy *phy = &mac->mac_phy;
2466 	struct bwn_phy_g *pg = &phy->phy_g;
2467 
2468 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2469 	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2470 
2471 	if (phy->rev == 0 || !phy->gmode)
2472 		return (ENODEV);
2473 
2474 	pg->pg_aci_wlan_automatic = 0;
2475 	return (0);
2476 }
2477 
2478 static int
2479 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2480 {
2481 	struct bwn_phy *phy = &mac->mac_phy;
2482 	struct bwn_phy_g *pg = &phy->phy_g;
2483 	struct bwn_softc *sc = mac->mac_sc;
2484 	unsigned int tssi;
2485 	int cck, ofdm;
2486 	int power;
2487 	int rfatt, bbatt;
2488 	unsigned int max;
2489 
2490 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2491 
2492 	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2493 	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2494 	if (cck < 0 && ofdm < 0) {
2495 		if (ignore_tssi == 0)
2496 			return (BWN_TXPWR_RES_DONE);
2497 		cck = 0;
2498 		ofdm = 0;
2499 	}
2500 	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2501 	if (pg->pg_avgtssi != 0xff)
2502 		tssi = (tssi + pg->pg_avgtssi) / 2;
2503 	pg->pg_avgtssi = tssi;
2504 	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2505 
2506 	max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2507 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2508 		max -= 3;
2509 	if (max >= 120) {
2510 		device_printf(sc->sc_dev, "invalid max TX-power value\n");
2511 		max = 80;
2512 		siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2513 	}
2514 
2515 	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2516 	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2517 	     tssi, 0x00), 0x3f)]);
2518 	if (power == 0)
2519 		return (BWN_TXPWR_RES_DONE);
2520 
2521 	rfatt = -((power + 7) / 8);
2522 	bbatt = (-(power / 2)) - (4 * rfatt);
2523 	if ((rfatt == 0) && (bbatt == 0))
2524 		return (BWN_TXPWR_RES_DONE);
2525 	pg->pg_bbatt_delta = bbatt;
2526 	pg->pg_rfatt_delta = rfatt;
2527 	return (BWN_TXPWR_RES_NEED_ADJUST);
2528 }
2529 
2530 static void
2531 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2532 {
2533 	struct bwn_phy *phy = &mac->mac_phy;
2534 	struct bwn_phy_g *pg = &phy->phy_g;
2535 	struct bwn_softc *sc = mac->mac_sc;
2536 	int rfatt, bbatt;
2537 	uint8_t txctl;
2538 
2539 	bwn_mac_suspend(mac);
2540 
2541 	bbatt = pg->pg_bbatt.att;
2542 	bbatt += pg->pg_bbatt_delta;
2543 	rfatt = pg->pg_rfatt.att;
2544 	rfatt += pg->pg_rfatt_delta;
2545 
2546 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2547 	txctl = pg->pg_txctl;
2548 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2549 		if (rfatt <= 1) {
2550 			if (txctl == 0) {
2551 				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2552 				rfatt += 2;
2553 				bbatt += 2;
2554 			} else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2555 			    BWN_BFL_PACTRL) {
2556 				bbatt += 4 * (rfatt - 2);
2557 				rfatt = 2;
2558 			}
2559 		} else if (rfatt > 4 && txctl) {
2560 			txctl = 0;
2561 			if (bbatt < 3) {
2562 				rfatt -= 3;
2563 				bbatt += 2;
2564 			} else {
2565 				rfatt -= 2;
2566 				bbatt -= 2;
2567 			}
2568 		}
2569 	}
2570 	pg->pg_txctl = txctl;
2571 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2572 	pg->pg_rfatt.att = rfatt;
2573 	pg->pg_bbatt.att = bbatt;
2574 
2575 	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2576 
2577 	bwn_phy_lock(mac);
2578 	bwn_rf_lock(mac);
2579 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2580 	    pg->pg_txctl);
2581 	bwn_rf_unlock(mac);
2582 	bwn_phy_unlock(mac);
2583 
2584 	bwn_mac_enable(mac);
2585 }
2586 
2587 static void
2588 bwn_phy_g_task_15s(struct bwn_mac *mac)
2589 {
2590 	struct bwn_phy *phy = &mac->mac_phy;
2591 	struct bwn_phy_g *pg = &phy->phy_g;
2592 	struct bwn_softc *sc = mac->mac_sc;
2593 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2594 	unsigned long expire, now;
2595 	struct bwn_lo_calib *cal, *tmp;
2596 	uint8_t expired = 0;
2597 
2598 	bwn_mac_suspend(mac);
2599 
2600 	if (lo == NULL)
2601 		goto fail;
2602 
2603 	BWN_GETTIME(now);
2604 	if (bwn_has_hwpctl(mac)) {
2605 		expire = now - BWN_LO_PWRVEC_EXPIRE;
2606 		if (time_before(lo->pwr_vec_read_time, expire)) {
2607 			bwn_lo_get_powervector(mac);
2608 			bwn_phy_g_dc_lookup_init(mac, 0);
2609 		}
2610 		goto fail;
2611 	}
2612 
2613 	expire = now - BWN_LO_CALIB_EXPIRE;
2614 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2615 		if (!time_before(cal->calib_time, expire))
2616 			continue;
2617 		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2618 		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2619 			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2620 			expired = 1;
2621 		}
2622 
2623 		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2624 		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2625 		    cal->ctl.i, cal->ctl.q);
2626 
2627 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2628 		kfree(cal, M_DEVBUF);
2629 	}
2630 	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2631 		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2632 		    &pg->pg_rfatt);
2633 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
2634 			device_printf(sc->sc_dev,
2635 			    "failed to recalibrate LO\n");
2636 			goto fail;
2637 		}
2638 		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2639 		bwn_lo_write(mac, &cal->ctl);
2640 	}
2641 
2642 fail:
2643 	bwn_mac_enable(mac);
2644 }
2645 
2646 static void
2647 bwn_phy_g_task_60s(struct bwn_mac *mac)
2648 {
2649 	struct bwn_phy *phy = &mac->mac_phy;
2650 	struct bwn_softc *sc = mac->mac_sc;
2651 	uint8_t old = phy->chan;
2652 
2653 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2654 		return;
2655 
2656 	bwn_mac_suspend(mac);
2657 	bwn_nrssi_slope_11g(mac);
2658 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2659 		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2660 		bwn_switch_channel(mac, old);
2661 	}
2662 	bwn_mac_enable(mac);
2663 }
2664 
2665 static void
2666 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2667 {
2668 
2669 	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2670 }
2671 
2672 static int
2673 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2674 	const struct ieee80211_bpf_params *params)
2675 {
2676 	struct ieee80211com *ic = ni->ni_ic;
2677 	struct ifnet *ifp = ic->ic_ifp;
2678 	struct bwn_softc *sc = ifp->if_softc;
2679 	struct bwn_mac *mac = sc->sc_curmac;
2680 
2681 	if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2682 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
2683 		ieee80211_free_node(ni);
2684 		m_freem(m);
2685 		return (ENETDOWN);
2686 	}
2687 
2688 	if (bwn_tx_isfull(sc, m)) {
2689 		ieee80211_free_node(ni);
2690 		m_freem(m);
2691 		ifp->if_oerrors++;
2692 		return (ENOBUFS);
2693 	}
2694 
2695 	if (bwn_tx_start(sc, ni, m) != 0) {
2696 		if (ni != NULL)
2697 			ieee80211_free_node(ni);
2698 		ifp->if_oerrors++;
2699 	}
2700 	sc->sc_watchdog_timer = 5;
2701 	return (0);
2702 }
2703 
2704 /*
2705  * Callback from the 802.11 layer to update the slot time
2706  * based on the current setting.  We use it to notify the
2707  * firmware of ERP changes and the f/w takes care of things
2708  * like slot time and preamble.
2709  */
2710 static void
2711 bwn_updateslot(struct ifnet *ifp)
2712 {
2713 	struct bwn_softc *sc = ifp->if_softc;
2714 	struct ieee80211com *ic = ifp->if_l2com;
2715 	struct bwn_mac *mac;
2716 
2717 	if (ifp->if_flags & IFF_RUNNING) {
2718 		mac = (struct bwn_mac *)sc->sc_curmac;
2719 		bwn_set_slot_time(mac,
2720 		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2721 	}
2722 }
2723 
2724 /*
2725  * Callback from the 802.11 layer after a promiscuous mode change.
2726  * Note this interface does not check the operating mode as this
2727  * is an internal callback and we are expected to honor the current
2728  * state (e.g. this is used for setting the interface in promiscuous
2729  * mode when operating in hostap mode to do ACS).
2730  */
2731 static void
2732 bwn_update_promisc(struct ifnet *ifp)
2733 {
2734 	struct bwn_softc *sc = ifp->if_softc;
2735 	struct bwn_mac *mac = sc->sc_curmac;
2736 
2737 	mac = sc->sc_curmac;
2738 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2739 		if (ifp->if_flags & IFF_PROMISC)
2740 			sc->sc_filters |= BWN_MACCTL_PROMISC;
2741 		else
2742 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2743 		bwn_set_opmode(mac);
2744 	}
2745 }
2746 
2747 /*
2748  * Callback from the 802.11 layer to update WME parameters.
2749  */
2750 static int
2751 bwn_wme_update(struct ieee80211com *ic)
2752 {
2753 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2754 	struct bwn_mac *mac = sc->sc_curmac;
2755 	struct wmeParams *wmep;
2756 	int i;
2757 
2758 	mac = sc->sc_curmac;
2759 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2760 		bwn_mac_suspend(mac);
2761 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
2762 			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2763 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2764 		}
2765 		bwn_mac_enable(mac);
2766 	}
2767 	return (0);
2768 }
2769 
2770 static void
2771 bwn_scan_start(struct ieee80211com *ic)
2772 {
2773 	struct ifnet *ifp = ic->ic_ifp;
2774 	struct bwn_softc *sc = ifp->if_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 ifnet *ifp = ic->ic_ifp;
2790 	struct bwn_softc *sc = ifp->if_softc;
2791 	struct bwn_mac *mac;
2792 
2793 	mac = sc->sc_curmac;
2794 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2795 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2796 		bwn_set_opmode(mac);
2797 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2798 	}
2799 }
2800 
2801 static void
2802 bwn_set_channel(struct ieee80211com *ic)
2803 {
2804 	struct ifnet *ifp = ic->ic_ifp;
2805 	struct bwn_softc *sc = ifp->if_softc;
2806 	struct bwn_mac *mac = sc->sc_curmac;
2807 	struct bwn_phy *phy = &mac->mac_phy;
2808 	int chan, error;
2809 
2810 	error = bwn_switch_band(sc, ic->ic_curchan);
2811 	if (error)
2812 		goto fail;
2813 	bwn_mac_suspend(mac);
2814 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2815 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2816 	if (chan != phy->chan)
2817 		bwn_switch_channel(mac, chan);
2818 
2819 	/* TX power level */
2820 	if (ic->ic_curchan->ic_maxpower != 0 &&
2821 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
2822 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2823 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2824 		    BWN_TXPWR_IGNORE_TSSI);
2825 	}
2826 
2827 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2828 	if (phy->set_antenna)
2829 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2830 
2831 	if (sc->sc_rf_enabled != phy->rf_on) {
2832 		if (sc->sc_rf_enabled) {
2833 			bwn_rf_turnon(mac);
2834 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2835 				device_printf(sc->sc_dev,
2836 				    "please turn on the RF switch\n");
2837 		} else
2838 			bwn_rf_turnoff(mac);
2839 	}
2840 
2841 	bwn_mac_enable(mac);
2842 
2843 fail:
2844 	/*
2845 	 * Setup radio tap channel freq and flags
2846 	 */
2847 	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2848 		htole16(ic->ic_curchan->ic_freq);
2849 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2850 		htole16(ic->ic_curchan->ic_flags & 0xffff);
2851 }
2852 
2853 static struct ieee80211vap *
2854 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2855     enum ieee80211_opmode opmode, int flags,
2856     const uint8_t bssid[IEEE80211_ADDR_LEN],
2857     const uint8_t mac0[IEEE80211_ADDR_LEN])
2858 {
2859 	struct ifnet *ifp = ic->ic_ifp;
2860 	struct bwn_softc *sc = ifp->if_softc;
2861 	struct ieee80211vap *vap;
2862 	struct bwn_vap *bvp;
2863 	uint8_t mac[IEEE80211_ADDR_LEN];
2864 
2865 	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
2866 		return NULL;
2867 
2868 	IEEE80211_ADDR_COPY(mac, mac0);
2869 	switch (opmode) {
2870 	case IEEE80211_M_HOSTAP:
2871 	case IEEE80211_M_MBSS:
2872 	case IEEE80211_M_STA:
2873 	case IEEE80211_M_WDS:
2874 	case IEEE80211_M_MONITOR:
2875 	case IEEE80211_M_IBSS:
2876 	case IEEE80211_M_AHDEMO:
2877 		break;
2878 	default:
2879 		return (NULL);
2880 	}
2881 
2882 	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2883 
2884 	bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap),
2885 	    M_80211_VAP, M_INTWAIT | M_ZERO);
2886 	vap = &bvp->bv_vap;
2887 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2888 	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2889 	/* override with driver methods */
2890 	bvp->bv_newstate = vap->iv_newstate;
2891 	vap->iv_newstate = bwn_newstate;
2892 
2893 	/* override max aid so sta's cannot assoc when we're out of sta id's */
2894 	vap->iv_max_aid = BWN_STAID_MAX;
2895 
2896 	ieee80211_ratectl_init(vap);
2897 
2898 	/* complete setup */
2899 	ieee80211_vap_attach(vap, ieee80211_media_change,
2900 	    ieee80211_media_status);
2901 	ic->ic_opmode = opmode;
2902 	return (vap);
2903 }
2904 
2905 static void
2906 bwn_vap_delete(struct ieee80211vap *vap)
2907 {
2908 	struct bwn_vap *bvp = BWN_VAP(vap);
2909 
2910 	ieee80211_ratectl_deinit(vap);
2911 	ieee80211_vap_detach(vap);
2912 	kfree(bvp, M_80211_VAP);
2913 }
2914 
2915 static void
2916 bwn_init(void *arg)
2917 {
2918 	struct bwn_softc *sc = arg;
2919 	struct ifnet *ifp = sc->sc_ifp;
2920 	struct ieee80211com *ic = ifp->if_l2com;
2921 	int error = 0;
2922 
2923 	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2924 		__func__, ifp->if_flags);
2925 
2926 	wlan_assert_serialized();
2927 	error = bwn_init_locked(sc);
2928 
2929 	if (error == 0)
2930 		ieee80211_start_all(ic);	/* start all vap's */
2931 }
2932 
2933 static int
2934 bwn_init_locked(struct bwn_softc *sc)
2935 {
2936 	struct bwn_mac *mac;
2937 	struct ifnet *ifp = sc->sc_ifp;
2938 	int error;
2939 
2940 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2941 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2942 	sc->sc_filters = 0;
2943 	bwn_wme_clear(sc);
2944 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2945 	sc->sc_rf_enabled = 1;
2946 
2947 	mac = sc->sc_curmac;
2948 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2949 		error = bwn_core_init(mac);
2950 		if (error != 0)
2951 			return (error);
2952 	}
2953 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
2954 		bwn_core_start(mac);
2955 
2956 	bwn_set_opmode(mac);
2957 	bwn_set_pretbtt(mac);
2958 	bwn_spu_setdelay(mac, 0);
2959 	bwn_set_macaddr(mac);
2960 
2961 	ifp->if_flags |= IFF_RUNNING;
2962 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2963 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2964 
2965 	return (0);
2966 }
2967 
2968 static void
2969 bwn_stop(struct bwn_softc *sc, int statechg)
2970 {
2971 
2972 	wlan_assert_serialized();
2973 	bwn_stop_locked(sc, statechg);
2974 }
2975 
2976 static void
2977 bwn_stop_locked(struct bwn_softc *sc, int statechg)
2978 {
2979 	struct bwn_mac *mac = sc->sc_curmac;
2980 	struct ifnet *ifp = sc->sc_ifp;
2981 
2982 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2983 		/* XXX FIXME opmode not based on VAP */
2984 		bwn_set_opmode(mac);
2985 		bwn_set_macaddr(mac);
2986 	}
2987 
2988 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2989 		bwn_core_stop(mac);
2990 
2991 	callout_stop(&sc->sc_led_blink_ch);
2992 	sc->sc_led_blinking = 0;
2993 
2994 	bwn_core_exit(mac);
2995 	sc->sc_rf_enabled = 0;
2996 
2997 	ifp->if_flags &= ~IFF_RUNNING;
2998 	ifq_clr_oactive(&ifp->if_snd);
2999 }
3000 
3001 static void
3002 bwn_wme_clear(struct bwn_softc *sc)
3003 {
3004 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
3005 	struct wmeParams *p;
3006 	unsigned int i;
3007 
3008 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3009 	    ("%s:%d: fail", __func__, __LINE__));
3010 
3011 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
3012 		p = &(sc->sc_wmeParams[i]);
3013 
3014 		switch (bwn_wme_shm_offsets[i]) {
3015 		case BWN_WME_VOICE:
3016 			p->wmep_txopLimit = 0;
3017 			p->wmep_aifsn = 2;
3018 			/* XXX FIXME: log2(cwmin) */
3019 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3020 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3021 			break;
3022 		case BWN_WME_VIDEO:
3023 			p->wmep_txopLimit = 0;
3024 			p->wmep_aifsn = 2;
3025 			/* XXX FIXME: log2(cwmin) */
3026 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3027 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3028 			break;
3029 		case BWN_WME_BESTEFFORT:
3030 			p->wmep_txopLimit = 0;
3031 			p->wmep_aifsn = 3;
3032 			/* XXX FIXME: log2(cwmin) */
3033 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3034 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3035 			break;
3036 		case BWN_WME_BACKGROUND:
3037 			p->wmep_txopLimit = 0;
3038 			p->wmep_aifsn = 7;
3039 			/* XXX FIXME: log2(cwmin) */
3040 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3041 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3042 			break;
3043 		default:
3044 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3045 		}
3046 	}
3047 }
3048 
3049 static int
3050 bwn_core_init(struct bwn_mac *mac)
3051 {
3052 	struct bwn_softc *sc = mac->mac_sc;
3053 	uint64_t hf;
3054 	int error;
3055 
3056 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3057 	    ("%s:%d: fail", __func__, __LINE__));
3058 
3059 	siba_powerup(sc->sc_dev, 0);
3060 	if (!siba_dev_isup(sc->sc_dev))
3061 		bwn_reset_core(mac,
3062 		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3063 
3064 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3065 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3066 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3067 	BWN_GETTIME(mac->mac_phy.nexttime);
3068 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3069 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3070 	mac->mac_stats.link_noise = -95;
3071 	mac->mac_reason_intr = 0;
3072 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
3073 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3074 #ifdef BWN_DEBUG
3075 	if (sc->sc_debug & BWN_DEBUG_XMIT)
3076 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3077 #endif
3078 	mac->mac_suspended = 1;
3079 	mac->mac_task_state = 0;
3080 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3081 
3082 	mac->mac_phy.init_pre(mac);
3083 
3084 	siba_pcicore_intr(sc->sc_dev);
3085 
3086 	siba_fix_imcfglobug(sc->sc_dev);
3087 	bwn_bt_disable(mac);
3088 	if (mac->mac_phy.prepare_hw) {
3089 		error = mac->mac_phy.prepare_hw(mac);
3090 		if (error)
3091 			goto fail0;
3092 	}
3093 	error = bwn_chip_init(mac);
3094 	if (error)
3095 		goto fail0;
3096 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3097 	    siba_get_revid(sc->sc_dev));
3098 	hf = bwn_hf_read(mac);
3099 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3100 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3101 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3102 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3103 		if (mac->mac_phy.rev == 1)
3104 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3105 	}
3106 	if (mac->mac_phy.rf_ver == 0x2050) {
3107 		if (mac->mac_phy.rf_rev < 6)
3108 			hf |= BWN_HF_FORCE_VCO_RECALC;
3109 		if (mac->mac_phy.rf_rev == 6)
3110 			hf |= BWN_HF_4318_TSSI;
3111 	}
3112 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3113 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3114 	if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3115 	    (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3116 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3117 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3118 	bwn_hf_write(mac, hf);
3119 
3120 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3121 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3122 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3123 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3124 
3125 	bwn_rate_init(mac);
3126 	bwn_set_phytxctl(mac);
3127 
3128 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3129 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3130 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3131 
3132 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3133 		bwn_pio_init(mac);
3134 	else
3135 		bwn_dma_init(mac);
3136 	bwn_wme_init(mac);
3137 	bwn_spu_setdelay(mac, 1);
3138 	bwn_bt_enable(mac);
3139 
3140 	siba_powerup(sc->sc_dev,
3141 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3142 	bwn_set_macaddr(mac);
3143 	bwn_crypt_init(mac);
3144 
3145 	/* XXX LED initializatin */
3146 
3147 	mac->mac_status = BWN_MAC_STATUS_INITED;
3148 
3149 	return (error);
3150 
3151 fail0:
3152 	siba_powerdown(sc->sc_dev);
3153 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3154 	    ("%s:%d: fail", __func__, __LINE__));
3155 	return (error);
3156 }
3157 
3158 static void
3159 bwn_core_start(struct bwn_mac *mac)
3160 {
3161 	struct bwn_softc *sc = mac->mac_sc;
3162 	uint32_t tmp;
3163 
3164 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3165 	    ("%s:%d: fail", __func__, __LINE__));
3166 
3167 	if (siba_get_revid(sc->sc_dev) < 5)
3168 		return;
3169 
3170 	while (1) {
3171 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3172 		if (!(tmp & 0x00000001))
3173 			break;
3174 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3175 	}
3176 
3177 	bwn_mac_enable(mac);
3178 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3179 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3180 
3181 	mac->mac_status = BWN_MAC_STATUS_STARTED;
3182 }
3183 
3184 static void
3185 bwn_core_exit(struct bwn_mac *mac)
3186 {
3187 	struct bwn_softc *sc = mac->mac_sc;
3188 	uint32_t macctl;
3189 
3190 	wlan_assert_serialized();
3191 
3192 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3193 	    ("%s:%d: fail", __func__, __LINE__));
3194 
3195 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
3196 		return;
3197 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
3198 
3199 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3200 	macctl &= ~BWN_MACCTL_MCODE_RUN;
3201 	macctl |= BWN_MACCTL_MCODE_JMP0;
3202 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3203 
3204 	bwn_dma_stop(mac);
3205 	bwn_pio_stop(mac);
3206 	bwn_chip_exit(mac);
3207 	mac->mac_phy.switch_analog(mac, 0);
3208 	siba_dev_down(sc->sc_dev, 0);
3209 	siba_powerdown(sc->sc_dev);
3210 }
3211 
3212 static void
3213 bwn_bt_disable(struct bwn_mac *mac)
3214 {
3215 	struct bwn_softc *sc = mac->mac_sc;
3216 
3217 	(void)sc;
3218 	/* XXX do nothing yet */
3219 }
3220 
3221 static int
3222 bwn_chip_init(struct bwn_mac *mac)
3223 {
3224 	struct bwn_softc *sc = mac->mac_sc;
3225 	struct bwn_phy *phy = &mac->mac_phy;
3226 	uint32_t macctl;
3227 	int error;
3228 
3229 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3230 	if (phy->gmode)
3231 		macctl |= BWN_MACCTL_GMODE;
3232 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3233 
3234 	error = bwn_fw_fillinfo(mac);
3235 	if (error)
3236 		return (error);
3237 	error = bwn_fw_loaducode(mac);
3238 	if (error)
3239 		return (error);
3240 
3241 	error = bwn_gpio_init(mac);
3242 	if (error)
3243 		return (error);
3244 
3245 	error = bwn_fw_loadinitvals(mac);
3246 	if (error) {
3247 		siba_gpio_set(sc->sc_dev, 0);
3248 		return (error);
3249 	}
3250 	phy->switch_analog(mac, 1);
3251 	error = bwn_phy_init(mac);
3252 	if (error) {
3253 		siba_gpio_set(sc->sc_dev, 0);
3254 		return (error);
3255 	}
3256 	if (phy->set_im)
3257 		phy->set_im(mac, BWN_IMMODE_NONE);
3258 	if (phy->set_antenna)
3259 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
3260 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3261 
3262 	if (phy->type == BWN_PHYTYPE_B)
3263 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3264 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
3265 	if (siba_get_revid(sc->sc_dev) < 5)
3266 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
3267 
3268 	BWN_WRITE_4(mac, BWN_MACCTL,
3269 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3270 	BWN_WRITE_4(mac, BWN_MACCTL,
3271 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3272 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3273 
3274 	bwn_set_opmode(mac);
3275 	if (siba_get_revid(sc->sc_dev) < 3) {
3276 		BWN_WRITE_2(mac, 0x060e, 0x0000);
3277 		BWN_WRITE_2(mac, 0x0610, 0x8000);
3278 		BWN_WRITE_2(mac, 0x0604, 0x0000);
3279 		BWN_WRITE_2(mac, 0x0606, 0x0200);
3280 	} else {
3281 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
3282 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
3283 	}
3284 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3285 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00);
3286 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3287 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3288 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3289 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3290 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3291 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3292 	    siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3293 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3294 	return (error);
3295 }
3296 
3297 /* read hostflags */
3298 static uint64_t
3299 bwn_hf_read(struct bwn_mac *mac)
3300 {
3301 	uint64_t ret;
3302 
3303 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3304 	ret <<= 16;
3305 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3306 	ret <<= 16;
3307 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3308 	return (ret);
3309 }
3310 
3311 static void
3312 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3313 {
3314 
3315 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3316 	    (value & 0x00000000ffffull));
3317 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3318 	    (value & 0x0000ffff0000ull) >> 16);
3319 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3320 	    (value & 0xffff00000000ULL) >> 32);
3321 }
3322 
3323 static void
3324 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3325 {
3326 
3327 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3328 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3329 }
3330 
3331 static void
3332 bwn_rate_init(struct bwn_mac *mac)
3333 {
3334 
3335 	switch (mac->mac_phy.type) {
3336 	case BWN_PHYTYPE_A:
3337 	case BWN_PHYTYPE_G:
3338 	case BWN_PHYTYPE_LP:
3339 	case BWN_PHYTYPE_N:
3340 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3341 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3342 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3343 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3344 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3345 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3346 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3347 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
3348 			break;
3349 		/* FALLTHROUGH */
3350 	case BWN_PHYTYPE_B:
3351 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3352 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3353 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3354 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3355 		break;
3356 	default:
3357 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3358 	}
3359 }
3360 
3361 static void
3362 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3363 {
3364 	uint16_t offset;
3365 
3366 	if (ofdm) {
3367 		offset = 0x480;
3368 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3369 	} else {
3370 		offset = 0x4c0;
3371 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3372 	}
3373 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3374 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
3375 }
3376 
3377 static uint8_t
3378 bwn_plcp_getcck(const uint8_t bitrate)
3379 {
3380 
3381 	switch (bitrate) {
3382 	case BWN_CCK_RATE_1MB:
3383 		return (0x0a);
3384 	case BWN_CCK_RATE_2MB:
3385 		return (0x14);
3386 	case BWN_CCK_RATE_5MB:
3387 		return (0x37);
3388 	case BWN_CCK_RATE_11MB:
3389 		return (0x6e);
3390 	}
3391 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3392 	return (0);
3393 }
3394 
3395 static uint8_t
3396 bwn_plcp_getofdm(const uint8_t bitrate)
3397 {
3398 
3399 	switch (bitrate) {
3400 	case BWN_OFDM_RATE_6MB:
3401 		return (0xb);
3402 	case BWN_OFDM_RATE_9MB:
3403 		return (0xf);
3404 	case BWN_OFDM_RATE_12MB:
3405 		return (0xa);
3406 	case BWN_OFDM_RATE_18MB:
3407 		return (0xe);
3408 	case BWN_OFDM_RATE_24MB:
3409 		return (0x9);
3410 	case BWN_OFDM_RATE_36MB:
3411 		return (0xd);
3412 	case BWN_OFDM_RATE_48MB:
3413 		return (0x8);
3414 	case BWN_OFDM_RATE_54MB:
3415 		return (0xc);
3416 	}
3417 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3418 	return (0);
3419 }
3420 
3421 static void
3422 bwn_set_phytxctl(struct bwn_mac *mac)
3423 {
3424 	uint16_t ctl;
3425 
3426 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3427 	    BWN_TX_PHY_TXPWR);
3428 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3429 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3430 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3431 }
3432 
3433 static void
3434 bwn_pio_init(struct bwn_mac *mac)
3435 {
3436 	struct bwn_pio *pio = &mac->mac_method.pio;
3437 
3438 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3439 	    & ~BWN_MACCTL_BIGENDIAN);
3440 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3441 
3442 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3443 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3444 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3445 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3446 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3447 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3448 }
3449 
3450 static void
3451 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3452     int index)
3453 {
3454 	struct bwn_pio_txpkt *tp;
3455 	struct bwn_softc *sc = mac->mac_sc;
3456 	unsigned int i;
3457 
3458 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3459 	tq->tq_index = index;
3460 
3461 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3462 	if (siba_get_revid(sc->sc_dev) >= 8)
3463 		tq->tq_size = 1920;
3464 	else {
3465 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3466 		tq->tq_size -= 80;
3467 	}
3468 
3469 	TAILQ_INIT(&tq->tq_pktlist);
3470 	for (i = 0; i < N(tq->tq_pkts); i++) {
3471 		tp = &(tq->tq_pkts[i]);
3472 		tp->tp_index = i;
3473 		tp->tp_queue = tq;
3474 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3475 	}
3476 }
3477 
3478 static uint16_t
3479 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3480 {
3481 	struct bwn_softc *sc = mac->mac_sc;
3482 	static const uint16_t bases[] = {
3483 		BWN_PIO_BASE0,
3484 		BWN_PIO_BASE1,
3485 		BWN_PIO_BASE2,
3486 		BWN_PIO_BASE3,
3487 		BWN_PIO_BASE4,
3488 		BWN_PIO_BASE5,
3489 		BWN_PIO_BASE6,
3490 		BWN_PIO_BASE7,
3491 	};
3492 	static const uint16_t bases_rev11[] = {
3493 		BWN_PIO11_BASE0,
3494 		BWN_PIO11_BASE1,
3495 		BWN_PIO11_BASE2,
3496 		BWN_PIO11_BASE3,
3497 		BWN_PIO11_BASE4,
3498 		BWN_PIO11_BASE5,
3499 	};
3500 
3501 	if (siba_get_revid(sc->sc_dev) >= 11) {
3502 		if (index >= N(bases_rev11))
3503 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
3504 		return (bases_rev11[index]);
3505 	}
3506 	if (index >= N(bases))
3507 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
3508 	return (bases[index]);
3509 }
3510 
3511 static void
3512 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3513     int index)
3514 {
3515 	struct bwn_softc *sc = mac->mac_sc;
3516 
3517 	prq->prq_mac = mac;
3518 	prq->prq_rev = siba_get_revid(sc->sc_dev);
3519 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3520 	bwn_dma_rxdirectfifo(mac, index, 1);
3521 }
3522 
3523 static void
3524 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3525 {
3526 	if (tq == NULL)
3527 		return;
3528 	bwn_pio_cancel_tx_packets(tq);
3529 }
3530 
3531 static void
3532 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3533 {
3534 
3535 	bwn_destroy_pioqueue_tx(pio);
3536 }
3537 
3538 static uint16_t
3539 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3540     uint16_t offset)
3541 {
3542 
3543 	return (BWN_READ_2(mac, tq->tq_base + offset));
3544 }
3545 
3546 static void
3547 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3548 {
3549 	uint32_t ctl;
3550 	int type;
3551 	uint16_t base;
3552 
3553 	type = bwn_dma_mask2type(bwn_dma_mask(mac));
3554 	base = bwn_dma_base(type, idx);
3555 	if (type == BWN_DMA_64BIT) {
3556 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3557 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3558 		if (enable)
3559 			ctl |= BWN_DMA64_RXDIRECTFIFO;
3560 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3561 	} else {
3562 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3563 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3564 		if (enable)
3565 			ctl |= BWN_DMA32_RXDIRECTFIFO;
3566 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3567 	}
3568 }
3569 
3570 static uint64_t
3571 bwn_dma_mask(struct bwn_mac *mac)
3572 {
3573 	uint32_t tmp;
3574 	uint16_t base;
3575 
3576 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3577 	if (tmp & SIBA_TGSHIGH_DMA64)
3578 		return (BWN_DMA_BIT_MASK(64));
3579 	base = bwn_dma_base(0, 0);
3580 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3581 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3582 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
3583 		return (BWN_DMA_BIT_MASK(32));
3584 
3585 	return (BWN_DMA_BIT_MASK(30));
3586 }
3587 
3588 static int
3589 bwn_dma_mask2type(uint64_t dmamask)
3590 {
3591 
3592 	if (dmamask == BWN_DMA_BIT_MASK(30))
3593 		return (BWN_DMA_30BIT);
3594 	if (dmamask == BWN_DMA_BIT_MASK(32))
3595 		return (BWN_DMA_32BIT);
3596 	if (dmamask == BWN_DMA_BIT_MASK(64))
3597 		return (BWN_DMA_64BIT);
3598 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3599 	return (BWN_DMA_30BIT);
3600 }
3601 
3602 static void
3603 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3604 {
3605 	struct bwn_pio_txpkt *tp;
3606 	unsigned int i;
3607 
3608 	for (i = 0; i < N(tq->tq_pkts); i++) {
3609 		tp = &(tq->tq_pkts[i]);
3610 		if (tp->tp_m) {
3611 			m_freem(tp->tp_m);
3612 			tp->tp_m = NULL;
3613 		}
3614 	}
3615 }
3616 
3617 static uint16_t
3618 bwn_dma_base(int type, int controller_idx)
3619 {
3620 	static const uint16_t map64[] = {
3621 		BWN_DMA64_BASE0,
3622 		BWN_DMA64_BASE1,
3623 		BWN_DMA64_BASE2,
3624 		BWN_DMA64_BASE3,
3625 		BWN_DMA64_BASE4,
3626 		BWN_DMA64_BASE5,
3627 	};
3628 	static const uint16_t map32[] = {
3629 		BWN_DMA32_BASE0,
3630 		BWN_DMA32_BASE1,
3631 		BWN_DMA32_BASE2,
3632 		BWN_DMA32_BASE3,
3633 		BWN_DMA32_BASE4,
3634 		BWN_DMA32_BASE5,
3635 	};
3636 
3637 	if (type == BWN_DMA_64BIT) {
3638 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3639 		    ("%s:%d: fail", __func__, __LINE__));
3640 		return (map64[controller_idx]);
3641 	}
3642 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3643 	    ("%s:%d: fail", __func__, __LINE__));
3644 	return (map32[controller_idx]);
3645 }
3646 
3647 static void
3648 bwn_dma_init(struct bwn_mac *mac)
3649 {
3650 	struct bwn_dma *dma = &mac->mac_method.dma;
3651 
3652 	/* setup TX DMA channels. */
3653 	bwn_dma_setup(dma->wme[WME_AC_BK]);
3654 	bwn_dma_setup(dma->wme[WME_AC_BE]);
3655 	bwn_dma_setup(dma->wme[WME_AC_VI]);
3656 	bwn_dma_setup(dma->wme[WME_AC_VO]);
3657 	bwn_dma_setup(dma->mcast);
3658 	/* setup RX DMA channel. */
3659 	bwn_dma_setup(dma->rx);
3660 }
3661 
3662 static struct bwn_dma_ring *
3663 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3664     int for_tx, int type)
3665 {
3666 	struct bwn_dma *dma = &mac->mac_method.dma;
3667 	struct bwn_dma_ring *dr;
3668 	struct bwn_dmadesc_generic *desc;
3669 	struct bwn_dmadesc_meta *mt;
3670 	struct bwn_softc *sc = mac->mac_sc;
3671 	int error, i;
3672 
3673 	dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO);
3674 	dr->dr_numslots = BWN_RXRING_SLOTS;
3675 	if (for_tx)
3676 		dr->dr_numslots = BWN_TXRING_SLOTS;
3677 
3678 	dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3679 	    M_DEVBUF, M_INTWAIT | M_ZERO);
3680 
3681 	dr->dr_type = type;
3682 	dr->dr_mac = mac;
3683 	dr->dr_base = bwn_dma_base(type, controller_index);
3684 	dr->dr_index = controller_index;
3685 	if (type == BWN_DMA_64BIT) {
3686 		dr->getdesc = bwn_dma_64_getdesc;
3687 		dr->setdesc = bwn_dma_64_setdesc;
3688 		dr->start_transfer = bwn_dma_64_start_transfer;
3689 		dr->suspend = bwn_dma_64_suspend;
3690 		dr->resume = bwn_dma_64_resume;
3691 		dr->get_curslot = bwn_dma_64_get_curslot;
3692 		dr->set_curslot = bwn_dma_64_set_curslot;
3693 	} else {
3694 		dr->getdesc = bwn_dma_32_getdesc;
3695 		dr->setdesc = bwn_dma_32_setdesc;
3696 		dr->start_transfer = bwn_dma_32_start_transfer;
3697 		dr->suspend = bwn_dma_32_suspend;
3698 		dr->resume = bwn_dma_32_resume;
3699 		dr->get_curslot = bwn_dma_32_get_curslot;
3700 		dr->set_curslot = bwn_dma_32_set_curslot;
3701 	}
3702 	if (for_tx) {
3703 		dr->dr_tx = 1;
3704 		dr->dr_curslot = -1;
3705 	} else {
3706 		if (dr->dr_index == 0) {
3707 			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3708 			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3709 		} else
3710 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3711 	}
3712 
3713 	error = bwn_dma_allocringmemory(dr);
3714 	if (error)
3715 		goto fail1;
3716 
3717 	if (for_tx) {
3718 		/*
3719 		 * Assumption: BWN_TXRING_SLOTS can be divided by
3720 		 * BWN_TX_SLOTS_PER_FRAME
3721 		 */
3722 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3723 		    ("%s:%d: fail", __func__, __LINE__));
3724 
3725 		/*
3726 		 * Create TX ring DMA stuffs
3727 		 */
3728 		dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag,
3729 		    4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3730 		    BWN_MAX_HDRSIZE(mac),
3731 		    BUS_DMA_WAITOK | BUS_DMA_ZERO,
3732 		    &dr->dr_txring_dtag, &dr->dr_txring_dmap,
3733 		    &dr->dr_txring_paddr);
3734 		if (dr->dr_txhdr_cache == NULL) {
3735 			device_printf(sc->sc_dev,
3736 			    "can't create TX ring DMA memory\n");
3737 			goto fail1;
3738 		}
3739 
3740 		for (i = 0; i < dr->dr_numslots; i += 2) {
3741 			dr->getdesc(dr, i, &desc, &mt);
3742 
3743 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3744 			mt->mt_m = NULL;
3745 			mt->mt_ni = NULL;
3746 			mt->mt_islast = 0;
3747 			mt->mt_dmap = dr->dr_txring_dmap;
3748 			mt->mt_paddr = dr->dr_txring_paddr +
3749 			    (i / BWN_TX_SLOTS_PER_FRAME) *
3750 			    BWN_MAX_HDRSIZE(mac);
3751 
3752 			dr->getdesc(dr, i + 1, &desc, &mt);
3753 
3754 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3755 			mt->mt_m = NULL;
3756 			mt->mt_ni = NULL;
3757 			mt->mt_islast = 1;
3758 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
3759 			    &mt->mt_dmap);
3760 			if (error) {
3761 				device_printf(sc->sc_dev,
3762 				     "can't create RX buf DMA map\n");
3763 				goto fail2;
3764 			}
3765 		}
3766 	} else {
3767 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3768 		    &dr->dr_spare_dmap);
3769 		if (error) {
3770 			device_printf(sc->sc_dev,
3771 			    "can't create RX buf DMA map\n");
3772 			goto out;		/* XXX wrong! */
3773 		}
3774 
3775 		for (i = 0; i < dr->dr_numslots; i++) {
3776 			dr->getdesc(dr, i, &desc, &mt);
3777 
3778 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3779 			    &mt->mt_dmap);
3780 			if (error) {
3781 				device_printf(sc->sc_dev,
3782 				    "can't create RX buf DMA map\n");
3783 				goto out;	/* XXX wrong! */
3784 			}
3785 			error = bwn_dma_newbuf(dr, desc, mt, 1);
3786 			if (error) {
3787 				device_printf(sc->sc_dev,
3788 				    "failed to allocate RX buf\n");
3789 				goto out;	/* XXX wrong! */
3790 			}
3791 		}
3792 
3793 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3794 		    BUS_DMASYNC_PREWRITE);
3795 
3796 		dr->dr_usedslot = dr->dr_numslots;
3797 	}
3798 
3799       out:
3800 	return (dr);
3801 
3802 fail2:
3803 	/* XXX free up dma allocations */
3804 fail1:
3805 	kfree(dr->dr_meta, M_DEVBUF);
3806 	kfree(dr, M_DEVBUF);
3807 	return (NULL);
3808 }
3809 
3810 static void
3811 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3812 {
3813 
3814 	if (dr == NULL)
3815 		return;
3816 
3817 	bwn_dma_free_descbufs(*dr);
3818 	bwn_dma_free_ringmemory(*dr);
3819 
3820 	if ((*dr)->dr_meta != NULL)
3821 		kfree((*dr)->dr_meta, M_DEVBUF);
3822 	kfree(*dr, M_DEVBUF);
3823 
3824 	*dr = NULL;
3825 }
3826 
3827 static void
3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3829     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3830 {
3831 	struct bwn_dmadesc32 *desc;
3832 
3833 	*meta = &(dr->dr_meta[slot]);
3834 	desc = dr->dr_ring_descbase;
3835 	desc = &(desc[slot]);
3836 
3837 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3838 }
3839 
3840 static void
3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3842     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3843     int start, int end, int irq)
3844 {
3845 	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3846 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3847 	uint32_t addr, addrext, ctl;
3848 	int slot;
3849 
3850 	slot = (int)(&(desc->dma.dma32) - descbase);
3851 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3852 	    ("%s:%d: fail", __func__, __LINE__));
3853 
3854 	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3855 	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3856 	addr |= siba_dma_translation(sc->sc_dev);
3857 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3858 	if (slot == dr->dr_numslots - 1)
3859 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
3860 	if (start)
3861 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
3862 	if (end)
3863 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
3864 	if (irq)
3865 		ctl |= BWN_DMA32_DCTL_IRQ;
3866 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3867 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
3868 
3869 	desc->dma.dma32.control = htole32(ctl);
3870 	desc->dma.dma32.address = htole32(addr);
3871 }
3872 
3873 static void
3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3875 {
3876 
3877 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3878 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3879 }
3880 
3881 static void
3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3883 {
3884 
3885 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3886 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3887 }
3888 
3889 static void
3890 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3891 {
3892 
3893 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3894 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3895 }
3896 
3897 static int
3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3899 {
3900 	uint32_t val;
3901 
3902 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3903 	val &= BWN_DMA32_RXDPTR;
3904 
3905 	return (val / sizeof(struct bwn_dmadesc32));
3906 }
3907 
3908 static void
3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3910 {
3911 
3912 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3913 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3914 }
3915 
3916 static void
3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3918     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3919 {
3920 	struct bwn_dmadesc64 *desc;
3921 
3922 	*meta = &(dr->dr_meta[slot]);
3923 	desc = dr->dr_ring_descbase;
3924 	desc = &(desc[slot]);
3925 
3926 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3927 }
3928 
3929 static void
3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3931     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3932     int start, int end, int irq)
3933 {
3934 	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3935 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3936 	int slot;
3937 	uint32_t ctl0 = 0, ctl1 = 0;
3938 	uint32_t addrlo, addrhi;
3939 	uint32_t addrext;
3940 
3941 	slot = (int)(&(desc->dma.dma64) - descbase);
3942 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3943 	    ("%s:%d: fail", __func__, __LINE__));
3944 
3945 	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3946 	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3947 	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3948 	    30;
3949 	addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3950 	if (slot == dr->dr_numslots - 1)
3951 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3952 	if (start)
3953 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3954 	if (end)
3955 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3956 	if (irq)
3957 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
3958 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3959 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3960 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
3961 
3962 	desc->dma.dma64.control0 = htole32(ctl0);
3963 	desc->dma.dma64.control1 = htole32(ctl1);
3964 	desc->dma.dma64.address_low = htole32(addrlo);
3965 	desc->dma.dma64.address_high = htole32(addrhi);
3966 }
3967 
3968 static void
3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3970 {
3971 
3972 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3973 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3974 }
3975 
3976 static void
3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3978 {
3979 
3980 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3981 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3982 }
3983 
3984 static void
3985 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3986 {
3987 
3988 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3989 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3990 }
3991 
3992 static int
3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3994 {
3995 	uint32_t val;
3996 
3997 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3998 	val &= BWN_DMA64_RXSTATDPTR;
3999 
4000 	return (val / sizeof(struct bwn_dmadesc64));
4001 }
4002 
4003 static void
4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4005 {
4006 
4007 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4008 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4009 }
4010 
4011 static int
4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4013 {
4014 	struct bwn_mac *mac = dr->dr_mac;
4015 	struct bwn_dma *dma = &mac->mac_method.dma;
4016 	struct bwn_softc *sc = mac->mac_sc;
4017 	int error;
4018 
4019 	error = bus_dma_tag_create(dma->parent_dtag,
4020 			    BWN_ALIGN, 0,
4021 			    BUS_SPACE_MAXADDR,
4022 			    BUS_SPACE_MAXADDR,
4023 			    NULL, NULL,
4024 			    BWN_DMA_RINGMEMSIZE,
4025 			    1,
4026 			    BUS_SPACE_MAXSIZE_32BIT,
4027 			    0,
4028 			    &dr->dr_ring_dtag);
4029 	if (error) {
4030 		device_printf(sc->sc_dev,
4031 		    "can't create TX ring DMA tag: TODO frees\n");
4032 		return (-1);
4033 	}
4034 
4035 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
4036 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4037 	    &dr->dr_ring_dmap);
4038 	if (error) {
4039 		device_printf(sc->sc_dev,
4040 		    "can't allocate DMA mem: TODO frees\n");
4041 		return (-1);
4042 	}
4043 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4044 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4045 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0);
4046 	if (error) {
4047 		device_printf(sc->sc_dev,
4048 		    "can't load DMA mem: TODO free\n");
4049 		return (-1);
4050 	}
4051 
4052 	return (0);
4053 }
4054 
4055 static void
4056 bwn_dma_setup(struct bwn_dma_ring *dr)
4057 {
4058 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
4059 	uint64_t ring64;
4060 	uint32_t addrext, ring32, value;
4061 	uint32_t trans = siba_dma_translation(sc->sc_dev);
4062 
4063 	if (dr->dr_tx) {
4064 		dr->dr_curslot = -1;
4065 
4066 		if (dr->dr_type == BWN_DMA_64BIT) {
4067 			ring64 = (uint64_t)(dr->dr_ring_dmabase);
4068 			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4069 			    >> 30;
4070 			value = BWN_DMA64_TXENABLE;
4071 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4072 			    & BWN_DMA64_TXADDREXT_MASK;
4073 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4074 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4075 			    (ring64 & 0xffffffff));
4076 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4077 			    ((ring64 >> 32) &
4078 			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4079 		} else {
4080 			ring32 = (uint32_t)(dr->dr_ring_dmabase);
4081 			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4082 			value = BWN_DMA32_TXENABLE;
4083 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4084 			    & BWN_DMA32_TXADDREXT_MASK;
4085 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4086 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4087 			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4088 		}
4089 		return;
4090 	}
4091 
4092 	/*
4093 	 * set for RX
4094 	 */
4095 	dr->dr_usedslot = dr->dr_numslots;
4096 
4097 	if (dr->dr_type == BWN_DMA_64BIT) {
4098 		ring64 = (uint64_t)(dr->dr_ring_dmabase);
4099 		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4100 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4101 		value |= BWN_DMA64_RXENABLE;
4102 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4103 		    & BWN_DMA64_RXADDREXT_MASK;
4104 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4105 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4106 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4107 		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4108 		    | (trans << 1));
4109 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4110 		    sizeof(struct bwn_dmadesc64));
4111 	} else {
4112 		ring32 = (uint32_t)(dr->dr_ring_dmabase);
4113 		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4114 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4115 		value |= BWN_DMA32_RXENABLE;
4116 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4117 		    & BWN_DMA32_RXADDREXT_MASK;
4118 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4119 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4120 		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4121 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4122 		    sizeof(struct bwn_dmadesc32));
4123 	}
4124 }
4125 
4126 static void
4127 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4128 {
4129 
4130 	if (dr->dr_tx) {
4131 		bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap);
4132 		if (dr->dr_txhdr_cache != NULL)
4133 			bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache,
4134 			    dr->dr_txring_dmap);
4135 		bus_dma_tag_destroy(dr->dr_txring_dtag);
4136 	}
4137 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4138 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4139 	    dr->dr_ring_dmap);
4140 	bus_dma_tag_destroy(dr->dr_ring_dtag);
4141 }
4142 
4143 static void
4144 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4145 {
4146 
4147 	if (dr->dr_tx) {
4148 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4149 		if (dr->dr_type == BWN_DMA_64BIT) {
4150 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4151 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4152 		} else
4153 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4154 	} else {
4155 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4156 		if (dr->dr_type == BWN_DMA_64BIT) {
4157 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4158 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4159 		} else
4160 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4161 	}
4162 }
4163 
4164 static void
4165 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4166 {
4167 	struct bwn_dmadesc_generic *desc;
4168 	struct bwn_dmadesc_meta *meta;
4169 	struct bwn_mac *mac = dr->dr_mac;
4170 	struct bwn_dma *dma = &mac->mac_method.dma;
4171 	struct bwn_softc *sc = mac->mac_sc;
4172 	int i;
4173 
4174 	if (!dr->dr_usedslot)
4175 		return;
4176 	for (i = 0; i < dr->dr_numslots; i++) {
4177 		dr->getdesc(dr, i, &desc, &meta);
4178 
4179 		if (meta->mt_m == NULL) {
4180 			if (!dr->dr_tx)
4181 				device_printf(sc->sc_dev, "%s: not TX?\n",
4182 				    __func__);
4183 			continue;
4184 		}
4185 		if (dr->dr_tx) {
4186 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
4187 				/* Nothing */
4188 			} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
4189 				bus_dmamap_unload(dma->txbuf_dtag,
4190 				    meta->mt_dmap);
4191 			}
4192 		} else
4193 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4194 		bwn_dma_free_descbuf(dr, meta);
4195 	}
4196 }
4197 
4198 static int
4199 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4200     int type)
4201 {
4202 	struct bwn_softc *sc = mac->mac_sc;
4203 	uint32_t value;
4204 	int i;
4205 	uint16_t offset;
4206 
4207 	for (i = 0; i < 10; i++) {
4208 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4209 		    BWN_DMA32_TXSTATUS;
4210 		value = BWN_READ_4(mac, base + offset);
4211 		if (type == BWN_DMA_64BIT) {
4212 			value &= BWN_DMA64_TXSTAT;
4213 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
4214 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4215 			    value == BWN_DMA64_TXSTAT_STOPPED)
4216 				break;
4217 		} else {
4218 			value &= BWN_DMA32_TXSTATE;
4219 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
4220 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4221 			    value == BWN_DMA32_TXSTAT_STOPPED)
4222 				break;
4223 		}
4224 		DELAY(1000);
4225 	}
4226 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4227 	BWN_WRITE_4(mac, base + offset, 0);
4228 	for (i = 0; i < 10; i++) {
4229 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4230 						   BWN_DMA32_TXSTATUS;
4231 		value = BWN_READ_4(mac, base + offset);
4232 		if (type == BWN_DMA_64BIT) {
4233 			value &= BWN_DMA64_TXSTAT;
4234 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
4235 				i = -1;
4236 				break;
4237 			}
4238 		} else {
4239 			value &= BWN_DMA32_TXSTATE;
4240 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
4241 				i = -1;
4242 				break;
4243 			}
4244 		}
4245 		DELAY(1000);
4246 	}
4247 	if (i != -1) {
4248 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4249 		return (ENODEV);
4250 	}
4251 	DELAY(1000);
4252 
4253 	return (0);
4254 }
4255 
4256 static int
4257 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4258     int type)
4259 {
4260 	struct bwn_softc *sc = mac->mac_sc;
4261 	uint32_t value;
4262 	int i;
4263 	uint16_t offset;
4264 
4265 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4266 	BWN_WRITE_4(mac, base + offset, 0);
4267 	for (i = 0; i < 10; i++) {
4268 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4269 		    BWN_DMA32_RXSTATUS;
4270 		value = BWN_READ_4(mac, base + offset);
4271 		if (type == BWN_DMA_64BIT) {
4272 			value &= BWN_DMA64_RXSTAT;
4273 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
4274 				i = -1;
4275 				break;
4276 			}
4277 		} else {
4278 			value &= BWN_DMA32_RXSTATE;
4279 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
4280 				i = -1;
4281 				break;
4282 			}
4283 		}
4284 		DELAY(1000);
4285 	}
4286 	if (i != -1) {
4287 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4288 		return (ENODEV);
4289 	}
4290 
4291 	return (0);
4292 }
4293 
4294 static void
4295 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4296     struct bwn_dmadesc_meta *meta)
4297 {
4298 
4299 	if (meta->mt_m != NULL) {
4300 		m_freem(meta->mt_m);
4301 		meta->mt_m = NULL;
4302 	}
4303 	if (meta->mt_ni != NULL) {
4304 		ieee80211_free_node(meta->mt_ni);
4305 		meta->mt_ni = NULL;
4306 	}
4307 }
4308 
4309 static void
4310 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4311 {
4312 	struct bwn_rxhdr4 *rxhdr;
4313 	unsigned char *frame;
4314 
4315 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
4316 	rxhdr->frame_len = 0;
4317 
4318 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4319 	    sizeof(struct bwn_plcp6) + 2,
4320 	    ("%s:%d: fail", __func__, __LINE__));
4321 	frame = mtod(m, char *) + dr->dr_frameoffset;
4322 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4323 }
4324 
4325 static uint8_t
4326 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4327 {
4328 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4329 
4330 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4331 	    == 0xff);
4332 }
4333 
4334 static void
4335 bwn_wme_init(struct bwn_mac *mac)
4336 {
4337 
4338 	bwn_wme_load(mac);
4339 
4340 	/* enable WME support. */
4341 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4342 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4343 	    BWN_IFSCTL_USE_EDCF);
4344 }
4345 
4346 static void
4347 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4348 {
4349 	struct bwn_softc *sc = mac->mac_sc;
4350 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4351 	uint16_t delay;	/* microsec */
4352 
4353 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4354 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4355 		delay = 500;
4356 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4357 		delay = max(delay, (uint16_t)2400);
4358 
4359 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4360 }
4361 
4362 static void
4363 bwn_bt_enable(struct bwn_mac *mac)
4364 {
4365 	struct bwn_softc *sc = mac->mac_sc;
4366 	uint64_t hf;
4367 
4368 	if (bwn_bluetooth == 0)
4369 		return;
4370 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4371 		return;
4372 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4373 		return;
4374 
4375 	hf = bwn_hf_read(mac);
4376 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4377 		hf |= BWN_HF_BT_COEXISTALT;
4378 	else
4379 		hf |= BWN_HF_BT_COEXIST;
4380 	bwn_hf_write(mac, hf);
4381 }
4382 
4383 static void
4384 bwn_set_macaddr(struct bwn_mac *mac)
4385 {
4386 
4387 	bwn_mac_write_bssid(mac);
4388 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4389 }
4390 
4391 static void
4392 bwn_clear_keys(struct bwn_mac *mac)
4393 {
4394 	int i;
4395 
4396 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
4397 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4398 		    ("%s:%d: fail", __func__, __LINE__));
4399 
4400 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4401 		    NULL, BWN_SEC_KEYSIZE, NULL);
4402 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4403 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4404 			    NULL, BWN_SEC_KEYSIZE, NULL);
4405 		}
4406 		mac->mac_key[i].keyconf = NULL;
4407 	}
4408 }
4409 
4410 static void
4411 bwn_crypt_init(struct bwn_mac *mac)
4412 {
4413 	struct bwn_softc *sc = mac->mac_sc;
4414 
4415 	mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4416 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4417 	    ("%s:%d: fail", __func__, __LINE__));
4418 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4419 	mac->mac_ktp *= 2;
4420 	if (siba_get_revid(sc->sc_dev) >= 5)
4421 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4422 	bwn_clear_keys(mac);
4423 }
4424 
4425 static void
4426 bwn_chip_exit(struct bwn_mac *mac)
4427 {
4428 	struct bwn_softc *sc = mac->mac_sc;
4429 
4430 	bwn_phy_exit(mac);
4431 	siba_gpio_set(sc->sc_dev, 0);
4432 }
4433 
4434 static int
4435 bwn_fw_fillinfo(struct bwn_mac *mac)
4436 {
4437 	int error;
4438 
4439 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4440 	if (error == 0)
4441 		return (0);
4442 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4443 	if (error == 0)
4444 		return (0);
4445 	return (error);
4446 }
4447 
4448 static int
4449 bwn_gpio_init(struct bwn_mac *mac)
4450 {
4451 	struct bwn_softc *sc = mac->mac_sc;
4452 	uint32_t mask = 0x1f, set = 0xf, value;
4453 
4454 	BWN_WRITE_4(mac, BWN_MACCTL,
4455 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4456 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
4457 	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4458 
4459 	if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4460 		mask |= 0x0060;
4461 		set |= 0x0060;
4462 	}
4463 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4464 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
4465 		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4466 		mask |= 0x0200;
4467 		set |= 0x0200;
4468 	}
4469 	if (siba_get_revid(sc->sc_dev) >= 2)
4470 		mask |= 0x0010;
4471 
4472 	value = siba_gpio_get(sc->sc_dev);
4473 	if (value == -1)
4474 		return (0);
4475 	siba_gpio_set(sc->sc_dev, (value & mask) | set);
4476 
4477 	return (0);
4478 }
4479 
4480 static int
4481 bwn_fw_loadinitvals(struct bwn_mac *mac)
4482 {
4483 #define	GETFWOFFSET(fwp, offset)				\
4484 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4485 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
4486 	const struct bwn_fwhdr *hdr;
4487 	struct bwn_fw *fw = &mac->mac_fw;
4488 	int error;
4489 
4490 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4491 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4492 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4493 	if (error)
4494 		return (error);
4495 	if (fw->initvals_band.fw) {
4496 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4497 		error = bwn_fwinitvals_write(mac,
4498 		    GETFWOFFSET(fw->initvals_band, hdr_len),
4499 		    be32toh(hdr->size),
4500 		    fw->initvals_band.fw->datasize - hdr_len);
4501 	}
4502 	return (error);
4503 #undef GETFWOFFSET
4504 }
4505 
4506 static int
4507 bwn_phy_init(struct bwn_mac *mac)
4508 {
4509 	struct bwn_softc *sc = mac->mac_sc;
4510 	int error;
4511 
4512 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4513 	mac->mac_phy.rf_onoff(mac, 1);
4514 	error = mac->mac_phy.init(mac);
4515 	if (error) {
4516 		device_printf(sc->sc_dev, "PHY init failed\n");
4517 		goto fail0;
4518 	}
4519 	error = bwn_switch_channel(mac,
4520 	    mac->mac_phy.get_default_chan(mac));
4521 	if (error) {
4522 		device_printf(sc->sc_dev,
4523 		    "failed to switch default channel\n");
4524 		goto fail1;
4525 	}
4526 	return (0);
4527 fail1:
4528 	if (mac->mac_phy.exit)
4529 		mac->mac_phy.exit(mac);
4530 fail0:
4531 	mac->mac_phy.rf_onoff(mac, 0);
4532 
4533 	return (error);
4534 }
4535 
4536 static void
4537 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4538 {
4539 	uint16_t ant;
4540 	uint16_t tmp;
4541 
4542 	ant = bwn_ant2phy(antenna);
4543 
4544 	/* For ACK/CTS */
4545 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4546 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4547 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4548 	/* For Probe Resposes */
4549 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4550 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4551 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4552 }
4553 
4554 static void
4555 bwn_set_opmode(struct bwn_mac *mac)
4556 {
4557 	struct bwn_softc *sc = mac->mac_sc;
4558 	struct ifnet *ifp = sc->sc_ifp;
4559 	struct ieee80211com *ic = ifp->if_l2com;
4560 	uint32_t ctl;
4561 	uint16_t cfp_pretbtt;
4562 
4563 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4564 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4565 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4566 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4567 	ctl |= BWN_MACCTL_STA;
4568 
4569 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4570 	    ic->ic_opmode == IEEE80211_M_MBSS)
4571 		ctl |= BWN_MACCTL_HOSTAP;
4572 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
4573 		ctl &= ~BWN_MACCTL_STA;
4574 	ctl |= sc->sc_filters;
4575 
4576 	if (siba_get_revid(sc->sc_dev) <= 4)
4577 		ctl |= BWN_MACCTL_PROMISC;
4578 
4579 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4580 
4581 	cfp_pretbtt = 2;
4582 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4583 		if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4584 		    siba_get_chiprev(sc->sc_dev) == 3)
4585 			cfp_pretbtt = 100;
4586 		else
4587 			cfp_pretbtt = 50;
4588 	}
4589 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4590 }
4591 
4592 static int
4593 bwn_dma_gettype(struct bwn_mac *mac)
4594 {
4595 	uint32_t tmp;
4596 	uint16_t base;
4597 
4598 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4599 	if (tmp & SIBA_TGSHIGH_DMA64)
4600 		return (BWN_DMA_64BIT);
4601 	base = bwn_dma_base(0, 0);
4602 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4603 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4604 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
4605 		return (BWN_DMA_32BIT);
4606 
4607 	return (BWN_DMA_30BIT);
4608 }
4609 
4610 static void
4611 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4612 {
4613 	if (!error) {
4614 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4615 		*((bus_addr_t *)arg) = seg->ds_addr;
4616 	}
4617 }
4618 
4619 static void
4620 bwn_phy_g_init_sub(struct bwn_mac *mac)
4621 {
4622 	struct bwn_phy *phy = &mac->mac_phy;
4623 	struct bwn_phy_g *pg = &phy->phy_g;
4624 	struct bwn_softc *sc = mac->mac_sc;
4625 	uint16_t i, tmp;
4626 
4627 	if (phy->rev == 1)
4628 		bwn_phy_init_b5(mac);
4629 	else
4630 		bwn_phy_init_b6(mac);
4631 
4632 	if (phy->rev >= 2 || phy->gmode)
4633 		bwn_phy_init_a(mac);
4634 
4635 	if (phy->rev >= 2) {
4636 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4637 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4638 	}
4639 	if (phy->rev == 2) {
4640 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4641 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4642 	}
4643 	if (phy->rev > 5) {
4644 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4645 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4646 	}
4647 	if (phy->gmode || phy->rev >= 2) {
4648 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4649 		tmp &= BWN_PHYVER_VERSION;
4650 		if (tmp == 3 || tmp == 5) {
4651 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4652 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4653 		}
4654 		if (tmp == 5) {
4655 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4656 			    0x1f00);
4657 		}
4658 	}
4659 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4660 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4661 	if (phy->rf_rev == 8) {
4662 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4663 		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4664 	}
4665 	if (BWN_HAS_LOOPBACK(phy))
4666 		bwn_loopback_calcgain(mac);
4667 
4668 	if (phy->rf_rev != 8) {
4669 		if (pg->pg_initval == 0xffff)
4670 			pg->pg_initval = bwn_rf_init_bcm2050(mac);
4671 		else
4672 			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4673 	}
4674 	bwn_lo_g_init(mac);
4675 	if (BWN_HAS_TXMAG(phy)) {
4676 		BWN_RF_WRITE(mac, 0x52,
4677 		    (BWN_RF_READ(mac, 0x52) & 0xff00)
4678 		    | pg->pg_loctl.tx_bias |
4679 		    pg->pg_loctl.tx_magn);
4680 	} else {
4681 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4682 	}
4683 	if (phy->rev >= 6) {
4684 		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4685 		    (pg->pg_loctl.tx_bias << 12));
4686 	}
4687 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4688 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4689 	else
4690 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4691 	if (phy->rev < 2)
4692 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4693 	else
4694 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4695 	if (phy->gmode || phy->rev >= 2) {
4696 		bwn_lo_g_adjust(mac);
4697 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4698 	}
4699 
4700 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4701 		for (i = 0; i < 64; i++) {
4702 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4703 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4704 			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4705 			    -32), 31));
4706 		}
4707 		bwn_nrssi_threshold(mac);
4708 	} else if (phy->gmode || phy->rev >= 2) {
4709 		if (pg->pg_nrssi[0] == -1000) {
4710 			KASSERT(pg->pg_nrssi[1] == -1000,
4711 			    ("%s:%d: fail", __func__, __LINE__));
4712 			bwn_nrssi_slope_11g(mac);
4713 		} else
4714 			bwn_nrssi_threshold(mac);
4715 	}
4716 	if (phy->rf_rev == 8)
4717 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4718 	bwn_phy_hwpctl_init(mac);
4719 	if ((siba_get_chipid(sc->sc_dev) == 0x4306
4720 	     && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4721 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4722 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4723 	}
4724 }
4725 
4726 static uint8_t
4727 bwn_has_hwpctl(struct bwn_mac *mac)
4728 {
4729 
4730 	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4731 		return (0);
4732 	return (mac->mac_phy.use_hwpctl(mac));
4733 }
4734 
4735 static void
4736 bwn_phy_init_b5(struct bwn_mac *mac)
4737 {
4738 	struct bwn_phy *phy = &mac->mac_phy;
4739 	struct bwn_phy_g *pg = &phy->phy_g;
4740 	struct bwn_softc *sc = mac->mac_sc;
4741 	uint16_t offset, value;
4742 	uint8_t old_channel;
4743 
4744 	if (phy->analog == 1)
4745 		BWN_RF_SET(mac, 0x007a, 0x0050);
4746 	if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4747 	    (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4748 		value = 0x2120;
4749 		for (offset = 0x00a8; offset < 0x00c7; offset++) {
4750 			BWN_PHY_WRITE(mac, offset, value);
4751 			value += 0x202;
4752 		}
4753 	}
4754 	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4755 	if (phy->rf_ver == 0x2050)
4756 		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4757 
4758 	if (phy->gmode || phy->rev >= 2) {
4759 		if (phy->rf_ver == 0x2050) {
4760 			BWN_RF_SET(mac, 0x007a, 0x0020);
4761 			BWN_RF_SET(mac, 0x0051, 0x0004);
4762 		}
4763 		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4764 
4765 		BWN_PHY_SET(mac, 0x0802, 0x0100);
4766 		BWN_PHY_SET(mac, 0x042b, 0x2000);
4767 
4768 		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4769 
4770 		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4771 		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4772 		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4773 	}
4774 
4775 	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4776 		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4777 
4778 	if (phy->analog == 1) {
4779 		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4780 		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4781 		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4782 		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4783 		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4784 	} else
4785 		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4786 	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4787 	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4788 
4789 	if (phy->analog == 1)
4790 		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4791 	else
4792 		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4793 
4794 	if (phy->analog == 0)
4795 		BWN_WRITE_2(mac, 0x03e4, 0x3000);
4796 
4797 	old_channel = phy->chan;
4798 	bwn_phy_g_switch_chan(mac, 7, 0);
4799 
4800 	if (phy->rf_ver != 0x2050) {
4801 		BWN_RF_WRITE(mac, 0x0075, 0x0080);
4802 		BWN_RF_WRITE(mac, 0x0079, 0x0081);
4803 	}
4804 
4805 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
4806 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
4807 
4808 	if (phy->rf_ver == 0x2050) {
4809 		BWN_RF_WRITE(mac, 0x0050, 0x0020);
4810 		BWN_RF_WRITE(mac, 0x005a, 0x0070);
4811 	}
4812 
4813 	BWN_RF_WRITE(mac, 0x005b, 0x007b);
4814 	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4815 	BWN_RF_SET(mac, 0x007a, 0x0007);
4816 
4817 	bwn_phy_g_switch_chan(mac, old_channel, 0);
4818 	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4819 	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4820 	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4821 
4822 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4823 	    pg->pg_txctl);
4824 
4825 	if (phy->rf_ver == 0x2050)
4826 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
4827 
4828 	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4829 }
4830 
4831 static void
4832 bwn_loopback_calcgain(struct bwn_mac *mac)
4833 {
4834 	struct bwn_phy *phy = &mac->mac_phy;
4835 	struct bwn_phy_g *pg = &phy->phy_g;
4836 	struct bwn_softc *sc = mac->mac_sc;
4837 	uint16_t backup_phy[16] = { 0 };
4838 	uint16_t backup_radio[3];
4839 	uint16_t backup_bband;
4840 	uint16_t i, j, loop_i_max;
4841 	uint16_t trsw_rx;
4842 	uint16_t loop1_outer_done, loop1_inner_done;
4843 
4844 	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4845 	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4846 	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4847 	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4848 	if (phy->rev != 1) {
4849 		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4850 		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4851 	}
4852 	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4853 	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4854 	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4855 	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4856 	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4857 	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4858 	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4859 	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4860 	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4861 	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4862 	backup_bband = pg->pg_bbatt.att;
4863 	backup_radio[0] = BWN_RF_READ(mac, 0x52);
4864 	backup_radio[1] = BWN_RF_READ(mac, 0x43);
4865 	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4866 
4867 	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4868 	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4869 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4870 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4871 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4872 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4873 	if (phy->rev != 1) {
4874 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4875 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4876 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4877 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4878 	}
4879 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4880 	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4881 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4882 	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4883 
4884 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4885 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4886 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4887 
4888 	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4889 	if (phy->rev != 1) {
4890 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4891 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4892 	}
4893 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4894 
4895 	if (phy->rf_rev == 8)
4896 		BWN_RF_WRITE(mac, 0x43, 0x000f);
4897 	else {
4898 		BWN_RF_WRITE(mac, 0x52, 0);
4899 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4900 	}
4901 	bwn_phy_g_set_bbatt(mac, 11);
4902 
4903 	if (phy->rev >= 3)
4904 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4905 	else
4906 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4907 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4908 
4909 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4910 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4911 
4912 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4913 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4914 
4915 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4916 		if (phy->rev >= 7) {
4917 			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4918 			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4919 		}
4920 	}
4921 	BWN_RF_MASK(mac, 0x7a, 0x00f7);
4922 
4923 	j = 0;
4924 	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4925 	for (i = 0; i < loop_i_max; i++) {
4926 		for (j = 0; j < 16; j++) {
4927 			BWN_RF_WRITE(mac, 0x43, i);
4928 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4929 			    (j << 8));
4930 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4931 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4932 			DELAY(20);
4933 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4934 				goto done0;
4935 		}
4936 	}
4937 done0:
4938 	loop1_outer_done = i;
4939 	loop1_inner_done = j;
4940 	if (j >= 8) {
4941 		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4942 		trsw_rx = 0x1b;
4943 		for (j = j - 8; j < 16; j++) {
4944 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4945 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4946 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4947 			DELAY(20);
4948 			trsw_rx -= 3;
4949 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4950 				goto done1;
4951 		}
4952 	} else
4953 		trsw_rx = 0x18;
4954 done1:
4955 
4956 	if (phy->rev != 1) {
4957 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4958 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4959 	}
4960 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4961 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4962 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4963 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4964 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4965 	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4966 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4967 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4968 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4969 
4970 	bwn_phy_g_set_bbatt(mac, backup_bband);
4971 
4972 	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4973 	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4974 	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4975 
4976 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4977 	DELAY(10);
4978 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4979 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4980 	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4981 	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4982 
4983 	pg->pg_max_lb_gain =
4984 	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4985 	pg->pg_trsw_rx_gain = trsw_rx * 2;
4986 }
4987 
4988 static uint16_t
4989 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4990 {
4991 	struct bwn_phy *phy = &mac->mac_phy;
4992 	uint32_t tmp1 = 0, tmp2 = 0;
4993 	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4994 	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4995 	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4996 	static const uint8_t rcc_table[] = {
4997 		0x02, 0x03, 0x01, 0x0f,
4998 		0x06, 0x07, 0x05, 0x0f,
4999 		0x0a, 0x0b, 0x09, 0x0f,
5000 		0x0e, 0x0f, 0x0d, 0x0f,
5001 	};
5002 
5003 	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5004 	    rfoverval = rfover = cck3 = 0;
5005 	radio0 = BWN_RF_READ(mac, 0x43);
5006 	radio1 = BWN_RF_READ(mac, 0x51);
5007 	radio2 = BWN_RF_READ(mac, 0x52);
5008 	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5009 	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5010 	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5011 	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5012 
5013 	if (phy->type == BWN_PHYTYPE_B) {
5014 		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5015 		reg0 = BWN_READ_2(mac, 0x3ec);
5016 
5017 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5018 		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5019 	} else if (phy->gmode || phy->rev >= 2) {
5020 		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5021 		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5022 		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5023 		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5024 		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5025 		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5026 
5027 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5028 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5029 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5030 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5031 		if (BWN_HAS_LOOPBACK(phy)) {
5032 			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5033 			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5034 			if (phy->rev >= 3)
5035 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5036 			else
5037 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5038 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5039 		}
5040 
5041 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5042 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5043 			BWN_LPD(0, 1, 1)));
5044 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5045 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5046 	}
5047 	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5048 
5049 	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5050 	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5051 	reg1 = BWN_READ_2(mac, 0x3e6);
5052 	reg2 = BWN_READ_2(mac, 0x3f4);
5053 
5054 	if (phy->analog == 0)
5055 		BWN_WRITE_2(mac, 0x03e6, 0x0122);
5056 	else {
5057 		if (phy->analog >= 2)
5058 			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5059 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5060 		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5061 	}
5062 
5063 	reg = BWN_RF_READ(mac, 0x60);
5064 	index = (reg & 0x001e) >> 1;
5065 	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5066 
5067 	if (phy->type == BWN_PHYTYPE_B)
5068 		BWN_RF_WRITE(mac, 0x78, 0x26);
5069 	if (phy->gmode || phy->rev >= 2) {
5070 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5071 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5072 			BWN_LPD(0, 1, 1)));
5073 	}
5074 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5075 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5076 	if (phy->gmode || phy->rev >= 2) {
5077 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5078 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5079 			BWN_LPD(0, 0, 1)));
5080 	}
5081 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5082 	BWN_RF_SET(mac, 0x51, 0x0004);
5083 	if (phy->rf_rev == 8)
5084 		BWN_RF_WRITE(mac, 0x43, 0x1f);
5085 	else {
5086 		BWN_RF_WRITE(mac, 0x52, 0);
5087 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5088 	}
5089 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5090 
5091 	for (i = 0; i < 16; i++) {
5092 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5093 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5094 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5095 		if (phy->gmode || phy->rev >= 2) {
5096 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5097 			    bwn_rf_2050_rfoverval(mac,
5098 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5099 		}
5100 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5101 		DELAY(10);
5102 		if (phy->gmode || phy->rev >= 2) {
5103 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5104 			    bwn_rf_2050_rfoverval(mac,
5105 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5106 		}
5107 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5108 		DELAY(10);
5109 		if (phy->gmode || phy->rev >= 2) {
5110 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5111 			    bwn_rf_2050_rfoverval(mac,
5112 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5113 		}
5114 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5115 		DELAY(20);
5116 		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5117 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5118 		if (phy->gmode || phy->rev >= 2) {
5119 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5120 			    bwn_rf_2050_rfoverval(mac,
5121 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5122 		}
5123 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5124 	}
5125 	DELAY(10);
5126 
5127 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5128 	tmp1++;
5129 	tmp1 >>= 9;
5130 
5131 	for (i = 0; i < 16; i++) {
5132 		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5133 		BWN_RF_WRITE(mac, 0x78, radio78);
5134 		DELAY(10);
5135 		for (j = 0; j < 16; j++) {
5136 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5137 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5138 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5139 			if (phy->gmode || phy->rev >= 2) {
5140 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5141 				    bwn_rf_2050_rfoverval(mac,
5142 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5143 			}
5144 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5145 			DELAY(10);
5146 			if (phy->gmode || phy->rev >= 2) {
5147 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5148 				    bwn_rf_2050_rfoverval(mac,
5149 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5150 			}
5151 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5152 			DELAY(10);
5153 			if (phy->gmode || phy->rev >= 2) {
5154 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5155 				    bwn_rf_2050_rfoverval(mac,
5156 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5157 			}
5158 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5159 			DELAY(10);
5160 			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5161 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5162 			if (phy->gmode || phy->rev >= 2) {
5163 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5164 				    bwn_rf_2050_rfoverval(mac,
5165 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5166 			}
5167 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5168 		}
5169 		tmp2++;
5170 		tmp2 >>= 8;
5171 		if (tmp1 < tmp2)
5172 			break;
5173 	}
5174 
5175 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5176 	BWN_RF_WRITE(mac, 0x51, radio1);
5177 	BWN_RF_WRITE(mac, 0x52, radio2);
5178 	BWN_RF_WRITE(mac, 0x43, radio0);
5179 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5180 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5181 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5182 	BWN_WRITE_2(mac, 0x3e6, reg1);
5183 	if (phy->analog != 0)
5184 		BWN_WRITE_2(mac, 0x3f4, reg2);
5185 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5186 	bwn_spu_workaround(mac, phy->chan);
5187 	if (phy->type == BWN_PHYTYPE_B) {
5188 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5189 		BWN_WRITE_2(mac, 0x3ec, reg0);
5190 	} else if (phy->gmode) {
5191 		BWN_WRITE_2(mac, BWN_PHY_RADIO,
5192 			    BWN_READ_2(mac, BWN_PHY_RADIO)
5193 			    & 0x7fff);
5194 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5195 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5196 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5197 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5198 			      analogoverval);
5199 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5200 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5201 		if (BWN_HAS_LOOPBACK(phy)) {
5202 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5203 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5204 		}
5205 	}
5206 
5207 	return ((i > 15) ? radio78 : rcc);
5208 }
5209 
5210 static void
5211 bwn_phy_init_b6(struct bwn_mac *mac)
5212 {
5213 	struct bwn_phy *phy = &mac->mac_phy;
5214 	struct bwn_phy_g *pg = &phy->phy_g;
5215 	struct bwn_softc *sc = mac->mac_sc;
5216 	uint16_t offset, val;
5217 	uint8_t old_channel;
5218 
5219 	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5220 	    ("%s:%d: fail", __func__, __LINE__));
5221 
5222 	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5223 	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5224 	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5225 		BWN_RF_WRITE(mac, 0x51, 0x37);
5226 		BWN_RF_WRITE(mac, 0x52, 0x70);
5227 		BWN_RF_WRITE(mac, 0x53, 0xb3);
5228 		BWN_RF_WRITE(mac, 0x54, 0x9b);
5229 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5230 		BWN_RF_WRITE(mac, 0x5b, 0x88);
5231 		BWN_RF_WRITE(mac, 0x5d, 0x88);
5232 		BWN_RF_WRITE(mac, 0x5e, 0x88);
5233 		BWN_RF_WRITE(mac, 0x7d, 0x88);
5234 		bwn_hf_write(mac,
5235 		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5236 	}
5237 	if (phy->rf_rev == 8) {
5238 		BWN_RF_WRITE(mac, 0x51, 0);
5239 		BWN_RF_WRITE(mac, 0x52, 0x40);
5240 		BWN_RF_WRITE(mac, 0x53, 0xb7);
5241 		BWN_RF_WRITE(mac, 0x54, 0x98);
5242 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5243 		BWN_RF_WRITE(mac, 0x5b, 0x6b);
5244 		BWN_RF_WRITE(mac, 0x5c, 0x0f);
5245 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5246 			BWN_RF_WRITE(mac, 0x5d, 0xfa);
5247 			BWN_RF_WRITE(mac, 0x5e, 0xd8);
5248 		} else {
5249 			BWN_RF_WRITE(mac, 0x5d, 0xf5);
5250 			BWN_RF_WRITE(mac, 0x5e, 0xb8);
5251 		}
5252 		BWN_RF_WRITE(mac, 0x0073, 0x0003);
5253 		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5254 		BWN_RF_WRITE(mac, 0x007c, 0x0001);
5255 		BWN_RF_WRITE(mac, 0x007e, 0x0008);
5256 	}
5257 	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5258 		BWN_PHY_WRITE(mac, offset, val);
5259 		val -= 0x0202;
5260 	}
5261 	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5262 		BWN_PHY_WRITE(mac, offset, val);
5263 		val -= 0x0202;
5264 	}
5265 	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5266 		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5267 		val += 0x0202;
5268 	}
5269 	if (phy->type == BWN_PHYTYPE_G) {
5270 		BWN_RF_SET(mac, 0x007a, 0x0020);
5271 		BWN_RF_SET(mac, 0x0051, 0x0004);
5272 		BWN_PHY_SET(mac, 0x0802, 0x0100);
5273 		BWN_PHY_SET(mac, 0x042b, 0x2000);
5274 		BWN_PHY_WRITE(mac, 0x5b, 0);
5275 		BWN_PHY_WRITE(mac, 0x5c, 0);
5276 	}
5277 
5278 	old_channel = phy->chan;
5279 	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5280 
5281 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
5282 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
5283 	DELAY(40);
5284 	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5285 		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5286 		BWN_RF_WRITE(mac, 0x50, 0x20);
5287 	}
5288 	if (phy->rf_rev <= 2) {
5289 		BWN_RF_WRITE(mac, 0x7c, 0x20);
5290 		BWN_RF_WRITE(mac, 0x5a, 0x70);
5291 		BWN_RF_WRITE(mac, 0x5b, 0x7b);
5292 		BWN_RF_WRITE(mac, 0x5c, 0xb0);
5293 	}
5294 	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5295 
5296 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5297 
5298 	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5299 	if (phy->rf_rev >= 6)
5300 		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5301 	else
5302 		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5303 	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5304 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5305 	    pg->pg_txctl);
5306 	if (phy->rf_rev <= 5)
5307 		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5308 	if (phy->rf_rev <= 2)
5309 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5310 
5311 	if (phy->analog == 4) {
5312 		BWN_WRITE_2(mac, 0x3e4, 9);
5313 		BWN_PHY_MASK(mac, 0x61, 0x0fff);
5314 	} else
5315 		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5316 	if (phy->type == BWN_PHYTYPE_B)
5317 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5318 	else if (phy->type == BWN_PHYTYPE_G)
5319 		BWN_WRITE_2(mac, 0x03e6, 0x0);
5320 }
5321 
5322 static void
5323 bwn_phy_init_a(struct bwn_mac *mac)
5324 {
5325 	struct bwn_phy *phy = &mac->mac_phy;
5326 	struct bwn_softc *sc = mac->mac_sc;
5327 
5328 	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5329 	    ("%s:%d: fail", __func__, __LINE__));
5330 
5331 	if (phy->rev >= 6) {
5332 		if (phy->type == BWN_PHYTYPE_A)
5333 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5334 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5335 			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5336 		else
5337 			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5338 	}
5339 
5340 	bwn_wa_init(mac);
5341 
5342 	if (phy->type == BWN_PHYTYPE_G &&
5343 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5344 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5345 }
5346 
5347 static void
5348 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5349 {
5350 	int i;
5351 
5352 	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5353 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5354 }
5355 
5356 static void
5357 bwn_wa_agc(struct bwn_mac *mac)
5358 {
5359 	struct bwn_phy *phy = &mac->mac_phy;
5360 
5361 	if (phy->rev == 1) {
5362 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5363 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5364 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5365 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5366 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5367 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5368 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5369 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5370 		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5371 	} else {
5372 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5373 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5374 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5375 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5376 	}
5377 
5378 	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5379 	    0x5700);
5380 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5381 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5382 	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5383 	BWN_RF_SET(mac, 0x7a, 0x0008);
5384 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5385 	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5386 	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5387 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5388 	if (phy->rev == 1)
5389 		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5390 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5391 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5392 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5393 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5394 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5395 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5396 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5397 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5398 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5399 	if (phy->rev == 1) {
5400 		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5401 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5402 	} else {
5403 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5404 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5405 		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5406 		if (phy->rev >= 6) {
5407 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5408 			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5409 			    (uint16_t)~0xf000, 0x3000);
5410 		}
5411 	}
5412 	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5413 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5414 	if (phy->rev == 1) {
5415 		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5416 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5417 		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5418 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5419 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5420 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5421 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5422 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5423 	} else {
5424 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5425 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5426 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5427 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5428 	}
5429 	if (phy->rev >= 6) {
5430 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5431 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5432 	}
5433 	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5434 }
5435 
5436 static void
5437 bwn_wa_grev1(struct bwn_mac *mac)
5438 {
5439 	struct bwn_phy *phy = &mac->mac_phy;
5440 	int i;
5441 	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5442 	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5443 	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5444 
5445 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5446 
5447 	/* init CRSTHRES and ANTDWELL */
5448 	if (phy->rev == 1) {
5449 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5450 	} else if (phy->rev == 2) {
5451 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5452 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5453 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5454 	} else {
5455 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5456 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5457 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5458 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5459 	}
5460 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5461 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5462 	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5463 
5464 	/* XXX support PHY-A??? */
5465 	for (i = 0; i < N(bwn_tab_finefreqg); i++)
5466 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5467 		    bwn_tab_finefreqg[i]);
5468 
5469 	/* XXX support PHY-A??? */
5470 	if (phy->rev == 1)
5471 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5472 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5473 			    bwn_tab_noise_g1[i]);
5474 	else
5475 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5476 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5477 			    bwn_tab_noise_g2[i]);
5478 
5479 
5480 	for (i = 0; i < N(bwn_tab_rotor); i++)
5481 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5482 		    bwn_tab_rotor[i]);
5483 
5484 	/* XXX support PHY-A??? */
5485 	if (phy->rev >= 6) {
5486 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5487 		    BWN_PHY_ENCORE_EN)
5488 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5489 		else
5490 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5491 	} else
5492 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5493 
5494 	for (i = 0; i < N(bwn_tab_retard); i++)
5495 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5496 		    bwn_tab_retard[i]);
5497 
5498 	if (phy->rev == 1) {
5499 		for (i = 0; i < 16; i++)
5500 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5501 			    i, 0x0020);
5502 	} else {
5503 		for (i = 0; i < 32; i++)
5504 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5505 	}
5506 
5507 	bwn_wa_agc(mac);
5508 }
5509 
5510 static void
5511 bwn_wa_grev26789(struct bwn_mac *mac)
5512 {
5513 	struct bwn_phy *phy = &mac->mac_phy;
5514 	int i;
5515 	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5516 	uint16_t ofdmrev;
5517 
5518 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5519 
5520 	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5521 
5522 	/* init CRSTHRES and ANTDWELL */
5523 	if (phy->rev == 1)
5524 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5525 	else if (phy->rev == 2) {
5526 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5527 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5528 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5529 	} else {
5530 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5531 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5532 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5533 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5534 	}
5535 
5536 	for (i = 0; i < 64; i++)
5537 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5538 
5539 	/* XXX support PHY-A??? */
5540 	if (phy->rev == 1)
5541 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5542 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5543 			    bwn_tab_noise_g1[i]);
5544 	else
5545 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5546 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5547 			    bwn_tab_noise_g2[i]);
5548 
5549 	/* XXX support PHY-A??? */
5550 	if (phy->rev >= 6) {
5551 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5552 		    BWN_PHY_ENCORE_EN)
5553 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5554 		else
5555 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5556 	} else
5557 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5558 
5559 	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5560 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5561 		    bwn_tab_sigmasqr2[i]);
5562 
5563 	if (phy->rev == 1) {
5564 		for (i = 0; i < 16; i++)
5565 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5566 			    0x0020);
5567 	} else {
5568 		for (i = 0; i < 32; i++)
5569 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5570 	}
5571 
5572 	bwn_wa_agc(mac);
5573 
5574 	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5575 	if (ofdmrev > 2) {
5576 		if (phy->type == BWN_PHYTYPE_A)
5577 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5578 		else
5579 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5580 	} else {
5581 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5582 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5583 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5584 	}
5585 
5586 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5587 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5588 }
5589 
5590 static void
5591 bwn_wa_init(struct bwn_mac *mac)
5592 {
5593 	struct bwn_phy *phy = &mac->mac_phy;
5594 	struct bwn_softc *sc = mac->mac_sc;
5595 
5596 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5597 
5598 	switch (phy->rev) {
5599 	case 1:
5600 		bwn_wa_grev1(mac);
5601 		break;
5602 	case 2:
5603 	case 6:
5604 	case 7:
5605 	case 8:
5606 	case 9:
5607 		bwn_wa_grev26789(mac);
5608 		break;
5609 	default:
5610 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5611 	}
5612 
5613 	if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5614 	    siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5615 	    siba_get_pci_revid(sc->sc_dev) != 0x17) {
5616 		if (phy->rev < 2) {
5617 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5618 			    0x0002);
5619 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5620 			    0x0001);
5621 		} else {
5622 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5623 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5624 			if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5625 			     BWN_BFL_EXTLNA) &&
5626 			    (phy->rev >= 7)) {
5627 				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5628 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5629 				    0x0020, 0x0001);
5630 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5631 				    0x0021, 0x0001);
5632 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5633 				    0x0022, 0x0001);
5634 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5635 				    0x0023, 0x0000);
5636 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5637 				    0x0000, 0x0000);
5638 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5639 				    0x0003, 0x0002);
5640 			}
5641 		}
5642 	}
5643 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5644 		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5645 		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5646 	}
5647 
5648 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5649 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5650 }
5651 
5652 static void
5653 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5654     uint16_t value)
5655 {
5656 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5657 	uint16_t addr;
5658 
5659 	addr = table + offset;
5660 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5661 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5662 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5663 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5664 	}
5665 	pg->pg_ofdmtab_addr = addr;
5666 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5667 }
5668 
5669 static void
5670 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5671     uint32_t value)
5672 {
5673 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5674 	uint16_t addr;
5675 
5676 	addr = table + offset;
5677 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5678 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5679 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5680 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5681 	}
5682 	pg->pg_ofdmtab_addr = addr;
5683 
5684 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5685 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5686 }
5687 
5688 static void
5689 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5690     uint16_t value)
5691 {
5692 
5693 	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5694 	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5695 }
5696 
5697 static void
5698 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5699 {
5700 	struct bwn_phy *phy = &mac->mac_phy;
5701 	struct bwn_softc *sc = mac->mac_sc;
5702 	unsigned int i, max_loop;
5703 	uint16_t value;
5704 	uint32_t buffer[5] = {
5705 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5706 	};
5707 
5708 	if (ofdm) {
5709 		max_loop = 0x1e;
5710 		buffer[0] = 0x000201cc;
5711 	} else {
5712 		max_loop = 0xfa;
5713 		buffer[0] = 0x000b846e;
5714 	}
5715 
5716 	for (i = 0; i < 5; i++)
5717 		bwn_ram_write(mac, i * 4, buffer[i]);
5718 
5719 	BWN_WRITE_2(mac, 0x0568, 0x0000);
5720 	BWN_WRITE_2(mac, 0x07c0,
5721 	    (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5722 	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5723 	BWN_WRITE_2(mac, 0x050c, value);
5724 	if (phy->type == BWN_PHYTYPE_LP)
5725 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
5726 	BWN_WRITE_2(mac, 0x0508, 0x0000);
5727 	BWN_WRITE_2(mac, 0x050a, 0x0000);
5728 	BWN_WRITE_2(mac, 0x054c, 0x0000);
5729 	BWN_WRITE_2(mac, 0x056a, 0x0014);
5730 	BWN_WRITE_2(mac, 0x0568, 0x0826);
5731 	BWN_WRITE_2(mac, 0x0500, 0x0000);
5732 	if (phy->type == BWN_PHYTYPE_LP)
5733 		BWN_WRITE_2(mac, 0x0502, 0x0050);
5734 	else
5735 		BWN_WRITE_2(mac, 0x0502, 0x0030);
5736 
5737 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5738 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
5739 	for (i = 0x00; i < max_loop; i++) {
5740 		value = BWN_READ_2(mac, 0x050e);
5741 		if (value & 0x0080)
5742 			break;
5743 		DELAY(10);
5744 	}
5745 	for (i = 0x00; i < 0x0a; i++) {
5746 		value = BWN_READ_2(mac, 0x050e);
5747 		if (value & 0x0400)
5748 			break;
5749 		DELAY(10);
5750 	}
5751 	for (i = 0x00; i < 0x19; i++) {
5752 		value = BWN_READ_2(mac, 0x0690);
5753 		if (!(value & 0x0100))
5754 			break;
5755 		DELAY(10);
5756 	}
5757 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5758 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
5759 }
5760 
5761 static void
5762 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5763 {
5764 	uint32_t macctl;
5765 
5766 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5767 
5768 	macctl = BWN_READ_4(mac, BWN_MACCTL);
5769 	if (macctl & BWN_MACCTL_BIGENDIAN)
5770 		kprintf("TODO: need swap\n");
5771 
5772 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5773 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5774 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5775 }
5776 
5777 static void
5778 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5779 {
5780 	uint16_t value;
5781 
5782 	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5783 	    ("%s:%d: fail", __func__, __LINE__));
5784 
5785 	value = (uint8_t) (ctl->q);
5786 	value |= ((uint8_t) (ctl->i)) << 8;
5787 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5788 }
5789 
5790 static uint16_t
5791 bwn_lo_calcfeed(struct bwn_mac *mac,
5792     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5793 {
5794 	struct bwn_phy *phy = &mac->mac_phy;
5795 	struct bwn_softc *sc = mac->mac_sc;
5796 	uint16_t rfover;
5797 	uint16_t feedthrough;
5798 
5799 	if (phy->gmode) {
5800 		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5801 		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5802 
5803 		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5804 		    ("%s:%d: fail", __func__, __LINE__));
5805 		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5806 		    ("%s:%d: fail", __func__, __LINE__));
5807 
5808 		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5809 
5810 		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5811 		if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5812 		    phy->rev > 6)
5813 			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5814 
5815 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5816 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5817 		DELAY(10);
5818 		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5819 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5820 		DELAY(10);
5821 		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5822 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5823 		DELAY(10);
5824 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5825 	} else {
5826 		pga |= BWN_PHY_PGACTL_UNKNOWN;
5827 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5828 		DELAY(10);
5829 		pga |= BWN_PHY_PGACTL_LOWBANDW;
5830 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5831 		DELAY(10);
5832 		pga |= BWN_PHY_PGACTL_LPF;
5833 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5834 	}
5835 	DELAY(21);
5836 	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5837 
5838 	return (feedthrough);
5839 }
5840 
5841 static uint16_t
5842 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5843     uint16_t *value, uint16_t *pad_mix_gain)
5844 {
5845 	struct bwn_phy *phy = &mac->mac_phy;
5846 	uint16_t reg, v, padmix;
5847 
5848 	if (phy->type == BWN_PHYTYPE_B) {
5849 		v = 0x30;
5850 		if (phy->rf_rev <= 5) {
5851 			reg = 0x43;
5852 			padmix = 0;
5853 		} else {
5854 			reg = 0x52;
5855 			padmix = 5;
5856 		}
5857 	} else {
5858 		if (phy->rev >= 2 && phy->rf_rev == 8) {
5859 			reg = 0x43;
5860 			v = 0x10;
5861 			padmix = 2;
5862 		} else {
5863 			reg = 0x52;
5864 			v = 0x30;
5865 			padmix = 5;
5866 		}
5867 	}
5868 	if (value)
5869 		*value = v;
5870 	if (pad_mix_gain)
5871 		*pad_mix_gain = padmix;
5872 
5873 	return (reg);
5874 }
5875 
5876 static void
5877 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5878 {
5879 	struct bwn_phy *phy = &mac->mac_phy;
5880 	struct bwn_phy_g *pg = &phy->phy_g;
5881 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5882 	uint16_t reg, mask;
5883 	uint16_t trsw_rx, pga;
5884 	uint16_t rf_pctl_reg;
5885 
5886 	static const uint8_t tx_bias_values[] = {
5887 		0x09, 0x08, 0x0a, 0x01, 0x00,
5888 		0x02, 0x05, 0x04, 0x06,
5889 	};
5890 	static const uint8_t tx_magn_values[] = {
5891 		0x70, 0x40,
5892 	};
5893 
5894 	if (!BWN_HAS_LOOPBACK(phy)) {
5895 		rf_pctl_reg = 6;
5896 		trsw_rx = 2;
5897 		pga = 0;
5898 	} else {
5899 		int lb_gain;
5900 
5901 		trsw_rx = 0;
5902 		lb_gain = pg->pg_max_lb_gain / 2;
5903 		if (lb_gain > 10) {
5904 			rf_pctl_reg = 0;
5905 			pga = abs(10 - lb_gain) / 6;
5906 			pga = MIN(MAX(pga, 0), 15);
5907 		} else {
5908 			int cmp_val;
5909 			int tmp;
5910 
5911 			pga = 0;
5912 			cmp_val = 0x24;
5913 			if ((phy->rev >= 2) &&
5914 			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5915 				cmp_val = 0x3c;
5916 			tmp = lb_gain;
5917 			if ((10 - lb_gain) < cmp_val)
5918 				tmp = (10 - lb_gain);
5919 			if (tmp < 0)
5920 				tmp += 6;
5921 			else
5922 				tmp += 3;
5923 			cmp_val /= 4;
5924 			tmp /= 4;
5925 			if (tmp >= cmp_val)
5926 				rf_pctl_reg = cmp_val;
5927 			else
5928 				rf_pctl_reg = tmp;
5929 		}
5930 	}
5931 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5932 	bwn_phy_g_set_bbatt(mac, 2);
5933 
5934 	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5935 	mask = ~mask;
5936 	BWN_RF_MASK(mac, reg, mask);
5937 
5938 	if (BWN_HAS_TXMAG(phy)) {
5939 		int i, j;
5940 		int feedthrough;
5941 		int min_feedth = 0xffff;
5942 		uint8_t tx_magn, tx_bias;
5943 
5944 		for (i = 0; i < N(tx_magn_values); i++) {
5945 			tx_magn = tx_magn_values[i];
5946 			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5947 			for (j = 0; j < N(tx_bias_values); j++) {
5948 				tx_bias = tx_bias_values[j];
5949 				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5950 				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5951 				    trsw_rx);
5952 				if (feedthrough < min_feedth) {
5953 					lo->tx_bias = tx_bias;
5954 					lo->tx_magn = tx_magn;
5955 					min_feedth = feedthrough;
5956 				}
5957 				if (lo->tx_bias == 0)
5958 					break;
5959 			}
5960 			BWN_RF_WRITE(mac, 0x52,
5961 					  (BWN_RF_READ(mac, 0x52)
5962 					   & 0xff00) | lo->tx_bias | lo->
5963 					  tx_magn);
5964 		}
5965 	} else {
5966 		lo->tx_magn = 0;
5967 		lo->tx_bias = 0;
5968 		BWN_RF_MASK(mac, 0x52, 0xfff0);
5969 	}
5970 
5971 	BWN_GETTIME(lo->txctl_measured_time);
5972 }
5973 
5974 static void
5975 bwn_lo_get_powervector(struct bwn_mac *mac)
5976 {
5977 	struct bwn_phy *phy = &mac->mac_phy;
5978 	struct bwn_phy_g *pg = &phy->phy_g;
5979 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5980 	int i;
5981 	uint64_t tmp;
5982 	uint64_t power_vector = 0;
5983 
5984 	for (i = 0; i < 8; i += 2) {
5985 		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5986 		power_vector |= (tmp << (i * 8));
5987 		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5988 	}
5989 	if (power_vector)
5990 		lo->power_vector = power_vector;
5991 
5992 	BWN_GETTIME(lo->pwr_vec_read_time);
5993 }
5994 
5995 static void
5996 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5997     int use_trsw_rx)
5998 {
5999 	struct bwn_phy *phy = &mac->mac_phy;
6000 	struct bwn_phy_g *pg = &phy->phy_g;
6001 	uint16_t tmp;
6002 
6003 	if (max_rx_gain < 0)
6004 		max_rx_gain = 0;
6005 
6006 	if (BWN_HAS_LOOPBACK(phy)) {
6007 		int trsw_rx = 0;
6008 		int trsw_rx_gain;
6009 
6010 		if (use_trsw_rx) {
6011 			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6012 			if (max_rx_gain >= trsw_rx_gain) {
6013 				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6014 				trsw_rx = 0x20;
6015 			}
6016 		} else
6017 			trsw_rx_gain = max_rx_gain;
6018 		if (trsw_rx_gain < 9) {
6019 			pg->pg_lna_lod_gain = 0;
6020 		} else {
6021 			pg->pg_lna_lod_gain = 1;
6022 			trsw_rx_gain -= 8;
6023 		}
6024 		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6025 		pg->pg_pga_gain = trsw_rx_gain / 3;
6026 		if (pg->pg_pga_gain >= 5) {
6027 			pg->pg_pga_gain -= 5;
6028 			pg->pg_lna_gain = 2;
6029 		} else
6030 			pg->pg_lna_gain = 0;
6031 	} else {
6032 		pg->pg_lna_gain = 0;
6033 		pg->pg_trsw_rx_gain = 0x20;
6034 		if (max_rx_gain >= 0x14) {
6035 			pg->pg_lna_lod_gain = 1;
6036 			pg->pg_pga_gain = 2;
6037 		} else if (max_rx_gain >= 0x12) {
6038 			pg->pg_lna_lod_gain = 1;
6039 			pg->pg_pga_gain = 1;
6040 		} else if (max_rx_gain >= 0xf) {
6041 			pg->pg_lna_lod_gain = 1;
6042 			pg->pg_pga_gain = 0;
6043 		} else {
6044 			pg->pg_lna_lod_gain = 0;
6045 			pg->pg_pga_gain = 0;
6046 		}
6047 	}
6048 
6049 	tmp = BWN_RF_READ(mac, 0x7a);
6050 	if (pg->pg_lna_lod_gain == 0)
6051 		tmp &= ~0x0008;
6052 	else
6053 		tmp |= 0x0008;
6054 	BWN_RF_WRITE(mac, 0x7a, tmp);
6055 }
6056 
6057 static void
6058 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6059 {
6060 	struct bwn_phy *phy = &mac->mac_phy;
6061 	struct bwn_phy_g *pg = &phy->phy_g;
6062 	struct bwn_softc *sc = mac->mac_sc;
6063 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6064 	struct timespec ts;
6065 	uint16_t tmp;
6066 
6067 	if (bwn_has_hwpctl(mac)) {
6068 		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6069 		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6070 		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6071 		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6072 		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6073 
6074 		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6075 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6076 		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6077 		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6078 	}
6079 	if (phy->type == BWN_PHYTYPE_B &&
6080 	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6081 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6082 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6083 	}
6084 	if (phy->rev >= 2) {
6085 		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6086 		sav->phy_analogoverval =
6087 		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6088 		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6089 		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6090 		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6091 		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6092 		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6093 
6094 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6095 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6096 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6097 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6098 		if (phy->type == BWN_PHYTYPE_G) {
6099 			if ((phy->rev >= 7) &&
6100 			    (siba_sprom_get_bf_lo(sc->sc_dev) &
6101 			     BWN_BFL_EXTLNA)) {
6102 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6103 			} else {
6104 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6105 			}
6106 		} else {
6107 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6108 		}
6109 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6110 	}
6111 	sav->reg0 = BWN_READ_2(mac, 0x3f4);
6112 	sav->reg1 = BWN_READ_2(mac, 0x3e2);
6113 	sav->rf0 = BWN_RF_READ(mac, 0x43);
6114 	sav->rf1 = BWN_RF_READ(mac, 0x7a);
6115 	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6116 	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6117 	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6118 	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6119 
6120 	if (!BWN_HAS_TXMAG(phy)) {
6121 		sav->rf2 = BWN_RF_READ(mac, 0x52);
6122 		sav->rf2 &= 0x00f0;
6123 	}
6124 	if (phy->type == BWN_PHYTYPE_B) {
6125 		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6126 		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6127 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6128 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6129 	} else {
6130 		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6131 			    | 0x8000);
6132 	}
6133 	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6134 		    & 0xf000);
6135 
6136 	tmp =
6137 	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6138 	BWN_PHY_WRITE(mac, tmp, 0x007f);
6139 
6140 	tmp = sav->phy_syncctl;
6141 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6142 	tmp = sav->rf1;
6143 	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6144 
6145 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6146 	if (phy->type == BWN_PHYTYPE_G ||
6147 	    (phy->type == BWN_PHYTYPE_B &&
6148 	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6149 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6150 	} else
6151 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6152 	if (phy->rev >= 2)
6153 		bwn_dummy_transmission(mac, 0, 1);
6154 	bwn_phy_g_switch_chan(mac, 6, 0);
6155 	BWN_RF_READ(mac, 0x51);
6156 	if (phy->type == BWN_PHYTYPE_G)
6157 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6158 
6159 	nanouptime(&ts);
6160 	if (time_before(lo->txctl_measured_time,
6161 	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6162 		bwn_lo_measure_txctl_values(mac);
6163 
6164 	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6165 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6166 	else {
6167 		if (phy->type == BWN_PHYTYPE_B)
6168 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6169 		else
6170 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6171 	}
6172 }
6173 
6174 static void
6175 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6176 {
6177 	struct bwn_phy *phy = &mac->mac_phy;
6178 	struct bwn_phy_g *pg = &phy->phy_g;
6179 	uint16_t tmp;
6180 
6181 	if (phy->rev >= 2) {
6182 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6183 		tmp = (pg->pg_pga_gain << 8);
6184 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6185 		DELAY(5);
6186 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6187 		DELAY(2);
6188 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6189 	} else {
6190 		tmp = (pg->pg_pga_gain | 0xefa0);
6191 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6192 	}
6193 	if (phy->type == BWN_PHYTYPE_G) {
6194 		if (phy->rev >= 3)
6195 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6196 		else
6197 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6198 		if (phy->rev >= 2)
6199 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6200 		else
6201 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6202 	}
6203 	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6204 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6205 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6206 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6207 	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6208 	BWN_RF_WRITE(mac, 0x43, sav->rf0);
6209 	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6210 	if (!BWN_HAS_TXMAG(phy)) {
6211 		tmp = sav->rf2;
6212 		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6213 	}
6214 	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6215 	if (phy->type == BWN_PHYTYPE_B &&
6216 	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6217 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6218 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6219 	}
6220 	if (phy->rev >= 2) {
6221 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6222 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6223 			      sav->phy_analogoverval);
6224 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6225 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6226 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6227 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6228 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6229 	}
6230 	if (bwn_has_hwpctl(mac)) {
6231 		tmp = (sav->phy_lomask & 0xbfff);
6232 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6233 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6234 		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6235 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6236 		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6237 	}
6238 	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6239 }
6240 
6241 static int
6242 bwn_lo_probe_loctl(struct bwn_mac *mac,
6243     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6244 {
6245 	struct bwn_phy *phy = &mac->mac_phy;
6246 	struct bwn_phy_g *pg = &phy->phy_g;
6247 	struct bwn_loctl orig, test;
6248 	struct bwn_loctl prev = { -100, -100 };
6249 	static const struct bwn_loctl modifiers[] = {
6250 		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6251 		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6252 	};
6253 	int begin, end, lower = 0, i;
6254 	uint16_t feedth;
6255 
6256 	if (d->curstate == 0) {
6257 		begin = 1;
6258 		end = 8;
6259 	} else if (d->curstate % 2 == 0) {
6260 		begin = d->curstate - 1;
6261 		end = d->curstate + 1;
6262 	} else {
6263 		begin = d->curstate - 2;
6264 		end = d->curstate + 2;
6265 	}
6266 	if (begin < 1)
6267 		begin += 8;
6268 	if (end > 8)
6269 		end -= 8;
6270 
6271 	memcpy(&orig, probe, sizeof(struct bwn_loctl));
6272 	i = begin;
6273 	d->curstate = i;
6274 	while (1) {
6275 		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6276 		memcpy(&test, &orig, sizeof(struct bwn_loctl));
6277 		test.i += modifiers[i - 1].i * d->multipler;
6278 		test.q += modifiers[i - 1].q * d->multipler;
6279 		if ((test.i != prev.i || test.q != prev.q) &&
6280 		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6281 			bwn_lo_write(mac, &test);
6282 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6283 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6284 			if (feedth < d->feedth) {
6285 				memcpy(probe, &test,
6286 				    sizeof(struct bwn_loctl));
6287 				lower = 1;
6288 				d->feedth = feedth;
6289 				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6290 					break;
6291 			}
6292 		}
6293 		memcpy(&prev, &test, sizeof(prev));
6294 		if (i == end)
6295 			break;
6296 		if (i == 8)
6297 			i = 1;
6298 		else
6299 			i++;
6300 		d->curstate = i;
6301 	}
6302 
6303 	return (lower);
6304 }
6305 
6306 static void
6307 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6308 {
6309 	struct bwn_phy *phy = &mac->mac_phy;
6310 	struct bwn_phy_g *pg = &phy->phy_g;
6311 	struct bwn_lo_g_sm d;
6312 	struct bwn_loctl probe;
6313 	int lower, repeat, cnt = 0;
6314 	uint16_t feedth;
6315 
6316 	d.nmeasure = 0;
6317 	d.multipler = 1;
6318 	if (BWN_HAS_LOOPBACK(phy))
6319 		d.multipler = 3;
6320 
6321 	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6322 	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6323 
6324 	do {
6325 		bwn_lo_write(mac, &d.loctl);
6326 		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6327 		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6328 		if (feedth < 0x258) {
6329 			if (feedth >= 0x12c)
6330 				*rxgain += 6;
6331 			else
6332 				*rxgain += 3;
6333 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6334 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6335 		}
6336 		d.feedth = feedth;
6337 		d.curstate = 0;
6338 		do {
6339 			KASSERT(d.curstate >= 0 && d.curstate <= 8,
6340 			    ("%s:%d: fail", __func__, __LINE__));
6341 			memcpy(&probe, &d.loctl,
6342 			       sizeof(struct bwn_loctl));
6343 			lower = bwn_lo_probe_loctl(mac, &probe, &d);
6344 			if (!lower)
6345 				break;
6346 			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6347 				break;
6348 			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6349 			d.nmeasure++;
6350 		} while (d.nmeasure < 24);
6351 		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6352 
6353 		if (BWN_HAS_LOOPBACK(phy)) {
6354 			if (d.feedth > 0x1194)
6355 				*rxgain -= 6;
6356 			else if (d.feedth < 0x5dc)
6357 				*rxgain += 3;
6358 			if (cnt == 0) {
6359 				if (d.feedth <= 0x5dc) {
6360 					d.multipler = 1;
6361 					cnt++;
6362 				} else
6363 					d.multipler = 2;
6364 			} else if (cnt == 2)
6365 				d.multipler = 1;
6366 		}
6367 		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6368 	} while (++cnt < repeat);
6369 }
6370 
6371 static struct bwn_lo_calib *
6372 bwn_lo_calibset(struct bwn_mac *mac,
6373     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6374 {
6375 	struct bwn_phy *phy = &mac->mac_phy;
6376 	struct bwn_phy_g *pg = &phy->phy_g;
6377 	struct bwn_loctl loctl = { 0, 0 };
6378 	struct bwn_lo_calib *cal;
6379 	struct bwn_lo_g_value sval = { 0 };
6380 	int rxgain;
6381 	uint16_t pad, reg, value;
6382 
6383 	sval.old_channel = phy->chan;
6384 	bwn_mac_suspend(mac);
6385 	bwn_lo_save(mac, &sval);
6386 
6387 	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6388 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6389 	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6390 
6391 	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6392 	if (rfatt->padmix)
6393 		rxgain -= pad;
6394 	if (BWN_HAS_LOOPBACK(phy))
6395 		rxgain += pg->pg_max_lb_gain;
6396 	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6397 	bwn_phy_g_set_bbatt(mac, bbatt->att);
6398 	bwn_lo_probe_sm(mac, &loctl, &rxgain);
6399 
6400 	bwn_lo_restore(mac, &sval);
6401 	bwn_mac_enable(mac);
6402 
6403 	cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO);
6404 	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6405 	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6406 	memcpy(&cal->ctl, &loctl, sizeof(loctl));
6407 
6408 	BWN_GETTIME(cal->calib_time);
6409 
6410 	return (cal);
6411 }
6412 
6413 static struct bwn_lo_calib *
6414 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6415     const struct bwn_rfatt *rfatt)
6416 {
6417 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6418 	struct bwn_lo_calib *c;
6419 
6420 	TAILQ_FOREACH(c, &lo->calib_list, list) {
6421 		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6422 			continue;
6423 		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6424 			continue;
6425 		return (c);
6426 	}
6427 
6428 	c = bwn_lo_calibset(mac, bbatt, rfatt);
6429 	if (c == NULL)	/* XXX ivadasz: can't happen */
6430 		return (NULL);
6431 	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6432 
6433 	return (c);
6434 }
6435 
6436 static void
6437 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6438 {
6439 	struct bwn_phy *phy = &mac->mac_phy;
6440 	struct bwn_phy_g *pg = &phy->phy_g;
6441 	struct bwn_softc *sc = mac->mac_sc;
6442 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6443 	const struct bwn_rfatt *rfatt;
6444 	const struct bwn_bbatt *bbatt;
6445 	uint64_t pvector;
6446 	int i;
6447 	int rf_offset, bb_offset;
6448 	uint8_t changed = 0;
6449 
6450 	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6451 	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6452 	    ("%s:%d: fail", __func__, __LINE__));
6453 
6454 	pvector = lo->power_vector;
6455 	if (!update && !pvector)
6456 		return;
6457 
6458 	bwn_mac_suspend(mac);
6459 
6460 	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6461 		struct bwn_lo_calib *cal;
6462 		int idx;
6463 		uint16_t val;
6464 
6465 		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6466 			continue;
6467 		bb_offset = i / lo->rfatt.len;
6468 		rf_offset = i % lo->rfatt.len;
6469 		bbatt = &(lo->bbatt.array[bb_offset]);
6470 		rfatt = &(lo->rfatt.array[rf_offset]);
6471 
6472 		cal = bwn_lo_calibset(mac, bbatt, rfatt);
6473 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
6474 			device_printf(sc->sc_dev, "LO: Could not "
6475 			    "calibrate DC table entry\n");
6476 			continue;
6477 		}
6478 		val = (uint8_t)(cal->ctl.q);
6479 		val |= ((uint8_t)(cal->ctl.i)) << 4;
6480 		kfree(cal, M_DEVBUF);
6481 
6482 		idx = i / 2;
6483 		if (i % 2)
6484 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6485 			    | ((val & 0x00ff) << 8);
6486 		else
6487 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6488 			    | (val & 0x00ff);
6489 		changed = 1;
6490 	}
6491 	if (changed) {
6492 		for (i = 0; i < BWN_DC_LT_SIZE; i++)
6493 			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6494 	}
6495 	bwn_mac_enable(mac);
6496 }
6497 
6498 static void
6499 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6500 {
6501 
6502 	if (!rf->padmix)
6503 		return;
6504 	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6505 		rf->att = 4;
6506 }
6507 
6508 static void
6509 bwn_lo_g_adjust(struct bwn_mac *mac)
6510 {
6511 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6512 	struct bwn_lo_calib *cal;
6513 	struct bwn_rfatt rf;
6514 
6515 	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6516 	bwn_lo_fixup_rfatt(&rf);
6517 
6518 	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6519 	if (cal == NULL)	/* XXX ivadasz: can't happen */
6520 		return;
6521 	bwn_lo_write(mac, &cal->ctl);
6522 }
6523 
6524 static void
6525 bwn_lo_g_init(struct bwn_mac *mac)
6526 {
6527 
6528 	if (!bwn_has_hwpctl(mac))
6529 		return;
6530 
6531 	bwn_lo_get_powervector(mac);
6532 	bwn_phy_g_dc_lookup_init(mac, 1);
6533 }
6534 
6535 static void
6536 bwn_mac_suspend(struct bwn_mac *mac)
6537 {
6538 	struct bwn_softc *sc = mac->mac_sc;
6539 	int i;
6540 	uint32_t tmp;
6541 
6542 	KASSERT(mac->mac_suspended >= 0,
6543 	    ("%s:%d: fail", __func__, __LINE__));
6544 
6545 	if (mac->mac_suspended == 0) {
6546 		bwn_psctl(mac, BWN_PS_AWAKE);
6547 		BWN_WRITE_4(mac, BWN_MACCTL,
6548 			    BWN_READ_4(mac, BWN_MACCTL)
6549 			    & ~BWN_MACCTL_ON);
6550 		BWN_READ_4(mac, BWN_MACCTL);
6551 		for (i = 35; i; i--) {
6552 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6553 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6554 				goto out;
6555 			DELAY(10);
6556 		}
6557 		for (i = 40; i; i--) {
6558 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6559 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6560 				goto out;
6561 			DELAY(1000);
6562 		}
6563 		device_printf(sc->sc_dev, "MAC suspend failed\n");
6564 	}
6565 out:
6566 	mac->mac_suspended++;
6567 }
6568 
6569 static void
6570 bwn_mac_enable(struct bwn_mac *mac)
6571 {
6572 	struct bwn_softc *sc = mac->mac_sc;
6573 	uint16_t state;
6574 
6575 	state = bwn_shm_read_2(mac, BWN_SHARED,
6576 	    BWN_SHARED_UCODESTAT);
6577 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6578 	    state != BWN_SHARED_UCODESTAT_SLEEP)
6579 		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6580 
6581 	mac->mac_suspended--;
6582 	KASSERT(mac->mac_suspended >= 0,
6583 	    ("%s:%d: fail", __func__, __LINE__));
6584 	if (mac->mac_suspended == 0) {
6585 		BWN_WRITE_4(mac, BWN_MACCTL,
6586 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6587 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6588 		BWN_READ_4(mac, BWN_MACCTL);
6589 		BWN_READ_4(mac, BWN_INTR_REASON);
6590 		bwn_psctl(mac, 0);
6591 	}
6592 }
6593 
6594 static void
6595 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6596 {
6597 	struct bwn_softc *sc = mac->mac_sc;
6598 	int i;
6599 	uint16_t ucstat;
6600 
6601 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6602 	    ("%s:%d: fail", __func__, __LINE__));
6603 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6604 	    ("%s:%d: fail", __func__, __LINE__));
6605 
6606 	/* XXX forcibly awake and hwps-off */
6607 
6608 	BWN_WRITE_4(mac, BWN_MACCTL,
6609 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6610 	    ~BWN_MACCTL_HWPS);
6611 	BWN_READ_4(mac, BWN_MACCTL);
6612 	if (siba_get_revid(sc->sc_dev) >= 5) {
6613 		for (i = 0; i < 100; i++) {
6614 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6615 			    BWN_SHARED_UCODESTAT);
6616 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6617 				break;
6618 			DELAY(10);
6619 		}
6620 	}
6621 }
6622 
6623 static int16_t
6624 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6625 {
6626 
6627 	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6628 	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6629 }
6630 
6631 static void
6632 bwn_nrssi_threshold(struct bwn_mac *mac)
6633 {
6634 	struct bwn_phy *phy = &mac->mac_phy;
6635 	struct bwn_phy_g *pg = &phy->phy_g;
6636 	struct bwn_softc *sc = mac->mac_sc;
6637 	int32_t a, b;
6638 	int16_t tmp16;
6639 	uint16_t tmpu16;
6640 
6641 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6642 
6643 	if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6644 		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6645 			a = 0x13;
6646 			b = 0x12;
6647 		} else {
6648 			a = 0xe;
6649 			b = 0x11;
6650 		}
6651 
6652 		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6653 		a += (pg->pg_nrssi[0] << 6);
6654 		a += (a < 32) ? 31 : 32;
6655 		a = a >> 6;
6656 		a = MIN(MAX(a, -31), 31);
6657 
6658 		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6659 		b += (pg->pg_nrssi[0] << 6);
6660 		if (b < 32)
6661 			b += 31;
6662 		else
6663 			b += 32;
6664 		b = b >> 6;
6665 		b = MIN(MAX(b, -31), 31);
6666 
6667 		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6668 		tmpu16 |= ((uint32_t)b & 0x0000003f);
6669 		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6670 		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6671 		return;
6672 	}
6673 
6674 	tmp16 = bwn_nrssi_read(mac, 0x20);
6675 	if (tmp16 >= 0x20)
6676 		tmp16 -= 0x40;
6677 	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6678 }
6679 
6680 static void
6681 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6682 {
6683 #define	SAVE_RF_MAX		3
6684 #define	SAVE_PHY_COMM_MAX	4
6685 #define	SAVE_PHY3_MAX		8
6686 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6687 		{ 0x7a, 0x52, 0x43 };
6688 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6689 		{ 0x15, 0x5a, 0x59, 0x58 };
6690 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6691 		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6692 		0x0801, 0x0060, 0x0014, 0x0478
6693 	};
6694 	struct bwn_phy *phy = &mac->mac_phy;
6695 	struct bwn_phy_g *pg = &phy->phy_g;
6696 	int32_t i, tmp32, phy3_idx = 0;
6697 	uint16_t delta, tmp;
6698 	uint16_t save_rf[SAVE_RF_MAX];
6699 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6700 	uint16_t save_phy3[SAVE_PHY3_MAX];
6701 	uint16_t ant_div, phy0, chan_ex;
6702 	int16_t nrssi0, nrssi1;
6703 
6704 	KASSERT(phy->type == BWN_PHYTYPE_G,
6705 	    ("%s:%d: fail", __func__, __LINE__));
6706 
6707 	if (phy->rf_rev >= 9)
6708 		return;
6709 	if (phy->rf_rev == 8)
6710 		bwn_nrssi_offset(mac);
6711 
6712 	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6713 	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6714 
6715 	/*
6716 	 * Save RF/PHY registers for later restoration
6717 	 */
6718 	ant_div = BWN_READ_2(mac, 0x03e2);
6719 	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6720 	for (i = 0; i < SAVE_RF_MAX; ++i)
6721 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6722 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6723 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6724 
6725 	phy0 = BWN_READ_2(mac, BWN_PHY0);
6726 	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6727 	if (phy->rev >= 3) {
6728 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
6729 			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6730 		BWN_PHY_WRITE(mac, 0x002e, 0);
6731 		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6732 		switch (phy->rev) {
6733 		case 4:
6734 		case 6:
6735 		case 7:
6736 			BWN_PHY_SET(mac, 0x0478, 0x0100);
6737 			BWN_PHY_SET(mac, 0x0801, 0x0040);
6738 			break;
6739 		case 3:
6740 		case 5:
6741 			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6742 			break;
6743 		}
6744 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6745 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6746 	}
6747 	/*
6748 	 * Calculate nrssi0
6749 	 */
6750 	BWN_RF_SET(mac, 0x007a, 0x0070);
6751 	bwn_set_all_gains(mac, 0, 8, 0);
6752 	BWN_RF_MASK(mac, 0x007a, 0x00f7);
6753 	if (phy->rev >= 2) {
6754 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6755 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6756 	}
6757 	BWN_RF_SET(mac, 0x007a, 0x0080);
6758 	DELAY(20);
6759 
6760 	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6761 	if (nrssi0 >= 0x0020)
6762 		nrssi0 -= 0x0040;
6763 
6764 	/*
6765 	 * Calculate nrssi1
6766 	 */
6767 	BWN_RF_MASK(mac, 0x007a, 0x007f);
6768 	if (phy->rev >= 2)
6769 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6770 
6771 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6772 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6773 	BWN_RF_SET(mac, 0x007a, 0x000f);
6774 	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6775 	if (phy->rev >= 2) {
6776 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6777 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6778 	}
6779 
6780 	bwn_set_all_gains(mac, 3, 0, 1);
6781 	if (phy->rf_rev == 8) {
6782 		BWN_RF_WRITE(mac, 0x0043, 0x001f);
6783 	} else {
6784 		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6785 		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6786 		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6787 		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6788 	}
6789 	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6790 	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6791 	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6792 	DELAY(20);
6793 	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6794 
6795 	/*
6796 	 * Install calculated narrow RSSI values
6797 	 */
6798 	if (nrssi1 >= 0x0020)
6799 		nrssi1 -= 0x0040;
6800 	if (nrssi0 == nrssi1)
6801 		pg->pg_nrssi_slope = 0x00010000;
6802 	else
6803 		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6804 	if (nrssi0 >= -4) {
6805 		pg->pg_nrssi[0] = nrssi1;
6806 		pg->pg_nrssi[1] = nrssi0;
6807 	}
6808 
6809 	/*
6810 	 * Restore saved RF/PHY registers
6811 	 */
6812 	if (phy->rev >= 3) {
6813 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6814 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6815 			    save_phy3[phy3_idx]);
6816 		}
6817 	}
6818 	if (phy->rev >= 2) {
6819 		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6820 		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6821 	}
6822 
6823 	for (i = 0; i < SAVE_RF_MAX; ++i)
6824 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6825 
6826 	BWN_WRITE_2(mac, 0x03e2, ant_div);
6827 	BWN_WRITE_2(mac, 0x03e6, phy0);
6828 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6829 
6830 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6831 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6832 
6833 	bwn_spu_workaround(mac, phy->chan);
6834 	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6835 	bwn_set_original_gains(mac);
6836 	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6837 	if (phy->rev >= 3) {
6838 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6839 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6840 			    save_phy3[phy3_idx]);
6841 		}
6842 	}
6843 
6844 	delta = 0x1f - pg->pg_nrssi[0];
6845 	for (i = 0; i < 64; i++) {
6846 		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6847 		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6848 		pg->pg_nrssi_lt[i] = tmp32;
6849 	}
6850 
6851 	bwn_nrssi_threshold(mac);
6852 #undef SAVE_RF_MAX
6853 #undef SAVE_PHY_COMM_MAX
6854 #undef SAVE_PHY3_MAX
6855 }
6856 
6857 static void
6858 bwn_nrssi_offset(struct bwn_mac *mac)
6859 {
6860 #define	SAVE_RF_MAX		2
6861 #define	SAVE_PHY_COMM_MAX	10
6862 #define	SAVE_PHY6_MAX		8
6863 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6864 		{ 0x7a, 0x43 };
6865 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6866 		0x0001, 0x0811, 0x0812, 0x0814,
6867 		0x0815, 0x005a, 0x0059, 0x0058,
6868 		0x000a, 0x0003
6869 	};
6870 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6871 		0x002e, 0x002f, 0x080f, 0x0810,
6872 		0x0801, 0x0060, 0x0014, 0x0478
6873 	};
6874 	struct bwn_phy *phy = &mac->mac_phy;
6875 	int i, phy6_idx = 0;
6876 	uint16_t save_rf[SAVE_RF_MAX];
6877 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6878 	uint16_t save_phy6[SAVE_PHY6_MAX];
6879 	int16_t nrssi;
6880 	uint16_t saved = 0xffff;
6881 
6882 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6883 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6884 	for (i = 0; i < SAVE_RF_MAX; ++i)
6885 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6886 
6887 	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6888 	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6889 	BWN_PHY_SET(mac, 0x0811, 0x000c);
6890 	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6891 	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6892 	if (phy->rev >= 6) {
6893 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
6894 			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6895 
6896 		BWN_PHY_WRITE(mac, 0x002e, 0);
6897 		BWN_PHY_WRITE(mac, 0x002f, 0);
6898 		BWN_PHY_WRITE(mac, 0x080f, 0);
6899 		BWN_PHY_WRITE(mac, 0x0810, 0);
6900 		BWN_PHY_SET(mac, 0x0478, 0x0100);
6901 		BWN_PHY_SET(mac, 0x0801, 0x0040);
6902 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6903 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6904 	}
6905 	BWN_RF_SET(mac, 0x007a, 0x0070);
6906 	BWN_RF_SET(mac, 0x007a, 0x0080);
6907 	DELAY(30);
6908 
6909 	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6910 	if (nrssi >= 0x20)
6911 		nrssi -= 0x40;
6912 	if (nrssi == 31) {
6913 		for (i = 7; i >= 4; i--) {
6914 			BWN_RF_WRITE(mac, 0x007b, i);
6915 			DELAY(20);
6916 			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6917 			    0x003f);
6918 			if (nrssi >= 0x20)
6919 				nrssi -= 0x40;
6920 			if (nrssi < 31 && saved == 0xffff)
6921 				saved = i;
6922 		}
6923 		if (saved == 0xffff)
6924 			saved = 4;
6925 	} else {
6926 		BWN_RF_MASK(mac, 0x007a, 0x007f);
6927 		if (phy->rev != 1) {
6928 			BWN_PHY_SET(mac, 0x0814, 0x0001);
6929 			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6930 		}
6931 		BWN_PHY_SET(mac, 0x0811, 0x000c);
6932 		BWN_PHY_SET(mac, 0x0812, 0x000c);
6933 		BWN_PHY_SET(mac, 0x0811, 0x0030);
6934 		BWN_PHY_SET(mac, 0x0812, 0x0030);
6935 		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6936 		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6937 		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6938 		if (phy->rev == 0)
6939 			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6940 		else
6941 			BWN_PHY_SET(mac, 0x000a, 0x2000);
6942 		if (phy->rev != 1) {
6943 			BWN_PHY_SET(mac, 0x0814, 0x0004);
6944 			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6945 		}
6946 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6947 		BWN_RF_SET(mac, 0x007a, 0x000f);
6948 		bwn_set_all_gains(mac, 3, 0, 1);
6949 		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6950 		DELAY(30);
6951 		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6952 		if (nrssi >= 0x20)
6953 			nrssi -= 0x40;
6954 		if (nrssi == -32) {
6955 			for (i = 0; i < 4; i++) {
6956 				BWN_RF_WRITE(mac, 0x007b, i);
6957 				DELAY(20);
6958 				nrssi = (int16_t)((BWN_PHY_READ(mac,
6959 				    0x047f) >> 8) & 0x003f);
6960 				if (nrssi >= 0x20)
6961 					nrssi -= 0x40;
6962 				if (nrssi > -31 && saved == 0xffff)
6963 					saved = i;
6964 			}
6965 			if (saved == 0xffff)
6966 				saved = 3;
6967 		} else
6968 			saved = 0;
6969 	}
6970 	BWN_RF_WRITE(mac, 0x007b, saved);
6971 
6972 	/*
6973 	 * Restore saved RF/PHY registers
6974 	 */
6975 	if (phy->rev >= 6) {
6976 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6977 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6978 			    save_phy6[phy6_idx]);
6979 		}
6980 	}
6981 	if (phy->rev != 1) {
6982 		for (i = 3; i < 5; i++)
6983 			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6984 			    save_phy_comm[i]);
6985 	}
6986 	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6987 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6988 
6989 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6990 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6991 
6992 	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6993 	BWN_PHY_SET(mac, 0x0429, 0x8000);
6994 	bwn_set_original_gains(mac);
6995 	if (phy->rev >= 6) {
6996 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6997 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6998 			    save_phy6[phy6_idx]);
6999 		}
7000 	}
7001 
7002 	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7003 	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7004 	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7005 }
7006 
7007 static void
7008 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7009     int16_t third)
7010 {
7011 	struct bwn_phy *phy = &mac->mac_phy;
7012 	uint16_t i;
7013 	uint16_t start = 0x08, end = 0x18;
7014 	uint16_t tmp;
7015 	uint16_t table;
7016 
7017 	if (phy->rev <= 1) {
7018 		start = 0x10;
7019 		end = 0x20;
7020 	}
7021 
7022 	table = BWN_OFDMTAB_GAINX;
7023 	if (phy->rev <= 1)
7024 		table = BWN_OFDMTAB_GAINX_R1;
7025 	for (i = 0; i < 4; i++)
7026 		bwn_ofdmtab_write_2(mac, table, i, first);
7027 
7028 	for (i = start; i < end; i++)
7029 		bwn_ofdmtab_write_2(mac, table, i, second);
7030 
7031 	if (third != -1) {
7032 		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7033 		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7034 		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7035 		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7036 	}
7037 	bwn_dummy_transmission(mac, 0, 1);
7038 }
7039 
7040 static void
7041 bwn_set_original_gains(struct bwn_mac *mac)
7042 {
7043 	struct bwn_phy *phy = &mac->mac_phy;
7044 	uint16_t i, tmp;
7045 	uint16_t table;
7046 	uint16_t start = 0x0008, end = 0x0018;
7047 
7048 	if (phy->rev <= 1) {
7049 		start = 0x0010;
7050 		end = 0x0020;
7051 	}
7052 
7053 	table = BWN_OFDMTAB_GAINX;
7054 	if (phy->rev <= 1)
7055 		table = BWN_OFDMTAB_GAINX_R1;
7056 	for (i = 0; i < 4; i++) {
7057 		tmp = (i & 0xfffc);
7058 		tmp |= (i & 0x0001) << 1;
7059 		tmp |= (i & 0x0002) >> 1;
7060 
7061 		bwn_ofdmtab_write_2(mac, table, i, tmp);
7062 	}
7063 
7064 	for (i = start; i < end; i++)
7065 		bwn_ofdmtab_write_2(mac, table, i, i - start);
7066 
7067 	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7068 	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7069 	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7070 	bwn_dummy_transmission(mac, 0, 1);
7071 }
7072 
7073 static void
7074 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7075 {
7076 	struct bwn_phy *phy = &mac->mac_phy;
7077 	struct bwn_phy_g *pg = &phy->phy_g;
7078 	struct bwn_rfatt old_rfatt, rfatt;
7079 	struct bwn_bbatt old_bbatt, bbatt;
7080 	struct bwn_softc *sc = mac->mac_sc;
7081 	uint8_t old_txctl = 0;
7082 
7083 	KASSERT(phy->type == BWN_PHYTYPE_G,
7084 	    ("%s:%d: fail", __func__, __LINE__));
7085 
7086 	if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7087 	    (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7088 		return;
7089 
7090 	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7091 
7092 	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7093 
7094 	if (!phy->gmode)
7095 		return;
7096 	bwn_hwpctl_early_init(mac);
7097 	if (pg->pg_curtssi == 0) {
7098 		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7099 			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7100 		} else {
7101 			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7102 			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7103 			old_txctl = pg->pg_txctl;
7104 
7105 			bbatt.att = 11;
7106 			if (phy->rf_rev == 8) {
7107 				rfatt.att = 15;
7108 				rfatt.padmix = 1;
7109 			} else {
7110 				rfatt.att = 9;
7111 				rfatt.padmix = 0;
7112 			}
7113 			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7114 		}
7115 		bwn_dummy_transmission(mac, 0, 1);
7116 		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7117 		if (phy->rf_ver == 0x2050 && phy->analog == 0)
7118 			BWN_RF_MASK(mac, 0x0076, 0xff7b);
7119 		else
7120 			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7121 			    &old_rfatt, old_txctl);
7122 	}
7123 	bwn_hwpctl_init_gphy(mac);
7124 
7125 	/* clear TSSI */
7126 	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7127 	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7128 	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7129 	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7130 }
7131 
7132 static void
7133 bwn_hwpctl_early_init(struct bwn_mac *mac)
7134 {
7135 	struct bwn_phy *phy = &mac->mac_phy;
7136 
7137 	if (!bwn_has_hwpctl(mac)) {
7138 		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7139 		return;
7140 	}
7141 
7142 	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7143 	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7144 	BWN_PHY_SET(mac, 0x047c, 0x0002);
7145 	BWN_PHY_SET(mac, 0x047a, 0xf000);
7146 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7147 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7148 		BWN_PHY_SET(mac, 0x005d, 0x8000);
7149 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7150 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7151 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7152 	} else {
7153 		BWN_PHY_SET(mac, 0x0036, 0x0200);
7154 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7155 		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7156 		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7157 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7158 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7159 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7160 	}
7161 }
7162 
7163 static void
7164 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7165 {
7166 	struct bwn_phy *phy = &mac->mac_phy;
7167 	struct bwn_phy_g *pg = &phy->phy_g;
7168 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7169 	int i;
7170 	uint16_t nr_written = 0, tmp, value;
7171 	uint8_t rf, bb;
7172 
7173 	if (!bwn_has_hwpctl(mac)) {
7174 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7175 		return;
7176 	}
7177 
7178 	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7179 	    (pg->pg_idletssi - pg->pg_curtssi));
7180 	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7181 	    (pg->pg_idletssi - pg->pg_curtssi));
7182 
7183 	for (i = 0; i < 32; i++)
7184 		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7185 	for (i = 32; i < 64; i++)
7186 		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7187 	for (i = 0; i < 64; i += 2) {
7188 		value = (uint16_t) pg->pg_tssi2dbm[i];
7189 		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7190 		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7191 	}
7192 
7193 	for (rf = 0; rf < lo->rfatt.len; rf++) {
7194 		for (bb = 0; bb < lo->bbatt.len; bb++) {
7195 			if (nr_written >= 0x40)
7196 				return;
7197 			tmp = lo->bbatt.array[bb].att;
7198 			tmp <<= 8;
7199 			if (phy->rf_rev == 8)
7200 				tmp |= 0x50;
7201 			else
7202 				tmp |= 0x40;
7203 			tmp |= lo->rfatt.array[rf].att;
7204 			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7205 			nr_written++;
7206 		}
7207 	}
7208 
7209 	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7210 	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7211 
7212 	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7213 	BWN_PHY_SET(mac, 0x0478, 0x0800);
7214 	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7215 	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7216 
7217 	bwn_phy_g_dc_lookup_init(mac, 1);
7218 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7219 }
7220 
7221 static void
7222 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7223 {
7224 	struct bwn_softc *sc = mac->mac_sc;
7225 
7226 	if (spu != 0)
7227 		bwn_spu_workaround(mac, channel);
7228 
7229 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7230 
7231 	if (channel == 14) {
7232 		if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7233 			bwn_hf_write(mac,
7234 			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7235 		else
7236 			bwn_hf_write(mac,
7237 			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7238 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7239 		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7240 		return;
7241 	}
7242 
7243 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7244 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7245 }
7246 
7247 static uint16_t
7248 bwn_phy_g_chan2freq(uint8_t channel)
7249 {
7250 	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7251 
7252 	KASSERT(channel >= 1 && channel <= 14,
7253 	    ("%s:%d: fail", __func__, __LINE__));
7254 
7255 	return (bwn_phy_g_rf_channels[channel - 1]);
7256 }
7257 
7258 static void
7259 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7260     const struct bwn_rfatt *rfatt, uint8_t txctl)
7261 {
7262 	struct bwn_phy *phy = &mac->mac_phy;
7263 	struct bwn_phy_g *pg = &phy->phy_g;
7264 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7265 	uint16_t bb, rf;
7266 	uint16_t tx_bias, tx_magn;
7267 
7268 	bb = bbatt->att;
7269 	rf = rfatt->att;
7270 	tx_bias = lo->tx_bias;
7271 	tx_magn = lo->tx_magn;
7272 	if (tx_bias == 0xff)
7273 		tx_bias = 0;
7274 
7275 	pg->pg_txctl = txctl;
7276 	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7277 	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7278 	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7279 	bwn_phy_g_set_bbatt(mac, bb);
7280 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7281 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7282 		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7283 	else {
7284 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7285 		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7286 	}
7287 	if (BWN_HAS_TXMAG(phy))
7288 		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7289 	else
7290 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7291 	bwn_lo_g_adjust(mac);
7292 }
7293 
7294 static void
7295 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7296     uint16_t bbatt)
7297 {
7298 	struct bwn_phy *phy = &mac->mac_phy;
7299 
7300 	if (phy->analog == 0) {
7301 		BWN_WRITE_2(mac, BWN_PHY0,
7302 		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7303 		return;
7304 	}
7305 	if (phy->analog > 1) {
7306 		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7307 		return;
7308 	}
7309 	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7310 }
7311 
7312 static uint16_t
7313 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7314 {
7315 	struct bwn_phy *phy = &mac->mac_phy;
7316 	struct bwn_phy_g *pg = &phy->phy_g;
7317 	struct bwn_softc *sc = mac->mac_sc;
7318 	int max_lb_gain;
7319 	uint16_t extlna;
7320 	uint16_t i;
7321 
7322 	if (phy->gmode == 0)
7323 		return (0);
7324 
7325 	if (BWN_HAS_LOOPBACK(phy)) {
7326 		max_lb_gain = pg->pg_max_lb_gain;
7327 		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7328 		if (max_lb_gain >= 0x46) {
7329 			extlna = 0x3000;
7330 			max_lb_gain -= 0x46;
7331 		} else if (max_lb_gain >= 0x3a) {
7332 			extlna = 0x1000;
7333 			max_lb_gain -= 0x3a;
7334 		} else if (max_lb_gain >= 0x2e) {
7335 			extlna = 0x2000;
7336 			max_lb_gain -= 0x2e;
7337 		} else {
7338 			extlna = 0;
7339 			max_lb_gain -= 0x10;
7340 		}
7341 
7342 		for (i = 0; i < 16; i++) {
7343 			max_lb_gain -= (i * 6);
7344 			if (max_lb_gain < 6)
7345 				break;
7346 		}
7347 
7348 		if ((phy->rev < 7) ||
7349 		    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7350 			if (reg == BWN_PHY_RFOVER) {
7351 				return (0x1b3);
7352 			} else if (reg == BWN_PHY_RFOVERVAL) {
7353 				extlna |= (i << 8);
7354 				switch (lpd) {
7355 				case BWN_LPD(0, 1, 1):
7356 					return (0x0f92);
7357 				case BWN_LPD(0, 0, 1):
7358 				case BWN_LPD(1, 0, 1):
7359 					return (0x0092 | extlna);
7360 				case BWN_LPD(1, 0, 0):
7361 					return (0x0093 | extlna);
7362 				}
7363 				KASSERT(0 == 1,
7364 				    ("%s:%d: fail", __func__, __LINE__));
7365 			}
7366 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7367 		} else {
7368 			if (reg == BWN_PHY_RFOVER)
7369 				return (0x9b3);
7370 			if (reg == BWN_PHY_RFOVERVAL) {
7371 				if (extlna)
7372 					extlna |= 0x8000;
7373 				extlna |= (i << 8);
7374 				switch (lpd) {
7375 				case BWN_LPD(0, 1, 1):
7376 					return (0x8f92);
7377 				case BWN_LPD(0, 0, 1):
7378 					return (0x8092 | extlna);
7379 				case BWN_LPD(1, 0, 1):
7380 					return (0x2092 | extlna);
7381 				case BWN_LPD(1, 0, 0):
7382 					return (0x2093 | extlna);
7383 				}
7384 				KASSERT(0 == 1,
7385 				    ("%s:%d: fail", __func__, __LINE__));
7386 			}
7387 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7388 		}
7389 		return (0);
7390 	}
7391 
7392 	if ((phy->rev < 7) ||
7393 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7394 		if (reg == BWN_PHY_RFOVER) {
7395 			return (0x1b3);
7396 		} else if (reg == BWN_PHY_RFOVERVAL) {
7397 			switch (lpd) {
7398 			case BWN_LPD(0, 1, 1):
7399 				return (0x0fb2);
7400 			case BWN_LPD(0, 0, 1):
7401 				return (0x00b2);
7402 			case BWN_LPD(1, 0, 1):
7403 				return (0x30b2);
7404 			case BWN_LPD(1, 0, 0):
7405 				return (0x30b3);
7406 			}
7407 			KASSERT(0 == 1,
7408 			    ("%s:%d: fail", __func__, __LINE__));
7409 		}
7410 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7411 	} else {
7412 		if (reg == BWN_PHY_RFOVER) {
7413 			return (0x9b3);
7414 		} else if (reg == BWN_PHY_RFOVERVAL) {
7415 			switch (lpd) {
7416 			case BWN_LPD(0, 1, 1):
7417 				return (0x8fb2);
7418 			case BWN_LPD(0, 0, 1):
7419 				return (0x80b2);
7420 			case BWN_LPD(1, 0, 1):
7421 				return (0x20b2);
7422 			case BWN_LPD(1, 0, 0):
7423 				return (0x20b3);
7424 			}
7425 			KASSERT(0 == 1,
7426 			    ("%s:%d: fail", __func__, __LINE__));
7427 		}
7428 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7429 	}
7430 	return (0);
7431 }
7432 
7433 static void
7434 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7435 {
7436 
7437 	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7438 		return;
7439 	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7440 	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7441 	DELAY(1000);
7442 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7443 }
7444 
7445 static int
7446 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7447 {
7448 	struct bwn_softc *sc = mac->mac_sc;
7449 	struct bwn_fw *fw = &mac->mac_fw;
7450 	const uint8_t rev = siba_get_revid(sc->sc_dev);
7451 	const char *filename;
7452 	uint32_t high;
7453 	int error;
7454 
7455 	/* microcode */
7456 	if (rev >= 5 && rev <= 10)
7457 		filename = "ucode5";
7458 	else if (rev >= 11 && rev <= 12)
7459 		filename = "ucode11";
7460 	else if (rev == 13)
7461 		filename = "ucode13";
7462 	else if (rev == 14)
7463 		filename = "ucode14";
7464 	else if (rev >= 15)
7465 		filename = "ucode15";
7466 	else {
7467 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7468 		bwn_release_firmware(mac);
7469 		return (EOPNOTSUPP);
7470 	}
7471 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
7472 	if (error) {
7473 		bwn_release_firmware(mac);
7474 		return (error);
7475 	}
7476 
7477 	/* PCM */
7478 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7479 	if (rev >= 5 && rev <= 10) {
7480 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7481 		if (error == ENOENT)
7482 			fw->no_pcmfile = 1;
7483 		else if (error) {
7484 			bwn_release_firmware(mac);
7485 			return (error);
7486 		}
7487 	} else if (rev < 11) {
7488 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7489 		return (EOPNOTSUPP);
7490 	}
7491 
7492 	/* initvals */
7493 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7494 	switch (mac->mac_phy.type) {
7495 	case BWN_PHYTYPE_A:
7496 		if (rev < 5 || rev > 10)
7497 			goto fail1;
7498 		if (high & BWN_TGSHIGH_HAVE_2GHZ)
7499 			filename = "a0g1initvals5";
7500 		else
7501 			filename = "a0g0initvals5";
7502 		break;
7503 	case BWN_PHYTYPE_G:
7504 		if (rev >= 5 && rev <= 10)
7505 			filename = "b0g0initvals5";
7506 		else if (rev >= 13)
7507 			filename = "b0g0initvals13";
7508 		else
7509 			goto fail1;
7510 		break;
7511 	case BWN_PHYTYPE_LP:
7512 		if (rev == 13)
7513 			filename = "lp0initvals13";
7514 		else if (rev == 14)
7515 			filename = "lp0initvals14";
7516 		else if (rev >= 15)
7517 			filename = "lp0initvals15";
7518 		else
7519 			goto fail1;
7520 		break;
7521 	case BWN_PHYTYPE_N:
7522 		if (rev >= 11 && rev <= 12)
7523 			filename = "n0initvals11";
7524 		else
7525 			goto fail1;
7526 		break;
7527 	default:
7528 		goto fail1;
7529 	}
7530 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
7531 	if (error) {
7532 		bwn_release_firmware(mac);
7533 		return (error);
7534 	}
7535 
7536 	/* bandswitch initvals */
7537 	switch (mac->mac_phy.type) {
7538 	case BWN_PHYTYPE_A:
7539 		if (rev >= 5 && rev <= 10) {
7540 			if (high & BWN_TGSHIGH_HAVE_2GHZ)
7541 				filename = "a0g1bsinitvals5";
7542 			else
7543 				filename = "a0g0bsinitvals5";
7544 		} else if (rev >= 11)
7545 			filename = NULL;
7546 		else
7547 			goto fail1;
7548 		break;
7549 	case BWN_PHYTYPE_G:
7550 		if (rev >= 5 && rev <= 10)
7551 			filename = "b0g0bsinitvals5";
7552 		else if (rev >= 11)
7553 			filename = NULL;
7554 		else
7555 			goto fail1;
7556 		break;
7557 	case BWN_PHYTYPE_LP:
7558 		if (rev == 13)
7559 			filename = "lp0bsinitvals13";
7560 		else if (rev == 14)
7561 			filename = "lp0bsinitvals14";
7562 		else if (rev >= 15)
7563 			filename = "lp0bsinitvals15";
7564 		else
7565 			goto fail1;
7566 		break;
7567 	case BWN_PHYTYPE_N:
7568 		if (rev >= 11 && rev <= 12)
7569 			filename = "n0bsinitvals11";
7570 		else
7571 			goto fail1;
7572 		break;
7573 	default:
7574 		goto fail1;
7575 	}
7576 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7577 	if (error) {
7578 		bwn_release_firmware(mac);
7579 		return (error);
7580 	}
7581 	return (0);
7582 fail1:
7583 	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7584 	bwn_release_firmware(mac);
7585 	return (EOPNOTSUPP);
7586 }
7587 
7588 static int
7589 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7590     const char *name, struct bwn_fwfile *bfw)
7591 {
7592 	const struct bwn_fwhdr *hdr;
7593 	struct bwn_softc *sc = mac->mac_sc;
7594 	const struct firmware *fw;
7595 	char namebuf[64];
7596 
7597 	if (name == NULL) {
7598 		bwn_do_release_fw(bfw);
7599 		return (0);
7600 	}
7601 	if (bfw->filename != NULL) {
7602 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7603 			return (0);
7604 		bwn_do_release_fw(bfw);
7605 	}
7606 
7607 	ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7608 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7609 	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7610 	wlan_assert_serialized();
7611 	wlan_serialize_exit();
7612 	fw = firmware_get(namebuf);
7613 	wlan_serialize_enter();
7614 	if (fw == NULL) {
7615 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7616 		    namebuf);
7617 		return (ENOENT);
7618 	}
7619 	if (fw->datasize < sizeof(struct bwn_fwhdr))
7620 		goto fail;
7621 	hdr = (const struct bwn_fwhdr *)(fw->data);
7622 	switch (hdr->type) {
7623 	case BWN_FWTYPE_UCODE:
7624 	case BWN_FWTYPE_PCM:
7625 		if (be32toh(hdr->size) !=
7626 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
7627 			goto fail;
7628 		/* FALLTHROUGH */
7629 	case BWN_FWTYPE_IV:
7630 		if (hdr->ver != 1)
7631 			goto fail;
7632 		break;
7633 	default:
7634 		goto fail;
7635 	}
7636 	bfw->filename = name;
7637 	bfw->fw = fw;
7638 	bfw->type = type;
7639 	return (0);
7640 fail:
7641 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7642 	if (fw != NULL)
7643 		firmware_put(fw, FIRMWARE_UNLOAD);
7644 	return (EPROTO);
7645 }
7646 
7647 static void
7648 bwn_release_firmware(struct bwn_mac *mac)
7649 {
7650 
7651 	bwn_do_release_fw(&mac->mac_fw.ucode);
7652 	bwn_do_release_fw(&mac->mac_fw.pcm);
7653 	bwn_do_release_fw(&mac->mac_fw.initvals);
7654 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
7655 }
7656 
7657 static void
7658 bwn_do_release_fw(struct bwn_fwfile *bfw)
7659 {
7660 
7661 	if (bfw->fw != NULL)
7662 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7663 	bfw->fw = NULL;
7664 	bfw->filename = NULL;
7665 }
7666 
7667 static int
7668 bwn_fw_loaducode(struct bwn_mac *mac)
7669 {
7670 #define	GETFWOFFSET(fwp, offset)	\
7671 	((const uint32_t *)((const char *)fwp.fw->data + offset))
7672 #define	GETFWSIZE(fwp, offset)	\
7673 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
7674 	struct bwn_softc *sc = mac->mac_sc;
7675 	const uint32_t *data;
7676 	unsigned int i;
7677 	uint32_t ctl;
7678 	uint16_t date, fwcaps, time;
7679 	int error = 0;
7680 
7681 	ctl = BWN_READ_4(mac, BWN_MACCTL);
7682 	ctl |= BWN_MACCTL_MCODE_JMP0;
7683 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7684 	    __LINE__));
7685 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7686 	for (i = 0; i < 64; i++)
7687 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7688 	for (i = 0; i < 4096; i += 2)
7689 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7690 
7691 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7692 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7693 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7694 	     i++) {
7695 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7696 		DELAY(10);
7697 	}
7698 
7699 	if (mac->mac_fw.pcm.fw) {
7700 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7701 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7702 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7703 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7704 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7705 		    sizeof(struct bwn_fwhdr)); i++) {
7706 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7707 			DELAY(10);
7708 		}
7709 	}
7710 
7711 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7712 	BWN_WRITE_4(mac, BWN_MACCTL,
7713 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7714 	    BWN_MACCTL_MCODE_RUN);
7715 
7716 	for (i = 0; i < 21; i++) {
7717 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7718 			break;
7719 		if (i >= 20) {
7720 			device_printf(sc->sc_dev, "ucode timeout\n");
7721 			error = ENXIO;
7722 			goto error;
7723 		}
7724 		DELAY(50000);
7725 	}
7726 	BWN_READ_4(mac, BWN_INTR_REASON);
7727 
7728 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7729 	if (mac->mac_fw.rev <= 0x128) {
7730 		device_printf(sc->sc_dev, "the firmware is too old\n");
7731 		error = EOPNOTSUPP;
7732 		goto error;
7733 	}
7734 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7735 	    BWN_SHARED_UCODE_PATCH);
7736 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7737 	mac->mac_fw.opensource = (date == 0xffff);
7738 	if (bwn_wme != 0)
7739 		mac->mac_flags |= BWN_MAC_FLAG_WME;
7740 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7741 
7742 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7743 	if (mac->mac_fw.opensource == 0) {
7744 		device_printf(sc->sc_dev,
7745 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
7746 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7747 		if (mac->mac_fw.no_pcmfile)
7748 			device_printf(sc->sc_dev,
7749 			    "no HW crypto acceleration due to pcm5\n");
7750 	} else {
7751 		mac->mac_fw.patch = time;
7752 		fwcaps = bwn_fwcaps_read(mac);
7753 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7754 			device_printf(sc->sc_dev,
7755 			    "disabling HW crypto acceleration\n");
7756 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7757 		}
7758 		if (!(fwcaps & BWN_FWCAPS_WME)) {
7759 			device_printf(sc->sc_dev, "disabling WME support\n");
7760 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7761 		}
7762 	}
7763 
7764 	if (BWN_ISOLDFMT(mac))
7765 		device_printf(sc->sc_dev, "using old firmware image\n");
7766 
7767 	return (0);
7768 
7769 error:
7770 	BWN_WRITE_4(mac, BWN_MACCTL,
7771 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7772 	    BWN_MACCTL_MCODE_JMP0);
7773 
7774 	return (error);
7775 #undef GETFWSIZE
7776 #undef GETFWOFFSET
7777 }
7778 
7779 /* OpenFirmware only */
7780 static uint16_t
7781 bwn_fwcaps_read(struct bwn_mac *mac)
7782 {
7783 
7784 	KASSERT(mac->mac_fw.opensource == 1,
7785 	    ("%s:%d: fail", __func__, __LINE__));
7786 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7787 }
7788 
7789 static int
7790 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7791     size_t count, size_t array_size)
7792 {
7793 #define	GET_NEXTIV16(iv)						\
7794 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7795 	    sizeof(uint16_t) + sizeof(uint16_t)))
7796 #define	GET_NEXTIV32(iv)						\
7797 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7798 	    sizeof(uint16_t) + sizeof(uint32_t)))
7799 	struct bwn_softc *sc = mac->mac_sc;
7800 	const struct bwn_fwinitvals *iv;
7801 	uint16_t offset;
7802 	size_t i;
7803 	uint8_t bit32;
7804 
7805 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7806 	    ("%s:%d: fail", __func__, __LINE__));
7807 	iv = ivals;
7808 	for (i = 0; i < count; i++) {
7809 		if (array_size < sizeof(iv->offset_size))
7810 			goto fail;
7811 		array_size -= sizeof(iv->offset_size);
7812 		offset = be16toh(iv->offset_size);
7813 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7814 		offset &= BWN_FWINITVALS_OFFSET_MASK;
7815 		if (offset >= 0x1000)
7816 			goto fail;
7817 		if (bit32) {
7818 			if (array_size < sizeof(iv->data.d32))
7819 				goto fail;
7820 			array_size -= sizeof(iv->data.d32);
7821 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7822 			iv = GET_NEXTIV32(iv);
7823 		} else {
7824 
7825 			if (array_size < sizeof(iv->data.d16))
7826 				goto fail;
7827 			array_size -= sizeof(iv->data.d16);
7828 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7829 
7830 			iv = GET_NEXTIV16(iv);
7831 		}
7832 	}
7833 	if (array_size != 0)
7834 		goto fail;
7835 	return (0);
7836 fail:
7837 	device_printf(sc->sc_dev, "initvals: invalid format\n");
7838 	return (EPROTO);
7839 #undef GET_NEXTIV16
7840 #undef GET_NEXTIV32
7841 }
7842 
7843 static int
7844 bwn_switch_channel(struct bwn_mac *mac, int chan)
7845 {
7846 	struct bwn_phy *phy = &(mac->mac_phy);
7847 	struct bwn_softc *sc = mac->mac_sc;
7848 	struct ifnet *ifp = sc->sc_ifp;
7849 	struct ieee80211com *ic = ifp->if_l2com;
7850 	uint16_t channelcookie, savedcookie;
7851 	int error;
7852 
7853 	if (chan == 0xffff)
7854 		chan = phy->get_default_chan(mac);
7855 
7856 	channelcookie = chan;
7857 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7858 		channelcookie |= 0x100;
7859 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7860 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7861 	error = phy->switch_channel(mac, chan);
7862 	if (error)
7863 		goto fail;
7864 
7865 	mac->mac_phy.chan = chan;
7866 	DELAY(8000);
7867 	return (0);
7868 fail:
7869 	device_printf(sc->sc_dev, "failed to switch channel\n");
7870 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7871 	return (error);
7872 }
7873 
7874 static uint16_t
7875 bwn_ant2phy(int antenna)
7876 {
7877 
7878 	switch (antenna) {
7879 	case BWN_ANT0:
7880 		return (BWN_TX_PHY_ANT0);
7881 	case BWN_ANT1:
7882 		return (BWN_TX_PHY_ANT1);
7883 	case BWN_ANT2:
7884 		return (BWN_TX_PHY_ANT2);
7885 	case BWN_ANT3:
7886 		return (BWN_TX_PHY_ANT3);
7887 	case BWN_ANTAUTO:
7888 		return (BWN_TX_PHY_ANT01AUTO);
7889 	}
7890 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7891 	return (0);
7892 }
7893 
7894 static void
7895 bwn_wme_load(struct bwn_mac *mac)
7896 {
7897 	struct bwn_softc *sc = mac->mac_sc;
7898 	int i;
7899 
7900 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7901 	    ("%s:%d: fail", __func__, __LINE__));
7902 
7903 	bwn_mac_suspend(mac);
7904 	for (i = 0; i < N(sc->sc_wmeParams); i++)
7905 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7906 		    bwn_wme_shm_offsets[i]);
7907 	bwn_mac_enable(mac);
7908 }
7909 
7910 static void
7911 bwn_wme_loadparams(struct bwn_mac *mac,
7912     const struct wmeParams *p, uint16_t shm_offset)
7913 {
7914 #define	SM(_v, _f)      (((_v) << _f##_S) & _f)
7915 	struct bwn_softc *sc = mac->mac_sc;
7916 	uint16_t params[BWN_NR_WMEPARAMS];
7917 	int slot, tmp;
7918 	unsigned int i;
7919 
7920 	slot = BWN_READ_2(mac, BWN_RNG) &
7921 	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7922 
7923 	memset(&params, 0, sizeof(params));
7924 
7925 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7926 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7927 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7928 
7929 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7930 	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7931 	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7932 	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7933 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7934 	params[BWN_WMEPARAM_BSLOTS] = slot;
7935 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7936 
7937 	for (i = 0; i < N(params); i++) {
7938 		if (i == BWN_WMEPARAM_STATUS) {
7939 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
7940 			    shm_offset + (i * 2));
7941 			tmp |= 0x100;
7942 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7943 			    tmp);
7944 		} else {
7945 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7946 			    params[i]);
7947 		}
7948 	}
7949 }
7950 
7951 static void
7952 bwn_mac_write_bssid(struct bwn_mac *mac)
7953 {
7954 	struct bwn_softc *sc = mac->mac_sc;
7955 	uint32_t tmp;
7956 	int i;
7957 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7958 
7959 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7960 	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
7961 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7962 	    IEEE80211_ADDR_LEN);
7963 
7964 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7965 		tmp = (uint32_t) (mac_bssid[i + 0]);
7966 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7967 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7968 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7969 		bwn_ram_write(mac, 0x20 + i, tmp);
7970 	}
7971 }
7972 
7973 static void
7974 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7975     const uint8_t *macaddr)
7976 {
7977 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7978 	uint16_t data;
7979 
7980 	if (mac == NULL)
7981 		macaddr = zero;
7982 
7983 	offset |= 0x0020;
7984 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7985 
7986 	data = macaddr[0];
7987 	data |= macaddr[1] << 8;
7988 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7989 	data = macaddr[2];
7990 	data |= macaddr[3] << 8;
7991 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7992 	data = macaddr[4];
7993 	data |= macaddr[5] << 8;
7994 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7995 }
7996 
7997 static void
7998 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7999     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8000 {
8001 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8002 	uint8_t per_sta_keys_start = 8;
8003 
8004 	if (BWN_SEC_NEWAPI(mac))
8005 		per_sta_keys_start = 4;
8006 
8007 	KASSERT(index < mac->mac_max_nr_keys,
8008 	    ("%s:%d: fail", __func__, __LINE__));
8009 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
8010 	    ("%s:%d: fail", __func__, __LINE__));
8011 
8012 	if (index >= per_sta_keys_start)
8013 		bwn_key_macwrite(mac, index, NULL);
8014 	if (key)
8015 		memcpy(buf, key, key_len);
8016 	bwn_key_write(mac, index, algorithm, buf);
8017 	if (index >= per_sta_keys_start)
8018 		bwn_key_macwrite(mac, index, mac_addr);
8019 
8020 	mac->mac_key[index].algorithm = algorithm;
8021 }
8022 
8023 static void
8024 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8025 {
8026 	struct bwn_softc *sc = mac->mac_sc;
8027 	uint32_t addrtmp[2] = { 0, 0 };
8028 	uint8_t start = 8;
8029 
8030 	if (BWN_SEC_NEWAPI(mac))
8031 		start = 4;
8032 
8033 	KASSERT(index >= start,
8034 	    ("%s:%d: fail", __func__, __LINE__));
8035 	index -= start;
8036 
8037 	if (addr) {
8038 		addrtmp[0] = addr[0];
8039 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8040 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8041 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8042 		addrtmp[1] = addr[4];
8043 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8044 	}
8045 
8046 	if (siba_get_revid(sc->sc_dev) >= 5) {
8047 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8048 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8049 	} else {
8050 		if (index >= 8) {
8051 			bwn_shm_write_4(mac, BWN_SHARED,
8052 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8053 			bwn_shm_write_2(mac, BWN_SHARED,
8054 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8055 		}
8056 	}
8057 }
8058 
8059 static void
8060 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8061     const uint8_t *key)
8062 {
8063 	unsigned int i;
8064 	uint32_t offset;
8065 	uint16_t kidx, value;
8066 
8067 	kidx = BWN_SEC_KEY2FW(mac, index);
8068 	bwn_shm_write_2(mac, BWN_SHARED,
8069 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8070 
8071 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8072 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8073 		value = key[i];
8074 		value |= (uint16_t)(key[i + 1]) << 8;
8075 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8076 	}
8077 }
8078 
8079 static void
8080 bwn_phy_exit(struct bwn_mac *mac)
8081 {
8082 
8083 	mac->mac_phy.rf_onoff(mac, 0);
8084 	if (mac->mac_phy.exit != NULL)
8085 		mac->mac_phy.exit(mac);
8086 }
8087 
8088 static void
8089 bwn_dma_free(struct bwn_mac *mac)
8090 {
8091 	struct bwn_dma *dma;
8092 
8093 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8094 		return;
8095 	dma = &mac->mac_method.dma;
8096 
8097 	bwn_dma_ringfree(&dma->rx);
8098 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8099 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8100 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8101 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8102 	bwn_dma_ringfree(&dma->mcast);
8103 }
8104 
8105 static void
8106 bwn_core_stop(struct bwn_mac *mac)
8107 {
8108 	struct bwn_softc *sc = mac->mac_sc;
8109 
8110 	wlan_assert_serialized();
8111 
8112 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8113 		return;
8114 
8115 	callout_stop(&sc->sc_rfswitch_ch);
8116 	callout_stop(&sc->sc_task_ch);
8117 	callout_stop(&sc->sc_watchdog_ch);
8118 	sc->sc_watchdog_timer = 0;
8119 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8120 	BWN_READ_4(mac, BWN_INTR_MASK);
8121 	bwn_mac_suspend(mac);
8122 
8123 	mac->mac_status = BWN_MAC_STATUS_INITED;
8124 }
8125 
8126 static int
8127 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8128 {
8129 	struct bwn_mac *up_dev = NULL;
8130 	struct bwn_mac *down_dev;
8131 	struct bwn_mac *mac;
8132 	int err, status;
8133 	uint8_t gmode;
8134 
8135 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8136 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8137 		    mac->mac_phy.supports_2ghz) {
8138 			up_dev = mac;
8139 			gmode = 1;
8140 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8141 		    mac->mac_phy.supports_5ghz) {
8142 			up_dev = mac;
8143 			gmode = 0;
8144 		} else {
8145 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8146 			return (EINVAL);
8147 		}
8148 		if (up_dev != NULL)
8149 			break;
8150 	}
8151 	if (up_dev == NULL) {
8152 		device_printf(sc->sc_dev, "Could not find a device\n");
8153 		return (ENODEV);
8154 	}
8155 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8156 		return (0);
8157 
8158 	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8159 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8160 
8161 	down_dev = sc->sc_curmac;
8162 	status = down_dev->mac_status;
8163 	if (status >= BWN_MAC_STATUS_STARTED)
8164 		bwn_core_stop(down_dev);
8165 	if (status >= BWN_MAC_STATUS_INITED)
8166 		bwn_core_exit(down_dev);
8167 
8168 	if (down_dev != up_dev)
8169 		bwn_phy_reset(down_dev);
8170 
8171 	up_dev->mac_phy.gmode = gmode;
8172 	if (status >= BWN_MAC_STATUS_INITED) {
8173 		err = bwn_core_init(up_dev);
8174 		if (err) {
8175 			device_printf(sc->sc_dev,
8176 			    "fatal: failed to initialize for %s-GHz\n",
8177 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8178 			goto fail;
8179 		}
8180 	}
8181 	if (status >= BWN_MAC_STATUS_STARTED)
8182 		bwn_core_start(up_dev);
8183 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8184 	sc->sc_curmac = up_dev;
8185 
8186 	return (0);
8187 fail:
8188 	sc->sc_curmac = NULL;
8189 	return (err);
8190 }
8191 
8192 static void
8193 bwn_rf_turnon(struct bwn_mac *mac)
8194 {
8195 
8196 	bwn_mac_suspend(mac);
8197 	mac->mac_phy.rf_onoff(mac, 1);
8198 	mac->mac_phy.rf_on = 1;
8199 	bwn_mac_enable(mac);
8200 }
8201 
8202 static void
8203 bwn_rf_turnoff(struct bwn_mac *mac)
8204 {
8205 
8206 	bwn_mac_suspend(mac);
8207 	mac->mac_phy.rf_onoff(mac, 0);
8208 	mac->mac_phy.rf_on = 0;
8209 	bwn_mac_enable(mac);
8210 }
8211 
8212 static void
8213 bwn_phy_reset(struct bwn_mac *mac)
8214 {
8215 	struct bwn_softc *sc = mac->mac_sc;
8216 
8217 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8218 	    ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8219 	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8220 	DELAY(1000);
8221 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8222 	    (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8223 	    BWN_TGSLOW_PHYRESET);
8224 	DELAY(1000);
8225 }
8226 
8227 static int
8228 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8229 {
8230 	struct bwn_vap *bvp = BWN_VAP(vap);
8231 	struct ieee80211com *ic= vap->iv_ic;
8232 	struct ifnet *ifp = ic->ic_ifp;
8233 	enum ieee80211_state ostate = vap->iv_state;
8234 	struct bwn_softc *sc = ifp->if_softc;
8235 	struct bwn_mac *mac = sc->sc_curmac;
8236 	int error;
8237 
8238 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8239 	    ieee80211_state_name[vap->iv_state],
8240 	    ieee80211_state_name[nstate]);
8241 
8242 	error = bvp->bv_newstate(vap, nstate, arg);
8243 	if (error != 0)
8244 		return (error);
8245 
8246 	bwn_led_newstate(mac, nstate);
8247 
8248 	/*
8249 	 * Clear the BSSID when we stop a STA
8250 	 */
8251 	if (vap->iv_opmode == IEEE80211_M_STA) {
8252 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8253 			/*
8254 			 * Clear out the BSSID.  If we reassociate to
8255 			 * the same AP, this will reinialize things
8256 			 * correctly...
8257 			 */
8258 			if (ic->ic_opmode == IEEE80211_M_STA &&
8259 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8260 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8261 				bwn_set_macaddr(mac);
8262 			}
8263 		}
8264 	}
8265 
8266 	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8267 	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
8268 		/* XXX nothing to do? */
8269 	} else if (nstate == IEEE80211_S_RUN) {
8270 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8271 		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8272 		bwn_set_opmode(mac);
8273 		bwn_set_pretbtt(mac);
8274 		bwn_spu_setdelay(mac, 0);
8275 		bwn_set_macaddr(mac);
8276 	}
8277 
8278 	return (error);
8279 }
8280 
8281 static void
8282 bwn_set_pretbtt(struct bwn_mac *mac)
8283 {
8284 	struct bwn_softc *sc = mac->mac_sc;
8285 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8286 	uint16_t pretbtt;
8287 
8288 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8289 		pretbtt = 2;
8290 	else
8291 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8292 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8293 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8294 }
8295 
8296 static void
8297 bwn_intr(void *arg)
8298 {
8299 	struct bwn_mac *mac = arg;
8300 	struct bwn_softc *sc = mac->mac_sc;
8301 	uint32_t reason;
8302 
8303 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8304 	    (sc->sc_flags & BWN_FLAG_INVALID))
8305 		return;
8306 
8307 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
8308 	if (reason == 0xffffffff)	/* shared IRQ */
8309 		return;
8310 	reason &= mac->mac_intr_mask;
8311 	if (reason == 0)
8312 		return;
8313 
8314 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00;
8315 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8316 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8317 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8318 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8319 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8320 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8321 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8322 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8323 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8324 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8325 
8326 	/* Disable interrupts. */
8327 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8328 
8329 	mac->mac_reason_intr = reason;
8330 
8331 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8332 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8333 
8334 	taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
8335 	return;
8336 }
8337 
8338 static void
8339 bwn_intrtask(void *arg, int npending)
8340 {
8341 	struct bwn_mac *mac = arg;
8342 	struct bwn_softc *sc = mac->mac_sc;
8343 	struct ifnet *ifp = sc->sc_ifp;
8344 	uint32_t merged = 0;
8345 	int i, tx = 0, rx = 0;
8346 
8347 	wlan_serialize_enter();
8348 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8349 	    (sc->sc_flags & BWN_FLAG_INVALID)) {
8350 		wlan_serialize_exit();
8351 		return;
8352 	}
8353 
8354 	for (i = 0; i < N(mac->mac_reason); i++)
8355 		merged |= mac->mac_reason[i];
8356 
8357 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8358 		device_printf(sc->sc_dev, "MAC trans error\n");
8359 
8360 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8361 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8362 		mac->mac_phy.txerrors--;
8363 		if (mac->mac_phy.txerrors == 0) {
8364 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8365 			bwn_restart(mac, "PHY TX errors");
8366 		}
8367 	}
8368 
8369 	if (merged & BWN_DMAINTR_FATALMASK) {
8370 		device_printf(sc->sc_dev,
8371 		    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8372 		    mac->mac_reason[0], mac->mac_reason[1],
8373 		    mac->mac_reason[2], mac->mac_reason[3],
8374 		    mac->mac_reason[4], mac->mac_reason[5]);
8375 		bwn_restart(mac, "DMA error");
8376 		wlan_serialize_exit();
8377 		return;
8378 	}
8379 
8380 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8381 		bwn_intr_ucode_debug(mac);
8382 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8383 		bwn_intr_tbtt_indication(mac);
8384 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8385 		bwn_intr_atim_end(mac);
8386 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
8387 		bwn_intr_beacon(mac);
8388 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
8389 		bwn_intr_pmq(mac);
8390 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8391 		bwn_intr_noise(mac);
8392 
8393 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8394 		if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) {
8395 			device_printf(sc->sc_dev, "RX descriptor overflow\n");
8396 			bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx);
8397 		}
8398 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8399 			bwn_dma_rx(mac->mac_method.dma.rx);
8400 			rx = 1;
8401 		}
8402 	} else
8403 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8404 
8405 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8406 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8407 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8408 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8409 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8410 
8411 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8412 		bwn_intr_txeof(mac);
8413 		tx = 1;
8414 	}
8415 
8416 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8417 
8418 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8419 		int evt = BWN_LED_EVENT_NONE;
8420 
8421 		if (tx && rx) {
8422 			if (sc->sc_rx_rate > sc->sc_tx_rate)
8423 				evt = BWN_LED_EVENT_RX;
8424 			else
8425 				evt = BWN_LED_EVENT_TX;
8426 		} else if (tx) {
8427 			evt = BWN_LED_EVENT_TX;
8428 		} else if (rx) {
8429 			evt = BWN_LED_EVENT_RX;
8430 		} else if (rx == 0) {
8431 			evt = BWN_LED_EVENT_POLL;
8432 		}
8433 
8434 		if (evt != BWN_LED_EVENT_NONE)
8435 			bwn_led_event(mac, evt);
8436        }
8437 
8438 	if (!ifq_is_oactive(&ifp->if_snd)) {
8439 		if (!ifq_is_empty(&ifp->if_snd))
8440 			bwn_start_locked(ifp);
8441 	}
8442 
8443 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8445 
8446 	wlan_serialize_exit();
8447 }
8448 
8449 static void
8450 bwn_restart(struct bwn_mac *mac, const char *msg)
8451 {
8452 	struct bwn_softc *sc = mac->mac_sc;
8453 	struct ifnet *ifp = sc->sc_ifp;
8454 	struct ieee80211com *ic = ifp->if_l2com;
8455 
8456 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
8457 		return;
8458 
8459 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8460 	ieee80211_runtask(ic, &mac->mac_hwreset);
8461 }
8462 
8463 static void
8464 bwn_intr_ucode_debug(struct bwn_mac *mac)
8465 {
8466 	struct bwn_softc *sc = mac->mac_sc;
8467 	uint16_t reason;
8468 
8469 	if (mac->mac_fw.opensource == 0)
8470 		return;
8471 
8472 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8473 	switch (reason) {
8474 	case BWN_DEBUGINTR_PANIC:
8475 		bwn_handle_fwpanic(mac);
8476 		break;
8477 	case BWN_DEBUGINTR_DUMP_SHM:
8478 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8479 		break;
8480 	case BWN_DEBUGINTR_DUMP_REGS:
8481 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8482 		break;
8483 	case BWN_DEBUGINTR_MARKER:
8484 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8485 		break;
8486 	default:
8487 		device_printf(sc->sc_dev,
8488 		    "ucode debug unknown reason: %#x\n", reason);
8489 	}
8490 
8491 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8492 	    BWN_DEBUGINTR_ACK);
8493 }
8494 
8495 static void
8496 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8497 {
8498 	struct bwn_softc *sc = mac->mac_sc;
8499 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8500 
8501 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8502 		bwn_psctl(mac, 0);
8503 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8504 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8505 }
8506 
8507 static void
8508 bwn_intr_atim_end(struct bwn_mac *mac)
8509 {
8510 
8511 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8512 		BWN_WRITE_4(mac, BWN_MACCMD,
8513 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8514 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8515 	}
8516 }
8517 
8518 static void
8519 bwn_intr_beacon(struct bwn_mac *mac)
8520 {
8521 	struct bwn_softc *sc = mac->mac_sc;
8522 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8523 	uint32_t cmd, beacon0, beacon1;
8524 
8525 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8526 	    ic->ic_opmode == IEEE80211_M_MBSS)
8527 		return;
8528 
8529 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8530 
8531 	cmd = BWN_READ_4(mac, BWN_MACCMD);
8532 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8533 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8534 
8535 	if (beacon0 && beacon1) {
8536 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8537 		mac->mac_intr_mask |= BWN_INTR_BEACON;
8538 		return;
8539 	}
8540 
8541 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8542 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8543 		bwn_load_beacon0(mac);
8544 		bwn_load_beacon1(mac);
8545 		cmd = BWN_READ_4(mac, BWN_MACCMD);
8546 		cmd |= BWN_MACCMD_BEACON0_VALID;
8547 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8548 	} else {
8549 		if (!beacon0) {
8550 			bwn_load_beacon0(mac);
8551 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8552 			cmd |= BWN_MACCMD_BEACON0_VALID;
8553 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8554 		} else if (!beacon1) {
8555 			bwn_load_beacon1(mac);
8556 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8557 			cmd |= BWN_MACCMD_BEACON1_VALID;
8558 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8559 		}
8560 	}
8561 }
8562 
8563 static void
8564 bwn_intr_pmq(struct bwn_mac *mac)
8565 {
8566 	uint32_t tmp;
8567 
8568 	while (1) {
8569 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8570 		if (!(tmp & 0x00000008))
8571 			break;
8572 	}
8573 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8574 }
8575 
8576 static void
8577 bwn_intr_noise(struct bwn_mac *mac)
8578 {
8579 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8580 	uint16_t tmp;
8581 	uint8_t noise[4];
8582 	uint8_t i, j;
8583 	int32_t average;
8584 
8585 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
8586 		return;
8587 
8588 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8589 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8590 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8591 	    noise[3] == 0x7f)
8592 		goto new;
8593 
8594 	KASSERT(mac->mac_noise.noi_nsamples < 8,
8595 	    ("%s:%d: fail", __func__, __LINE__));
8596 	i = mac->mac_noise.noi_nsamples;
8597 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8598 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8599 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8600 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8601 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8602 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8603 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8604 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8605 	mac->mac_noise.noi_nsamples++;
8606 	if (mac->mac_noise.noi_nsamples == 8) {
8607 		average = 0;
8608 		for (i = 0; i < 8; i++) {
8609 			for (j = 0; j < 4; j++)
8610 				average += mac->mac_noise.noi_samples[i][j];
8611 		}
8612 		average = (((average / 32) * 125) + 64) / 128;
8613 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8614 		if (tmp >= 8)
8615 			average += 2;
8616 		else
8617 			average -= 25;
8618 		average -= (tmp == 8) ? 72 : 48;
8619 
8620 		mac->mac_stats.link_noise = average;
8621 		mac->mac_noise.noi_running = 0;
8622 		return;
8623 	}
8624 new:
8625 	bwn_noise_gensample(mac);
8626 }
8627 
8628 static int
8629 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8630 {
8631 	struct bwn_mac *mac = prq->prq_mac;
8632 	struct bwn_softc *sc = mac->mac_sc;
8633 	unsigned int i;
8634 
8635 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8636 		return (0);
8637 
8638 	for (i = 0; i < 5000; i++) {
8639 		if (bwn_pio_rxeof(prq) == 0)
8640 			break;
8641 	}
8642 	if (i >= 5000)
8643 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8644 	return ((i > 0) ? 1 : 0);
8645 }
8646 
8647 static void
8648 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr)
8649 {
8650 	int curslot, prevslot;
8651 
8652 	curslot = dr->get_curslot(dr);
8653 	if (curslot == 0)
8654 		prevslot = dr->dr_numslots - 1;
8655 	else
8656 		prevslot = curslot - 1;
8657 	dr->set_curslot(dr, prevslot);
8658 }
8659 
8660 static void
8661 bwn_dma_rx(struct bwn_dma_ring *dr)
8662 {
8663 	int slot, curslot;
8664 
8665 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8666 	curslot = dr->get_curslot(dr);
8667 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8668 	    ("%s:%d: fail", __func__, __LINE__));
8669 
8670 	slot = dr->dr_curslot;
8671 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8672 		bwn_dma_rxeof(dr, &slot);
8673 
8674 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8675 	    BUS_DMASYNC_PREWRITE);
8676 
8677 	dr->set_curslot(dr, slot);
8678 	dr->dr_curslot = slot;
8679 }
8680 
8681 static void
8682 bwn_intr_txeof(struct bwn_mac *mac)
8683 {
8684 	struct bwn_txstatus stat;
8685 	uint32_t stat0, stat1;
8686 	uint16_t tmp;
8687 
8688 	while (1) {
8689 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8690 		if (!(stat0 & 0x00000001))
8691 			break;
8692 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8693 
8694 		stat.cookie = (stat0 >> 16);
8695 		stat.seq = (stat1 & 0x0000ffff);
8696 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8697 		tmp = (stat0 & 0x0000ffff);
8698 		stat.framecnt = ((tmp & 0xf000) >> 12);
8699 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
8700 		stat.sreason = ((tmp & 0x001c) >> 2);
8701 		stat.pm = (tmp & 0x0080) ? 1 : 0;
8702 		stat.im = (tmp & 0x0040) ? 1 : 0;
8703 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8704 		stat.ack = (tmp & 0x0002) ? 1 : 0;
8705 
8706 		bwn_handle_txeof(mac, &stat);
8707 	}
8708 }
8709 
8710 static void
8711 bwn_hwreset(void *arg, int npending)
8712 {
8713 	struct bwn_mac *mac = arg;
8714 	struct bwn_softc *sc = mac->mac_sc;
8715 	int error = 0;
8716 	int prev_status;
8717 
8718 	wlan_serialize_enter();
8719 
8720 	prev_status = mac->mac_status;
8721 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8722 		bwn_core_stop(mac);
8723 	if (prev_status >= BWN_MAC_STATUS_INITED)
8724 		bwn_core_exit(mac);
8725 
8726 	if (prev_status >= BWN_MAC_STATUS_INITED) {
8727 		error = bwn_core_init(mac);
8728 		if (error)
8729 			goto out;
8730 	}
8731 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8732 		bwn_core_start(mac);
8733 out:
8734 	if (error) {
8735 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8736 		sc->sc_curmac = NULL;
8737 	}
8738 	wlan_serialize_exit();
8739 }
8740 
8741 static void
8742 bwn_handle_fwpanic(struct bwn_mac *mac)
8743 {
8744 	struct bwn_softc *sc = mac->mac_sc;
8745 	uint16_t reason;
8746 
8747 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8748 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8749 
8750 	if (reason == BWN_FWPANIC_RESTART)
8751 		bwn_restart(mac, "ucode panic");
8752 }
8753 
8754 static void
8755 bwn_load_beacon0(struct bwn_mac *mac)
8756 {
8757 
8758 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8759 }
8760 
8761 static void
8762 bwn_load_beacon1(struct bwn_mac *mac)
8763 {
8764 
8765 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8766 }
8767 
8768 static uint32_t
8769 bwn_jssi_read(struct bwn_mac *mac)
8770 {
8771 	uint32_t val = 0;
8772 
8773 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8774 	val <<= 16;
8775 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8776 
8777 	return (val);
8778 }
8779 
8780 static void
8781 bwn_noise_gensample(struct bwn_mac *mac)
8782 {
8783 	uint32_t jssi = 0x7f7f7f7f;
8784 
8785 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8786 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8787 	BWN_WRITE_4(mac, BWN_MACCMD,
8788 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8789 }
8790 
8791 static int
8792 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8793 {
8794 	return (dr->dr_numslots - dr->dr_usedslot);
8795 }
8796 
8797 static int
8798 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8799 {
8800 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8801 	    ("%s:%d: fail", __func__, __LINE__));
8802 	if (slot == dr->dr_numslots - 1)
8803 		return (0);
8804 	return (slot + 1);
8805 }
8806 
8807 static void
8808 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8809 {
8810 	struct bwn_mac *mac = dr->dr_mac;
8811 	struct bwn_softc *sc = mac->mac_sc;
8812 	struct bwn_dma *dma = &mac->mac_method.dma;
8813 	struct bwn_dmadesc_generic *desc;
8814 	struct bwn_dmadesc_meta *meta;
8815 	struct bwn_rxhdr4 *rxhdr;
8816 	struct ifnet *ifp = sc->sc_ifp;
8817 	struct mbuf *m;
8818 	uint32_t macstat;
8819 	int32_t tmp;
8820 	int cnt = 0;
8821 	uint16_t len;
8822 
8823 	dr->getdesc(dr, *slot, &desc, &meta);
8824 
8825 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8826 	m = meta->mt_m;
8827 
8828 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8829 		ifp->if_ierrors++;
8830 		return;
8831 	}
8832 
8833 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
8834 	len = le16toh(rxhdr->frame_len);
8835 	if (len <= 0) {
8836 		ifp->if_ierrors++;
8837 		return;
8838 	}
8839 	if (bwn_dma_check_redzone(dr, m)) {
8840 		device_printf(sc->sc_dev, "redzone error.\n");
8841 		bwn_dma_set_redzone(dr, m);
8842 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8843 		    BUS_DMASYNC_PREWRITE);
8844 		return;
8845 	}
8846 	if (len > dr->dr_rx_bufsize) {
8847 		tmp = len;
8848 		while (1) {
8849 			dr->getdesc(dr, *slot, &desc, &meta);
8850 			bwn_dma_set_redzone(dr, meta->mt_m);
8851 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8852 			    BUS_DMASYNC_PREWRITE);
8853 			*slot = bwn_dma_nextslot(dr, *slot);
8854 			cnt++;
8855 			tmp -= dr->dr_rx_bufsize;
8856 			if (tmp <= 0)
8857 				break;
8858 		}
8859 		device_printf(sc->sc_dev, "too small buffer "
8860 		       "(len %u buffer %u dropped %d)\n",
8861 		       len, dr->dr_rx_bufsize, cnt);
8862 		return;
8863 	}
8864 	macstat = le32toh(rxhdr->mac_status);
8865 	if (macstat & BWN_RX_MAC_FCSERR) {
8866 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8867 			device_printf(sc->sc_dev, "RX drop\n");
8868 			return;
8869 		}
8870 	}
8871 
8872 	m->m_pkthdr.rcvif = ifp;
8873 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8874 	m_adj(m, dr->dr_frameoffset);
8875 
8876 	bwn_rxeof(dr->dr_mac, m, rxhdr);
8877 }
8878 
8879 static void
8880 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8881 {
8882 	struct bwn_dma_ring *dr;
8883 	struct bwn_dmadesc_generic *desc;
8884 	struct bwn_dmadesc_meta *meta;
8885 	struct bwn_pio_txqueue *tq;
8886 	struct bwn_pio_txpkt *tp = NULL;
8887 	struct bwn_softc *sc = mac->mac_sc;
8888 	struct bwn_stats *stats = &mac->mac_stats;
8889 	struct ieee80211_node *ni;
8890 	struct ieee80211vap *vap;
8891 	int retrycnt = 0, slot;
8892 
8893 	if (status->im)
8894 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8895 	if (status->ampdu)
8896 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8897 	if (status->rtscnt) {
8898 		if (status->rtscnt == 0xf)
8899 			stats->rtsfail++;
8900 		else
8901 			stats->rts++;
8902 	}
8903 
8904 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8905 		if (status->ack) {
8906 			dr = bwn_dma_parse_cookie(mac, status,
8907 			    status->cookie, &slot);
8908 			if (dr == NULL) {
8909 				device_printf(sc->sc_dev,
8910 				    "failed to parse cookie\n");
8911 				return;
8912 			}
8913 			while (1) {
8914 				dr->getdesc(dr, slot, &desc, &meta);
8915 				if (meta->mt_islast) {
8916 					ni = meta->mt_ni;
8917 					vap = ni->ni_vap;
8918 					ieee80211_ratectl_tx_complete(vap, ni,
8919 					    status->ack ?
8920 					      IEEE80211_RATECTL_TX_SUCCESS :
8921 					      IEEE80211_RATECTL_TX_FAILURE,
8922 					    &retrycnt, 0);
8923 					break;
8924 				}
8925 				slot = bwn_dma_nextslot(dr, slot);
8926 			}
8927 		}
8928 		bwn_dma_handle_txeof(mac, status);
8929 	} else {
8930 		if (status->ack) {
8931 			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8932 			if (tq == NULL) {
8933 				device_printf(sc->sc_dev,
8934 				    "failed to parse cookie\n");
8935 				return;
8936 			}
8937 			ni = tp->tp_ni;
8938 			vap = ni->ni_vap;
8939 			ieee80211_ratectl_tx_complete(vap, ni,
8940 			    status->ack ?
8941 			      IEEE80211_RATECTL_TX_SUCCESS :
8942 			      IEEE80211_RATECTL_TX_FAILURE,
8943 			    &retrycnt, 0);
8944 		}
8945 		bwn_pio_handle_txeof(mac, status);
8946 	}
8947 
8948 	bwn_phy_txpower_check(mac, 0);
8949 }
8950 
8951 static uint8_t
8952 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8953 {
8954 	struct bwn_mac *mac = prq->prq_mac;
8955 	struct bwn_softc *sc = mac->mac_sc;
8956 	struct bwn_rxhdr4 rxhdr;
8957 	struct ifnet *ifp = sc->sc_ifp;
8958 	struct mbuf *m;
8959 	uint32_t ctl32, macstat, v32;
8960 	unsigned int i, padding;
8961 	uint16_t ctl16, len, totlen, v16;
8962 	unsigned char *mp;
8963 	char *data;
8964 
8965 	memset(&rxhdr, 0, sizeof(rxhdr));
8966 
8967 	if (prq->prq_rev >= 8) {
8968 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8969 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8970 			return (0);
8971 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8972 		    BWN_PIO8_RXCTL_FRAMEREADY);
8973 		for (i = 0; i < 10; i++) {
8974 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8975 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8976 				goto ready;
8977 			DELAY(10);
8978 		}
8979 	} else {
8980 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8981 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8982 			return (0);
8983 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8984 		    BWN_PIO_RXCTL_FRAMEREADY);
8985 		for (i = 0; i < 10; i++) {
8986 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8987 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8988 				goto ready;
8989 			DELAY(10);
8990 		}
8991 	}
8992 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8993 	return (1);
8994 ready:
8995 	if (prq->prq_rev >= 8)
8996 		siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8997 		    prq->prq_base + BWN_PIO8_RXDATA);
8998 	else
8999 		siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9000 		    prq->prq_base + BWN_PIO_RXDATA);
9001 	len = le16toh(rxhdr.frame_len);
9002 	if (len > 0x700) {
9003 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9004 		goto error;
9005 	}
9006 	if (len == 0) {
9007 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9008 		goto error;
9009 	}
9010 
9011 	macstat = le32toh(rxhdr.mac_status);
9012 	if (macstat & BWN_RX_MAC_FCSERR) {
9013 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9014 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
9015 			goto error;
9016 		}
9017 	}
9018 
9019 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9020 	totlen = len + padding;
9021 	KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9022 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9023 	if (m == NULL) {
9024 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
9025 		goto error;
9026 	}
9027 	mp = mtod(m, unsigned char *);
9028 	if (prq->prq_rev >= 8) {
9029 		siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9030 		    prq->prq_base + BWN_PIO8_RXDATA);
9031 		if (totlen & 3) {
9032 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9033 			data = &(mp[totlen - 1]);
9034 			switch (totlen & 3) {
9035 			case 3:
9036 				*data = (v32 >> 16);
9037 				data--;
9038 			case 2:
9039 				*data = (v32 >> 8);
9040 				data--;
9041 			case 1:
9042 				*data = v32;
9043 			}
9044 		}
9045 	} else {
9046 		siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9047 		    prq->prq_base + BWN_PIO_RXDATA);
9048 		if (totlen & 1) {
9049 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9050 			mp[totlen - 1] = v16;
9051 		}
9052 	}
9053 
9054 	m->m_pkthdr.rcvif = ifp;
9055 	m->m_len = m->m_pkthdr.len = totlen;
9056 
9057 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
9058 
9059 	return (1);
9060 error:
9061 	if (prq->prq_rev >= 8)
9062 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9063 		    BWN_PIO8_RXCTL_DATAREADY);
9064 	else
9065 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9066 	return (1);
9067 }
9068 
9069 static int
9070 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9071     struct bwn_dmadesc_meta *meta, int init)
9072 {
9073 	struct bwn_mac *mac = dr->dr_mac;
9074 	struct bwn_dma *dma = &mac->mac_method.dma;
9075 	struct bwn_rxhdr4 *hdr;
9076 	bus_dmamap_t map;
9077 	bus_addr_t paddr;
9078 	struct mbuf *m;
9079 	int error;
9080 
9081 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9082 	if (m == NULL) {
9083 		error = ENOBUFS;
9084 
9085 		/*
9086 		 * If the NIC is up and running, we need to:
9087 		 * - Clear RX buffer's header.
9088 		 * - Restore RX descriptor settings.
9089 		 */
9090 		if (init)
9091 			return (error);
9092 		else
9093 			goto back;
9094 	}
9095 	m->m_len = m->m_pkthdr.len = MCLBYTES;
9096 
9097 	bwn_dma_set_redzone(dr, m);
9098 
9099 	/*
9100 	 * Try to load RX buf into temporary DMA map
9101 	 */
9102 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9103 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9104 	if (error) {
9105 		m_freem(m);
9106 
9107 		/*
9108 		 * See the comment above
9109 		 */
9110 		if (init)
9111 			return (error);
9112 		else
9113 			goto back;
9114 	}
9115 
9116 	if (!init)
9117 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9118 	meta->mt_m = m;
9119 	meta->mt_paddr = paddr;
9120 
9121 	/*
9122 	 * Swap RX buf's DMA map with the loaded temporary one
9123 	 */
9124 	map = meta->mt_dmap;
9125 	meta->mt_dmap = dr->dr_spare_dmap;
9126 	dr->dr_spare_dmap = map;
9127 
9128 back:
9129 	/*
9130 	 * Clear RX buf header
9131 	 */
9132 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9133 	bzero(hdr, sizeof(*hdr));
9134 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9135 	    BUS_DMASYNC_PREWRITE);
9136 
9137 	/*
9138 	 * Setup RX buf descriptor
9139 	 */
9140 	dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9141 	    sizeof(*hdr), 0, 0, 0);
9142 	return (error);
9143 }
9144 
9145 static void
9146 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9147 		 bus_size_t mapsz __unused, int error)
9148 {
9149 
9150 	if (!error) {
9151 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9152 		*((bus_addr_t *)arg) = seg->ds_addr;
9153 	}
9154 }
9155 
9156 static int
9157 bwn_hwrate2ieeerate(int rate)
9158 {
9159 
9160 	switch (rate) {
9161 	case BWN_CCK_RATE_1MB:
9162 		return (2);
9163 	case BWN_CCK_RATE_2MB:
9164 		return (4);
9165 	case BWN_CCK_RATE_5MB:
9166 		return (11);
9167 	case BWN_CCK_RATE_11MB:
9168 		return (22);
9169 	case BWN_OFDM_RATE_6MB:
9170 		return (12);
9171 	case BWN_OFDM_RATE_9MB:
9172 		return (18);
9173 	case BWN_OFDM_RATE_12MB:
9174 		return (24);
9175 	case BWN_OFDM_RATE_18MB:
9176 		return (36);
9177 	case BWN_OFDM_RATE_24MB:
9178 		return (48);
9179 	case BWN_OFDM_RATE_36MB:
9180 		return (72);
9181 	case BWN_OFDM_RATE_48MB:
9182 		return (96);
9183 	case BWN_OFDM_RATE_54MB:
9184 		return (108);
9185 	default:
9186 		kprintf("Ooops\n");
9187 		return (0);
9188 	}
9189 }
9190 
9191 static void
9192 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9193 {
9194 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9195 	struct bwn_plcp6 *plcp;
9196 	struct bwn_softc *sc = mac->mac_sc;
9197 	struct ieee80211_frame_min *wh;
9198 	struct ieee80211_node *ni;
9199 	struct ifnet *ifp = sc->sc_ifp;
9200 	struct ieee80211com *ic = ifp->if_l2com;
9201 	uint32_t macstat;
9202 	int padding, rate, rssi = 0, noise = 0, type;
9203 	uint16_t phytype, phystat0, phystat3, chanstat;
9204 	unsigned char *mp = mtod(m, unsigned char *);
9205 	static int rx_mac_dec_rpt = 0;
9206 
9207 	phystat0 = le16toh(rxhdr->phy_status0);
9208 	phystat3 = le16toh(rxhdr->phy_status3);
9209 	macstat = le32toh(rxhdr->mac_status);
9210 	chanstat = le16toh(rxhdr->channel);
9211 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9212 
9213 	if (macstat & BWN_RX_MAC_FCSERR)
9214 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9215 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9216 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9217 	if (macstat & BWN_RX_MAC_DECERR)
9218 		goto drop;
9219 
9220 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9221 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9222 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9223 		    m->m_pkthdr.len);
9224 		goto drop;
9225 	}
9226 	plcp = (struct bwn_plcp6 *)(mp + padding);
9227 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
9228 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9229 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9230 		    m->m_pkthdr.len);
9231 		goto drop;
9232 	}
9233 	wh = mtod(m, struct ieee80211_frame_min *);
9234 
9235 	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9236 		device_printf(sc->sc_dev,
9237 		    "RX decryption attempted (old %d keyidx %#x)\n",
9238 		    BWN_ISOLDFMT(mac),
9239 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9240 
9241 	/* XXX calculating RSSI & noise & antenna */
9242 
9243 	if (phystat0 & BWN_RX_PHYST0_OFDM)
9244 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
9245 		    phytype == BWN_PHYTYPE_A);
9246 	else
9247 		rate = bwn_plcp_get_cckrate(mac, plcp);
9248 	if (rate == -1) {
9249 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9250 			goto drop;
9251 	}
9252 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9253 
9254 	/* RX radio tap */
9255 	if (ieee80211_radiotap_active(ic))
9256 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9257 	m_adj(m, -IEEE80211_CRC_LEN);
9258 
9259 	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
9260 	noise = mac->mac_stats.link_noise;
9261 
9262 	ifp->if_ipackets++;
9263 
9264 	ni = ieee80211_find_rxnode(ic, wh);
9265 	if (ni != NULL) {
9266 		type = ieee80211_input(ni, m, rssi, noise);
9267 		ieee80211_free_node(ni);
9268 	} else
9269 		type = ieee80211_input_all(ic, m, rssi, noise);
9270 
9271 	return;
9272 drop:
9273 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9274 }
9275 
9276 static void
9277 bwn_dma_handle_txeof(struct bwn_mac *mac,
9278     const struct bwn_txstatus *status)
9279 {
9280 	struct bwn_dma *dma = &mac->mac_method.dma;
9281 	struct bwn_dma_ring *dr;
9282 	struct bwn_dmadesc_generic *desc;
9283 	struct bwn_dmadesc_meta *meta;
9284 	struct bwn_softc *sc = mac->mac_sc;
9285 	struct ieee80211_node *ni;
9286 	struct ifnet *ifp = sc->sc_ifp;
9287 	struct mbuf *m;
9288 	int slot;
9289 
9290 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9291 	if (dr == NULL) {
9292 		device_printf(sc->sc_dev, "failed to parse cookie\n");
9293 		return;
9294 	}
9295 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9296 
9297 	while (1) {
9298 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
9299 		    ("%s:%d: fail", __func__, __LINE__));
9300 		dr->getdesc(dr, slot, &desc, &meta);
9301 
9302 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
9303 			bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap,
9304 			    BUS_DMASYNC_POSTWRITE);
9305 		} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
9306 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9307 		}
9308 
9309 		if (meta->mt_islast) {
9310 			KASSERT(meta->mt_m != NULL,
9311 			    ("%s:%d: fail", __func__, __LINE__));
9312 
9313 			ni = meta->mt_ni;
9314 			m = meta->mt_m;
9315 			if (ni != NULL) {
9316 				/*
9317 				 * Do any tx complete callback. Note this must
9318 				 * be done before releasing the node reference.
9319 				 */
9320 				if (m->m_flags & M_TXCB)
9321 					ieee80211_process_callback(ni, m, 0);
9322 				ieee80211_free_node(ni);
9323 				meta->mt_ni = NULL;
9324 			}
9325 			m_freem(m);
9326 			meta->mt_m = NULL;
9327 		} else {
9328 			KASSERT(meta->mt_m == NULL,
9329 			    ("%s:%d: fail", __func__, __LINE__));
9330 		}
9331 
9332 		dr->dr_usedslot--;
9333 		if (meta->mt_islast) {
9334 			ifp->if_opackets++;
9335 			break;
9336 		}
9337 		slot = bwn_dma_nextslot(dr, slot);
9338 	}
9339 	sc->sc_watchdog_timer = 0;
9340 	if (dr->dr_stop) {
9341 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9342 		    ("%s:%d: fail", __func__, __LINE__));
9343 		ifq_clr_oactive(&ifp->if_snd);
9344 		dr->dr_stop = 0;
9345 	}
9346 }
9347 
9348 static void
9349 bwn_pio_handle_txeof(struct bwn_mac *mac,
9350     const struct bwn_txstatus *status)
9351 {
9352 	struct bwn_pio_txqueue *tq;
9353 	struct bwn_pio_txpkt *tp = NULL;
9354 	struct bwn_softc *sc = mac->mac_sc;
9355 	struct ifnet *ifp = sc->sc_ifp;
9356 
9357 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9358 	if (tq == NULL)
9359 		return;
9360 
9361 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9362 	tq->tq_free++;
9363 
9364 	if (tp->tp_ni != NULL) {
9365 		/*
9366 		 * Do any tx complete callback.  Note this must
9367 		 * be done before releasing the node reference.
9368 		 */
9369 		if (tp->tp_m->m_flags & M_TXCB)
9370 			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9371 		ieee80211_free_node(tp->tp_ni);
9372 		tp->tp_ni = NULL;
9373 	}
9374 	m_freem(tp->tp_m);
9375 	tp->tp_m = NULL;
9376 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9377 
9378 	ifp->if_opackets++;
9379 
9380 	sc->sc_watchdog_timer = 0;
9381 	if (tq->tq_stop) {
9382 		ifq_clr_oactive(&ifp->if_snd);
9383 		tq->tq_stop = 0;
9384 	}
9385 }
9386 
9387 static void
9388 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9389 {
9390 	struct bwn_softc *sc = mac->mac_sc;
9391 	struct bwn_phy *phy = &mac->mac_phy;
9392 	struct ifnet *ifp = sc->sc_ifp;
9393 	struct ieee80211com *ic = ifp->if_l2com;
9394 	unsigned long now;
9395 	int result;
9396 
9397 	BWN_GETTIME(now);
9398 
9399 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9400 		return;
9401 	phy->nexttime = now + 2 * 1000;
9402 
9403 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9404 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9405 		return;
9406 
9407 	if (phy->recalc_txpwr != NULL) {
9408 		result = phy->recalc_txpwr(mac,
9409 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9410 		if (result == BWN_TXPWR_RES_DONE)
9411 			return;
9412 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9413 		    ("%s: fail", __func__));
9414 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9415 
9416 		ieee80211_runtask(ic, &mac->mac_txpower);
9417 	}
9418 }
9419 
9420 static uint16_t
9421 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9422 {
9423 
9424 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9425 }
9426 
9427 static uint32_t
9428 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9429 {
9430 
9431 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9432 }
9433 
9434 static void
9435 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9436 {
9437 
9438 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9439 }
9440 
9441 static void
9442 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9443 {
9444 
9445 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9446 }
9447 
9448 static int
9449 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9450 {
9451 
9452 	switch (rate) {
9453 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9454 	case 12:
9455 		return (BWN_OFDM_RATE_6MB);
9456 	case 18:
9457 		return (BWN_OFDM_RATE_9MB);
9458 	case 24:
9459 		return (BWN_OFDM_RATE_12MB);
9460 	case 36:
9461 		return (BWN_OFDM_RATE_18MB);
9462 	case 48:
9463 		return (BWN_OFDM_RATE_24MB);
9464 	case 72:
9465 		return (BWN_OFDM_RATE_36MB);
9466 	case 96:
9467 		return (BWN_OFDM_RATE_48MB);
9468 	case 108:
9469 		return (BWN_OFDM_RATE_54MB);
9470 	/* CCK rates (NB: not IEEE std, device-specific) */
9471 	case 2:
9472 		return (BWN_CCK_RATE_1MB);
9473 	case 4:
9474 		return (BWN_CCK_RATE_2MB);
9475 	case 11:
9476 		return (BWN_CCK_RATE_5MB);
9477 	case 22:
9478 		return (BWN_CCK_RATE_11MB);
9479 	}
9480 
9481 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9482 	return (BWN_CCK_RATE_1MB);
9483 }
9484 
9485 static int
9486 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9487     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9488 {
9489 	const struct bwn_phy *phy = &mac->mac_phy;
9490 	struct bwn_softc *sc = mac->mac_sc;
9491 	struct ieee80211_frame *wh;
9492 	struct ieee80211_frame *protwh;
9493 	struct ieee80211_frame_cts *cts;
9494 	struct ieee80211_frame_rts *rts;
9495 	const struct ieee80211_txparam *tp;
9496 	struct ieee80211vap *vap = ni->ni_vap;
9497 	struct ifnet *ifp = sc->sc_ifp;
9498 	struct ieee80211com *ic = ifp->if_l2com;
9499 	struct mbuf *mprot;
9500 	unsigned int len;
9501 	uint32_t macctl = 0;
9502 	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9503 	uint16_t phyctl = 0;
9504 	uint8_t rate, rate_fb;
9505 
9506 	wh = mtod(m, struct ieee80211_frame *);
9507 	memset(txhdr, 0, sizeof(*txhdr));
9508 
9509 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9510 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9511 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9512 
9513 	/*
9514 	 * Find TX rate
9515 	 */
9516 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9517 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9518 		rate = rate_fb = tp->mgmtrate;
9519 	else if (ismcast)
9520 		rate = rate_fb = tp->mcastrate;
9521 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9522 		rate = rate_fb = tp->ucastrate;
9523 	else {
9524 		rix = ieee80211_ratectl_rate(ni, NULL, 0);
9525 		rate = ni->ni_txrate;
9526 
9527 		if (rix > 0)
9528 			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9529 			    IEEE80211_RATE_VAL;
9530 		else
9531 			rate_fb = rate;
9532 	}
9533 
9534 	sc->sc_tx_rate = rate;
9535 
9536 	rate = bwn_ieeerate2hwrate(sc, rate);
9537 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9538 
9539 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9540 	    bwn_plcp_getcck(rate);
9541 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9542 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9543 
9544 	if ((rate_fb == rate) ||
9545 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9546 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
9547 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9548 	else
9549 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9550 		    m->m_pkthdr.len, rate, isshort);
9551 
9552 	/* XXX TX encryption */
9553 	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9554 	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9555 	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9556 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9557 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9558 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9559 
9560 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9561 	    BWN_TX_EFT_FB_CCK;
9562 	txhdr->chan = phy->chan;
9563 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9564 	    BWN_TX_PHY_ENC_CCK;
9565 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9566 	     rate == BWN_CCK_RATE_11MB))
9567 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
9568 
9569 	/* XXX TX antenna selection */
9570 
9571 	switch (bwn_antenna_sanitize(mac, 0)) {
9572 	case 0:
9573 		phyctl |= BWN_TX_PHY_ANT01AUTO;
9574 		break;
9575 	case 1:
9576 		phyctl |= BWN_TX_PHY_ANT0;
9577 		break;
9578 	case 2:
9579 		phyctl |= BWN_TX_PHY_ANT1;
9580 		break;
9581 	case 3:
9582 		phyctl |= BWN_TX_PHY_ANT2;
9583 		break;
9584 	case 4:
9585 		phyctl |= BWN_TX_PHY_ANT3;
9586 		break;
9587 	default:
9588 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9589 	}
9590 
9591 	if (!ismcast)
9592 		macctl |= BWN_TX_MAC_ACK;
9593 
9594 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9595 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9596 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9597 		macctl |= BWN_TX_MAC_LONGFRAME;
9598 
9599 	if (ic->ic_flags & IEEE80211_F_USEPROT) {
9600 		/* XXX RTS rate is always 1MB??? */
9601 		rts_rate = BWN_CCK_RATE_1MB;
9602 		rts_rate_fb = bwn_get_fbrate(rts_rate);
9603 
9604 		protdur = ieee80211_compute_duration(ic->ic_rt,
9605 		    m->m_pkthdr.len, rate, isshort) +
9606 		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9607 
9608 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9609 			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9610 			    (txhdr->body.old.rts_frame) :
9611 			    (txhdr->body.new.rts_frame));
9612 			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9613 			    protdur);
9614 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9615 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9616 			    mprot->m_pkthdr.len);
9617 			m_freem(mprot);
9618 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9619 			len = sizeof(struct ieee80211_frame_cts);
9620 		} else {
9621 			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9622 			    (txhdr->body.old.rts_frame) :
9623 			    (txhdr->body.new.rts_frame));
9624 			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9625 			    isshort);
9626 			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9627 			    wh->i_addr2, protdur);
9628 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9629 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9630 			    mprot->m_pkthdr.len);
9631 			m_freem(mprot);
9632 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
9633 			len = sizeof(struct ieee80211_frame_rts);
9634 		}
9635 		len += IEEE80211_CRC_LEN;
9636 		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9637 		    &txhdr->body.old.rts_plcp :
9638 		    &txhdr->body.new.rts_plcp), len, rts_rate);
9639 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9640 		    rts_rate_fb);
9641 
9642 		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9643 		    (&txhdr->body.old.rts_frame) :
9644 		    (&txhdr->body.new.rts_frame));
9645 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9646 
9647 		if (BWN_ISOFDMRATE(rts_rate)) {
9648 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9649 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9650 		} else {
9651 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9652 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9653 		}
9654 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9655 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9656 	}
9657 
9658 	if (BWN_ISOLDFMT(mac))
9659 		txhdr->body.old.cookie = htole16(cookie);
9660 	else
9661 		txhdr->body.new.cookie = htole16(cookie);
9662 
9663 	txhdr->macctl = htole32(macctl);
9664 	txhdr->phyctl = htole16(phyctl);
9665 
9666 	/*
9667 	 * TX radio tap
9668 	 */
9669 	if (ieee80211_radiotap_active_vap(vap)) {
9670 		sc->sc_tx_th.wt_flags = 0;
9671 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9672 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9673 		if (isshort &&
9674 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9675 		     rate == BWN_CCK_RATE_11MB))
9676 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9677 		sc->sc_tx_th.wt_rate = rate;
9678 
9679 		ieee80211_radiotap_tx(vap, m);
9680 	}
9681 
9682 	return (0);
9683 }
9684 
9685 static void
9686 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9687     const uint8_t rate)
9688 {
9689 	uint32_t d, plen;
9690 	uint8_t *raw = plcp->o.raw;
9691 
9692 	if (BWN_ISOFDMRATE(rate)) {
9693 		d = bwn_plcp_getofdm(rate);
9694 		KASSERT(!(octets & 0xf000),
9695 		    ("%s:%d: fail", __func__, __LINE__));
9696 		d |= (octets << 5);
9697 		plcp->o.data = htole32(d);
9698 	} else {
9699 		plen = octets * 16 / rate;
9700 		if ((octets * 16 % rate) > 0) {
9701 			plen++;
9702 			if ((rate == BWN_CCK_RATE_11MB)
9703 			    && ((octets * 8 % 11) < 4)) {
9704 				raw[1] = 0x84;
9705 			} else
9706 				raw[1] = 0x04;
9707 		} else
9708 			raw[1] = 0x04;
9709 		plcp->o.data |= htole32(plen << 16);
9710 		raw[0] = bwn_plcp_getcck(rate);
9711 	}
9712 }
9713 
9714 static uint8_t
9715 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9716 {
9717 	struct bwn_softc *sc = mac->mac_sc;
9718 	uint8_t mask;
9719 
9720 	if (n == 0)
9721 		return (0);
9722 	if (mac->mac_phy.gmode)
9723 		mask = siba_sprom_get_ant_bg(sc->sc_dev);
9724 	else
9725 		mask = siba_sprom_get_ant_a(sc->sc_dev);
9726 	if (!(mask & (1 << (n - 1))))
9727 		return (0);
9728 	return (n);
9729 }
9730 
9731 static uint8_t
9732 bwn_get_fbrate(uint8_t bitrate)
9733 {
9734 	switch (bitrate) {
9735 	case BWN_CCK_RATE_1MB:
9736 		return (BWN_CCK_RATE_1MB);
9737 	case BWN_CCK_RATE_2MB:
9738 		return (BWN_CCK_RATE_1MB);
9739 	case BWN_CCK_RATE_5MB:
9740 		return (BWN_CCK_RATE_2MB);
9741 	case BWN_CCK_RATE_11MB:
9742 		return (BWN_CCK_RATE_5MB);
9743 	case BWN_OFDM_RATE_6MB:
9744 		return (BWN_CCK_RATE_5MB);
9745 	case BWN_OFDM_RATE_9MB:
9746 		return (BWN_OFDM_RATE_6MB);
9747 	case BWN_OFDM_RATE_12MB:
9748 		return (BWN_OFDM_RATE_9MB);
9749 	case BWN_OFDM_RATE_18MB:
9750 		return (BWN_OFDM_RATE_12MB);
9751 	case BWN_OFDM_RATE_24MB:
9752 		return (BWN_OFDM_RATE_18MB);
9753 	case BWN_OFDM_RATE_36MB:
9754 		return (BWN_OFDM_RATE_24MB);
9755 	case BWN_OFDM_RATE_48MB:
9756 		return (BWN_OFDM_RATE_36MB);
9757 	case BWN_OFDM_RATE_54MB:
9758 		return (BWN_OFDM_RATE_48MB);
9759 	}
9760 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9761 	return (0);
9762 }
9763 
9764 static uint32_t
9765 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9766     uint32_t ctl, const void *_data, int len)
9767 {
9768 	struct bwn_softc *sc = mac->mac_sc;
9769 	uint32_t value = 0;
9770 	const uint8_t *data = _data;
9771 
9772 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9773 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9774 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9775 
9776 	siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9777 	    tq->tq_base + BWN_PIO8_TXDATA);
9778 	if (len & 3) {
9779 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9780 		    BWN_PIO8_TXCTL_24_31);
9781 		data = &(data[len - 1]);
9782 		switch (len & 3) {
9783 		case 3:
9784 			ctl |= BWN_PIO8_TXCTL_16_23;
9785 			value |= (uint32_t)(*data) << 16;
9786 			data--;
9787 		case 2:
9788 			ctl |= BWN_PIO8_TXCTL_8_15;
9789 			value |= (uint32_t)(*data) << 8;
9790 			data--;
9791 		case 1:
9792 			value |= (uint32_t)(*data);
9793 		}
9794 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9795 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9796 	}
9797 
9798 	return (ctl);
9799 }
9800 
9801 static void
9802 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9803     uint16_t offset, uint32_t value)
9804 {
9805 
9806 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
9807 }
9808 
9809 static uint16_t
9810 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9811     uint16_t ctl, const void *_data, int len)
9812 {
9813 	struct bwn_softc *sc = mac->mac_sc;
9814 	const uint8_t *data = _data;
9815 
9816 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9817 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9818 
9819 	siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9820 	    tq->tq_base + BWN_PIO_TXDATA);
9821 	if (len & 1) {
9822 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9823 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9824 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9825 	}
9826 
9827 	return (ctl);
9828 }
9829 
9830 static uint16_t
9831 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9832     uint16_t ctl, struct mbuf *m0)
9833 {
9834 	int i, j = 0;
9835 	uint16_t data = 0;
9836 	const uint8_t *buf;
9837 	struct mbuf *m = m0;
9838 
9839 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9840 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9841 
9842 	for (; m != NULL; m = m->m_next) {
9843 		buf = mtod(m, const uint8_t *);
9844 		for (i = 0; i < m->m_len; i++) {
9845 			if (!((j++) % 2))
9846 				data |= buf[i];
9847 			else {
9848 				data |= (buf[i] << 8);
9849 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9850 				data = 0;
9851 			}
9852 		}
9853 	}
9854 	if (m0->m_pkthdr.len % 2) {
9855 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9856 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9857 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9858 	}
9859 
9860 	return (ctl);
9861 }
9862 
9863 static void
9864 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9865 {
9866 
9867 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
9868 		return;
9869 	BWN_WRITE_2(mac, 0x684, 510 + time);
9870 
9871 	/*
9872 	 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a
9873 	 *              a severe performance penalty (especially when sending).
9874 	 */
9875 #if 0
9876 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9877 #endif
9878 }
9879 
9880 static struct bwn_dma_ring *
9881 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9882 {
9883 
9884 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9885 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9886 
9887 	switch (prio) {
9888 	case 3:
9889 		return (mac->mac_method.dma.wme[WME_AC_VO]);
9890 	case 2:
9891 		return (mac->mac_method.dma.wme[WME_AC_VI]);
9892 	case 0:
9893 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9894 	case 1:
9895 		return (mac->mac_method.dma.wme[WME_AC_BK]);
9896 	}
9897 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9898 	return (NULL);
9899 }
9900 
9901 static int
9902 bwn_dma_getslot(struct bwn_dma_ring *dr)
9903 {
9904 	int slot;
9905 
9906 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9907 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9908 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9909 
9910 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9911 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9912 	dr->dr_curslot = slot;
9913 	dr->dr_usedslot++;
9914 
9915 	return (slot);
9916 }
9917 
9918 static int
9919 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9920 {
9921 	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9922 	unsigned int a, b, c, d;
9923 	unsigned int avg;
9924 	uint32_t tmp;
9925 
9926 	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9927 	a = tmp & 0xff;
9928 	b = (tmp >> 8) & 0xff;
9929 	c = (tmp >> 16) & 0xff;
9930 	d = (tmp >> 24) & 0xff;
9931 	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9932 	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9933 		return (ENOENT);
9934 	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9935 	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9936 	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9937 
9938 	if (ofdm) {
9939 		a = (a + 32) & 0x3f;
9940 		b = (b + 32) & 0x3f;
9941 		c = (c + 32) & 0x3f;
9942 		d = (d + 32) & 0x3f;
9943 	}
9944 
9945 	avg = (a + b + c + d + 2) / 4;
9946 	if (ofdm) {
9947 		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9948 		    & BWN_HF_4DB_CCK_POWERBOOST)
9949 			avg = (avg >= 13) ? (avg - 13) : 0;
9950 	}
9951 	return (avg);
9952 }
9953 
9954 static void
9955 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9956 {
9957 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9958 	int rfatt = *rfattp;
9959 	int bbatt = *bbattp;
9960 
9961 	while (1) {
9962 		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9963 			break;
9964 		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9965 			break;
9966 		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9967 			break;
9968 		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9969 			break;
9970 		if (bbatt > lo->bbatt.max) {
9971 			bbatt -= 4;
9972 			rfatt += 1;
9973 			continue;
9974 		}
9975 		if (bbatt < lo->bbatt.min) {
9976 			bbatt += 4;
9977 			rfatt -= 1;
9978 			continue;
9979 		}
9980 		if (rfatt > lo->rfatt.max) {
9981 			rfatt -= 1;
9982 			bbatt += 4;
9983 			continue;
9984 		}
9985 		if (rfatt < lo->rfatt.min) {
9986 			rfatt += 1;
9987 			bbatt -= 4;
9988 			continue;
9989 		}
9990 		break;
9991 	}
9992 
9993 	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9994 	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9995 }
9996 
9997 static void
9998 bwn_phy_lock(struct bwn_mac *mac)
9999 {
10000 	struct bwn_softc *sc = mac->mac_sc;
10001 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10002 
10003 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10004 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10005 
10006 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10007 		bwn_psctl(mac, BWN_PS_AWAKE);
10008 }
10009 
10010 static void
10011 bwn_phy_unlock(struct bwn_mac *mac)
10012 {
10013 	struct bwn_softc *sc = mac->mac_sc;
10014 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10015 
10016 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10017 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10018 
10019 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10020 		bwn_psctl(mac, 0);
10021 }
10022 
10023 static void
10024 bwn_rf_lock(struct bwn_mac *mac)
10025 {
10026 
10027 	BWN_WRITE_4(mac, BWN_MACCTL,
10028 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10029 	BWN_READ_4(mac, BWN_MACCTL);
10030 	DELAY(10);
10031 }
10032 
10033 static void
10034 bwn_rf_unlock(struct bwn_mac *mac)
10035 {
10036 
10037 	BWN_READ_2(mac, BWN_PHYVER);
10038 	BWN_WRITE_4(mac, BWN_MACCTL,
10039 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10040 }
10041 
10042 static struct bwn_pio_txqueue *
10043 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10044     struct bwn_pio_txpkt **pack)
10045 {
10046 	struct bwn_pio *pio = &mac->mac_method.pio;
10047 	struct bwn_pio_txqueue *tq = NULL;
10048 	unsigned int index;
10049 
10050 	switch (cookie & 0xf000) {
10051 	case 0x1000:
10052 		tq = &pio->wme[WME_AC_BK];
10053 		break;
10054 	case 0x2000:
10055 		tq = &pio->wme[WME_AC_BE];
10056 		break;
10057 	case 0x3000:
10058 		tq = &pio->wme[WME_AC_VI];
10059 		break;
10060 	case 0x4000:
10061 		tq = &pio->wme[WME_AC_VO];
10062 		break;
10063 	case 0x5000:
10064 		tq = &pio->mcast;
10065 		break;
10066 	}
10067 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10068 	if (tq == NULL)
10069 		return (NULL);
10070 	index = (cookie & 0x0fff);
10071 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10072 	if (index >= N(tq->tq_pkts))
10073 		return (NULL);
10074 	*pack = &tq->tq_pkts[index];
10075 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10076 	return (tq);
10077 }
10078 
10079 static void
10080 bwn_txpwr(void *arg, int npending)
10081 {
10082 	struct bwn_mac *mac = arg;
10083 
10084 	wlan_serialize_enter();
10085 	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10086 	    mac->mac_phy.set_txpwr != NULL)
10087 		mac->mac_phy.set_txpwr(mac);
10088 	wlan_serialize_exit();
10089 }
10090 
10091 static void
10092 bwn_task_15s(struct bwn_mac *mac)
10093 {
10094 	uint16_t reg;
10095 
10096 	if (mac->mac_fw.opensource) {
10097 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10098 		if (reg) {
10099 			bwn_restart(mac, "fw watchdog");
10100 			return;
10101 		}
10102 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10103 	}
10104 	if (mac->mac_phy.task_15s)
10105 		mac->mac_phy.task_15s(mac);
10106 
10107 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10108 }
10109 
10110 static void
10111 bwn_task_30s(struct bwn_mac *mac)
10112 {
10113 
10114 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10115 		return;
10116 	mac->mac_noise.noi_running = 1;
10117 	mac->mac_noise.noi_nsamples = 0;
10118 
10119 	bwn_noise_gensample(mac);
10120 }
10121 
10122 static void
10123 bwn_task_60s(struct bwn_mac *mac)
10124 {
10125 
10126 	if (mac->mac_phy.task_60s)
10127 		mac->mac_phy.task_60s(mac);
10128 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10129 }
10130 
10131 static void
10132 bwn_tasks(void *arg)
10133 {
10134 	struct bwn_mac *mac = arg;
10135 	struct bwn_softc *sc = mac->mac_sc;
10136 
10137 	wlan_serialize_enter();
10138 
10139 	if (mac->mac_status != BWN_MAC_STATUS_STARTED) {
10140 		wlan_serialize_exit();
10141 		return;
10142 	}
10143 
10144 	if (mac->mac_task_state % 4 == 0)
10145 		bwn_task_60s(mac);
10146 	if (mac->mac_task_state % 2 == 0)
10147 		bwn_task_30s(mac);
10148 	bwn_task_15s(mac);
10149 
10150 	mac->mac_task_state++;
10151 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10152 	wlan_serialize_exit();
10153 }
10154 
10155 static int
10156 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10157 {
10158 	struct bwn_softc *sc = mac->mac_sc;
10159 
10160 	KASSERT(a == 0, ("not support APHY\n"));
10161 
10162 	switch (plcp->o.raw[0] & 0xf) {
10163 	case 0xb:
10164 		return (BWN_OFDM_RATE_6MB);
10165 	case 0xf:
10166 		return (BWN_OFDM_RATE_9MB);
10167 	case 0xa:
10168 		return (BWN_OFDM_RATE_12MB);
10169 	case 0xe:
10170 		return (BWN_OFDM_RATE_18MB);
10171 	case 0x9:
10172 		return (BWN_OFDM_RATE_24MB);
10173 	case 0xd:
10174 		return (BWN_OFDM_RATE_36MB);
10175 	case 0x8:
10176 		return (BWN_OFDM_RATE_48MB);
10177 	case 0xc:
10178 		return (BWN_OFDM_RATE_54MB);
10179 	}
10180 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10181 	    plcp->o.raw[0] & 0xf);
10182 	return (-1);
10183 }
10184 
10185 static int
10186 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10187 {
10188 	struct bwn_softc *sc = mac->mac_sc;
10189 
10190 	switch (plcp->o.raw[0]) {
10191 	case 0x0a:
10192 		return (BWN_CCK_RATE_1MB);
10193 	case 0x14:
10194 		return (BWN_CCK_RATE_2MB);
10195 	case 0x37:
10196 		return (BWN_CCK_RATE_5MB);
10197 	case 0x6e:
10198 		return (BWN_CCK_RATE_11MB);
10199 	}
10200 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10201 	return (-1);
10202 }
10203 
10204 static void
10205 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10206     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10207     int rssi, int noise)
10208 {
10209 	struct bwn_softc *sc = mac->mac_sc;
10210 	const struct ieee80211_frame_min *wh;
10211 	uint64_t tsf;
10212 	uint16_t low_mactime_now;
10213 
10214 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10215 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10216 
10217 	wh = mtod(m, const struct ieee80211_frame_min *);
10218 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10219 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10220 
10221 	bwn_tsf_read(mac, &tsf);
10222 	low_mactime_now = tsf;
10223 	tsf = tsf & ~0xffffULL;
10224 	tsf += le16toh(rxhdr->mac_time);
10225 	if (low_mactime_now < le16toh(rxhdr->mac_time))
10226 		tsf -= 0x10000;
10227 
10228 	sc->sc_rx_th.wr_tsf = tsf;
10229 	sc->sc_rx_th.wr_rate = rate;
10230 	sc->sc_rx_th.wr_antsignal = rssi;
10231 	sc->sc_rx_th.wr_antnoise = noise;
10232 }
10233 
10234 static void
10235 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10236 {
10237 	uint32_t low, high;
10238 
10239 	KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10240 	    ("%s:%d: fail", __func__, __LINE__));
10241 
10242 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10243 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10244 	*tsf = high;
10245 	*tsf <<= 32;
10246 	*tsf |= low;
10247 }
10248 
10249 static int
10250 bwn_dma_attach(struct bwn_mac *mac)
10251 {
10252 	struct bwn_dma *dma = &mac->mac_method.dma;
10253 	struct bwn_softc *sc = mac->mac_sc;
10254 	bus_addr_t lowaddr = 0;
10255 	int error;
10256 
10257 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10258 		return (0);
10259 
10260 	KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10261 
10262 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
10263 
10264 	dma->dmatype = bwn_dma_gettype(mac);
10265 	if (dma->dmatype == BWN_DMA_30BIT)
10266 		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10267 	else if (dma->dmatype == BWN_DMA_32BIT)
10268 		lowaddr = BUS_SPACE_MAXADDR_32BIT;
10269 	else
10270 		lowaddr = BUS_SPACE_MAXADDR;
10271 
10272 	/*
10273 	 * Create top level DMA tag
10274 	 */
10275 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
10276 			       BWN_ALIGN, 0,		/* alignment, bounds */
10277 			       lowaddr,			/* lowaddr */
10278 			       BUS_SPACE_MAXADDR,	/* highaddr */
10279 			       NULL, NULL,		/* filter, filterarg */
10280 			       MAXBSIZE,		/* maxsize */
10281 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
10282 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
10283 			       0,			/* flags */
10284 			       &dma->parent_dtag);
10285 	if (error) {
10286 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10287 		return (error);
10288 	}
10289 
10290 	/*
10291 	 * Create TX/RX mbuf DMA tag
10292 	 */
10293 	error = bus_dma_tag_create(dma->parent_dtag,
10294 				4,
10295 				0,
10296 				BUS_SPACE_MAXADDR,
10297 				BUS_SPACE_MAXADDR,
10298 				NULL, NULL,
10299 				MCLBYTES,
10300 				1,
10301 				BUS_SPACE_MAXSIZE_32BIT,
10302 				0,
10303 				&dma->rxbuf_dtag);
10304 	if (error) {
10305 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10306 		goto fail0;
10307 	}
10308 	error = bus_dma_tag_create(dma->parent_dtag,
10309 				4,
10310 				0,
10311 				BUS_SPACE_MAXADDR,
10312 				BUS_SPACE_MAXADDR,
10313 				NULL, NULL,
10314 				MCLBYTES,
10315 				1,
10316 				BUS_SPACE_MAXSIZE_32BIT,
10317 				0,
10318 				&dma->txbuf_dtag);
10319 	if (error) {
10320 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10321 		goto fail1;
10322 	}
10323 
10324 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10325 	if (dma->wme[WME_AC_BK] == NULL)
10326 		goto fail2;
10327 
10328 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10329 	if (dma->wme[WME_AC_BE] == NULL)
10330 		goto fail3;
10331 
10332 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10333 	if (dma->wme[WME_AC_VI] == NULL)
10334 		goto fail4;
10335 
10336 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10337 	if (dma->wme[WME_AC_VO] == NULL)
10338 		goto fail5;
10339 
10340 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10341 	if (dma->mcast == NULL)
10342 		goto fail6;
10343 	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10344 	if (dma->rx == NULL)
10345 		goto fail7;
10346 
10347 	return (error);
10348 
10349 fail7:	bwn_dma_ringfree(&dma->mcast);
10350 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10351 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10352 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10353 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10354 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
10355 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
10356 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
10357 	return (error);
10358 }
10359 
10360 static struct bwn_dma_ring *
10361 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10362     uint16_t cookie, int *slot)
10363 {
10364 	struct bwn_dma *dma = &mac->mac_method.dma;
10365 	struct bwn_dma_ring *dr;
10366 	struct bwn_softc *sc = mac->mac_sc;
10367 
10368 	switch (cookie & 0xf000) {
10369 	case 0x1000:
10370 		dr = dma->wme[WME_AC_BK];
10371 		break;
10372 	case 0x2000:
10373 		dr = dma->wme[WME_AC_BE];
10374 		break;
10375 	case 0x3000:
10376 		dr = dma->wme[WME_AC_VI];
10377 		break;
10378 	case 0x4000:
10379 		dr = dma->wme[WME_AC_VO];
10380 		break;
10381 	case 0x5000:
10382 		dr = dma->mcast;
10383 		break;
10384 	default:
10385 		dr = NULL;
10386 		KASSERT(0 == 1,
10387 		    ("invalid cookie value %d", cookie & 0xf000));
10388 	}
10389 	*slot = (cookie & 0x0fff);
10390 	if (*slot < 0 || *slot >= dr->dr_numslots) {
10391 		/*
10392 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10393 		 * that it occurs events which have same H/W sequence numbers.
10394 		 * When it's occurred just prints a WARNING msgs and ignores.
10395 		 */
10396 		KASSERT(status->seq == dma->lastseq,
10397 		    ("%s:%d: fail", __func__, __LINE__));
10398 		device_printf(sc->sc_dev,
10399 		    "out of slot ranges (0 < %d < %d)\n", *slot,
10400 		    dr->dr_numslots);
10401 		return (NULL);
10402 	}
10403 	dma->lastseq = status->seq;
10404 	return (dr);
10405 }
10406 
10407 static void
10408 bwn_dma_stop(struct bwn_mac *mac)
10409 {
10410 	struct bwn_dma *dma;
10411 
10412 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10413 		return;
10414 	dma = &mac->mac_method.dma;
10415 
10416 	bwn_dma_ringstop(&dma->rx);
10417 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10418 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10419 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10420 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10421 	bwn_dma_ringstop(&dma->mcast);
10422 }
10423 
10424 static void
10425 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10426 {
10427 
10428 	if (dr == NULL)
10429 		return;
10430 
10431 	bwn_dma_cleanup(*dr);
10432 }
10433 
10434 static void
10435 bwn_pio_stop(struct bwn_mac *mac)
10436 {
10437 	struct bwn_pio *pio;
10438 
10439 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10440 		return;
10441 	pio = &mac->mac_method.pio;
10442 
10443 	bwn_destroy_queue_tx(&pio->mcast);
10444 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10445 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10446 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10447 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10448 }
10449 
10450 static void
10451 bwn_led_attach(struct bwn_mac *mac)
10452 {
10453 	struct bwn_softc *sc = mac->mac_sc;
10454 	const uint8_t *led_act = NULL;
10455 	uint16_t val[BWN_LED_MAX];
10456 	int i;
10457 
10458 	sc->sc_led_idle = (2350 * hz) / 1000;
10459 	sc->sc_led_blink = 1;
10460 
10461 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10462 		if (siba_get_pci_subvendor(sc->sc_dev) ==
10463 		    bwn_vendor_led_act[i].vid) {
10464 			led_act = bwn_vendor_led_act[i].led_act;
10465 			break;
10466 		}
10467 	}
10468 	if (led_act == NULL)
10469 		led_act = bwn_default_led_act;
10470 
10471 	val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10472 	val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10473 	val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10474 	val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10475 
10476 	for (i = 0; i < BWN_LED_MAX; ++i) {
10477 		struct bwn_led *led = &sc->sc_leds[i];
10478 
10479 		if (val[i] == 0xff) {
10480 			led->led_act = led_act[i];
10481 		} else {
10482 			if (val[i] & BWN_LED_ACT_LOW)
10483 				led->led_flags |= BWN_LED_F_ACTLOW;
10484 			led->led_act = val[i] & BWN_LED_ACT_MASK;
10485 		}
10486 		led->led_mask = (1 << i);
10487 
10488 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10489 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
10490 		    led->led_act == BWN_LED_ACT_BLINK) {
10491 			led->led_flags |= BWN_LED_F_BLINK;
10492 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10493 				led->led_flags |= BWN_LED_F_POLLABLE;
10494 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10495 				led->led_flags |= BWN_LED_F_SLOW;
10496 
10497 			if (sc->sc_blink_led == NULL) {
10498 				sc->sc_blink_led = led;
10499 				if (led->led_flags & BWN_LED_F_SLOW)
10500 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
10501 			}
10502 		}
10503 
10504 		DPRINTF(sc, BWN_DEBUG_LED,
10505 		    "%dth led, act %d, lowact %d\n", i,
10506 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10507 	}
10508 	callout_init(&sc->sc_led_blink_ch);
10509 }
10510 
10511 static __inline uint16_t
10512 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10513 {
10514 
10515 	if (led->led_flags & BWN_LED_F_ACTLOW)
10516 		on = !on;
10517 	if (on)
10518 		val |= led->led_mask;
10519 	else
10520 		val &= ~led->led_mask;
10521 	return val;
10522 }
10523 
10524 static void
10525 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10526 {
10527 	struct bwn_softc *sc = mac->mac_sc;
10528 	struct ifnet *ifp = sc->sc_ifp;
10529 	struct ieee80211com *ic = ifp->if_l2com;
10530 	uint16_t val;
10531 	int i;
10532 
10533 	if (nstate == IEEE80211_S_INIT) {
10534 		callout_stop(&sc->sc_led_blink_ch);
10535 		sc->sc_led_blinking = 0;
10536 	}
10537 
10538 	if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0)
10539 		return;
10540 
10541 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10542 	for (i = 0; i < BWN_LED_MAX; ++i) {
10543 		struct bwn_led *led = &sc->sc_leds[i];
10544 		int on;
10545 
10546 		if (led->led_act == BWN_LED_ACT_UNKN ||
10547 		    led->led_act == BWN_LED_ACT_NULL)
10548 			continue;
10549 
10550 		if ((led->led_flags & BWN_LED_F_BLINK) &&
10551 		    nstate != IEEE80211_S_INIT)
10552 			continue;
10553 
10554 		switch (led->led_act) {
10555 		case BWN_LED_ACT_ON:    /* Always on */
10556 			on = 1;
10557 			break;
10558 		case BWN_LED_ACT_OFF:   /* Always off */
10559 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10560 			on = 0;
10561 			break;
10562 		default:
10563 			on = 1;
10564 			switch (nstate) {
10565 			case IEEE80211_S_INIT:
10566 				on = 0;
10567 				break;
10568 			case IEEE80211_S_RUN:
10569 				if (led->led_act == BWN_LED_ACT_11G &&
10570 				    ic->ic_curmode != IEEE80211_MODE_11G)
10571 					on = 0;
10572 				break;
10573 			default:
10574 				if (led->led_act == BWN_LED_ACT_ASSOC)
10575 					on = 0;
10576 				break;
10577 			}
10578 			break;
10579 		}
10580 
10581 		val = bwn_led_onoff(led, val, on);
10582 	}
10583 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10584 }
10585 
10586 static void
10587 bwn_led_event(struct bwn_mac *mac, int event)
10588 {
10589 	struct bwn_softc *sc = mac->mac_sc;
10590 	struct bwn_led *led = sc->sc_blink_led;
10591 	int rate;
10592 
10593 	if (event == BWN_LED_EVENT_POLL) {
10594 		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10595 			return;
10596 		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10597 			return;
10598 	}
10599 
10600 	sc->sc_led_ticks = ticks;
10601 	if (sc->sc_led_blinking)
10602 		return;
10603 
10604 	switch (event) {
10605 	case BWN_LED_EVENT_RX:
10606 		rate = sc->sc_rx_rate;
10607 		break;
10608 	case BWN_LED_EVENT_TX:
10609 		rate = sc->sc_tx_rate;
10610 		break;
10611 	case BWN_LED_EVENT_POLL:
10612 		rate = 0;
10613 		break;
10614 	default:
10615 		panic("unknown LED event %d\n", event);
10616 		break;
10617 	}
10618 	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10619 	    bwn_led_duration[rate].off_dur);
10620 }
10621 
10622 static void
10623 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10624 {
10625 	struct bwn_softc *sc = mac->mac_sc;
10626 	struct bwn_led *led = sc->sc_blink_led;
10627 	uint16_t val;
10628 
10629 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10630 	val = bwn_led_onoff(led, val, 1);
10631 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10632 
10633 	if (led->led_flags & BWN_LED_F_SLOW) {
10634 		BWN_LED_SLOWDOWN(on_dur);
10635 		BWN_LED_SLOWDOWN(off_dur);
10636 	}
10637 
10638 	sc->sc_led_blinking = 1;
10639 	sc->sc_led_blink_offdur = off_dur;
10640 
10641 	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10642 }
10643 
10644 static void
10645 bwn_led_blink_next(void *arg)
10646 {
10647 	struct bwn_mac *mac = arg;
10648 	struct bwn_softc *sc = mac->mac_sc;
10649 	uint16_t val;
10650 
10651 	wlan_serialize_enter();
10652 
10653 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10654 	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10655 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10656 
10657 	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10658 	    bwn_led_blink_end, mac);
10659 	wlan_serialize_exit();
10660 }
10661 
10662 static void
10663 bwn_led_blink_end(void *arg)
10664 {
10665 	struct bwn_mac *mac = arg;
10666 	struct bwn_softc *sc = mac->mac_sc;
10667 
10668 	sc->sc_led_blinking = 0;
10669 }
10670 
10671 static int
10672 bwn_suspend(device_t dev)
10673 {
10674 	struct bwn_softc *sc = device_get_softc(dev);
10675 
10676 	wlan_serialize_enter();
10677 	bwn_stop(sc, 1);
10678 	wlan_serialize_exit();
10679 
10680 	return (0);
10681 }
10682 
10683 static int
10684 bwn_resume(device_t dev)
10685 {
10686 	struct bwn_softc *sc = device_get_softc(dev);
10687 	struct ifnet *ifp = sc->sc_ifp;
10688 
10689 	wlan_serialize_enter();
10690 	if (ifp->if_flags & IFF_UP)
10691 		bwn_init(sc);
10692 	wlan_serialize_exit();
10693 	return (0);
10694 }
10695 
10696 static void
10697 bwn_rfswitch(void *arg)
10698 {
10699 	struct bwn_softc *sc = arg;
10700 	struct bwn_mac *mac = sc->sc_curmac;
10701 	int cur = 0, prev = 0;
10702 
10703 	wlan_serialize_enter();
10704 
10705 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10706 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
10707 
10708 	if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10709 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10710 			& BWN_RF_HWENABLED_HI_MASK))
10711 			cur = 1;
10712 	} else {
10713 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10714 		    & BWN_RF_HWENABLED_LO_MASK)
10715 			cur = 1;
10716 	}
10717 
10718 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10719 		prev = 1;
10720 
10721 	if (cur != prev) {
10722 		if (cur)
10723 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10724 		else
10725 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10726 
10727 		device_printf(sc->sc_dev,
10728 		    "status of RF switch is changed to %s\n",
10729 		    cur ? "ON" : "OFF");
10730 		if (cur != mac->mac_phy.rf_on) {
10731 			if (cur)
10732 				bwn_rf_turnon(mac);
10733 			else
10734 				bwn_rf_turnoff(mac);
10735 		}
10736 	}
10737 
10738 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
10739 	wlan_serialize_exit();
10740 }
10741 
10742 static void
10743 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10744 {
10745 	struct bwn_phy *phy = &mac->mac_phy;
10746 	struct bwn_phy_lp *plp = &phy->phy_lp;
10747 
10748 	plp->plp_antenna = BWN_ANT_DEFAULT;
10749 }
10750 
10751 static int
10752 bwn_phy_lp_init(struct bwn_mac *mac)
10753 {
10754 	static const struct bwn_stxtable tables[] = {
10755 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10756 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10757 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10758 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10759 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10760 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10761 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10762 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10763 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10764 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10765 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10766 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10767 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10768 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10769 		{ 2, 11, 0x40, 0, 0x0f }
10770 	};
10771 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10772 	struct bwn_softc *sc = mac->mac_sc;
10773 	const struct bwn_stxtable *st;
10774 	struct ifnet *ifp = sc->sc_ifp;
10775 	struct ieee80211com *ic = ifp->if_l2com;
10776 	int i, error;
10777 	uint16_t tmp;
10778 
10779 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
10780 	bwn_phy_lp_bbinit(mac);
10781 
10782 	/* initialize RF */
10783 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10784 	DELAY(1);
10785 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10786 	DELAY(1);
10787 
10788 	if (mac->mac_phy.rf_ver == 0x2062)
10789 		bwn_phy_lp_b2062_init(mac);
10790 	else {
10791 		bwn_phy_lp_b2063_init(mac);
10792 
10793 		/* synchronize stx table. */
10794 		for (i = 0; i < N(tables); i++) {
10795 			st = &tables[i];
10796 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
10797 			tmp >>= st->st_rfshift;
10798 			tmp <<= st->st_physhift;
10799 			BWN_PHY_SETMASK(mac,
10800 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10801 			    ~(st->st_mask << st->st_physhift), tmp);
10802 		}
10803 
10804 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10805 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10806 	}
10807 
10808 	/* calibrate RC */
10809 	if (mac->mac_phy.rev >= 2)
10810 		bwn_phy_lp_rxcal_r2(mac);
10811 	else if (!plp->plp_rccap) {
10812 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10813 			bwn_phy_lp_rccal_r12(mac);
10814 	} else
10815 		bwn_phy_lp_set_rccap(mac);
10816 
10817 	error = bwn_phy_lp_switch_channel(mac, 7);
10818 	if (error)
10819 		device_printf(sc->sc_dev,
10820 		    "failed to change channel 7 (%d)\n", error);
10821 	bwn_phy_lp_txpctl_init(mac);
10822 	bwn_phy_lp_calib(mac);
10823 	return (0);
10824 }
10825 
10826 static uint16_t
10827 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10828 {
10829 
10830 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10831 	return (BWN_READ_2(mac, BWN_PHYDATA));
10832 }
10833 
10834 static void
10835 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10836 {
10837 
10838 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10839 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
10840 }
10841 
10842 static void
10843 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10844     uint16_t set)
10845 {
10846 
10847 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10848 	BWN_WRITE_2(mac, BWN_PHYDATA,
10849 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10850 }
10851 
10852 static uint16_t
10853 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10854 {
10855 
10856 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10857 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
10858 		reg |= 0x100;
10859 	if (mac->mac_phy.rev >= 2)
10860 		reg |= 0x200;
10861 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10862 	return BWN_READ_2(mac, BWN_RFDATALO);
10863 }
10864 
10865 static void
10866 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10867 {
10868 
10869 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10870 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10871 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
10872 }
10873 
10874 static void
10875 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10876 {
10877 
10878 	if (on) {
10879 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10880 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10881 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10882 		return;
10883 	}
10884 
10885 	if (mac->mac_phy.rev >= 2) {
10886 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10887 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10888 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10889 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10890 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10891 		return;
10892 	}
10893 
10894 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10895 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10896 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10897 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10898 }
10899 
10900 static int
10901 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10902 {
10903 	struct bwn_phy *phy = &mac->mac_phy;
10904 	struct bwn_phy_lp *plp = &phy->phy_lp;
10905 	int error;
10906 
10907 	if (phy->rf_ver == 0x2063) {
10908 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10909 		if (error)
10910 			return (error);
10911 	} else {
10912 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10913 		if (error)
10914 			return (error);
10915 		bwn_phy_lp_set_anafilter(mac, chan);
10916 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10917 	}
10918 
10919 	plp->plp_chan = chan;
10920 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10921 	return (0);
10922 }
10923 
10924 static uint32_t
10925 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10926 {
10927 	struct bwn_softc *sc = mac->mac_sc;
10928 	struct ifnet *ifp = sc->sc_ifp;
10929 	struct ieee80211com *ic = ifp->if_l2com;
10930 
10931 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10932 }
10933 
10934 static void
10935 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10936 {
10937 	struct bwn_phy *phy = &mac->mac_phy;
10938 	struct bwn_phy_lp *plp = &phy->phy_lp;
10939 
10940 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10941 		return;
10942 
10943 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10944 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10945 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10946 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10947 	plp->plp_antenna = antenna;
10948 }
10949 
10950 static void
10951 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10952 {
10953 
10954 	bwn_phy_lp_calib(mac);
10955 }
10956 
10957 static void
10958 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10959 {
10960 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10961 	struct bwn_softc *sc = mac->mac_sc;
10962 	struct ifnet *ifp = sc->sc_ifp;
10963 	struct ieee80211com *ic = ifp->if_l2com;
10964 
10965 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10966 		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10967 		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10968 		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10969 		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10970 		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10971 		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10972 		return;
10973 	}
10974 
10975 	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10976 	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10977 	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10978 	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10979 	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10980 	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10981 	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10982 	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10983 }
10984 
10985 static void
10986 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10987 {
10988 
10989 	bwn_phy_lp_tblinit(mac);
10990 	if (mac->mac_phy.rev >= 2)
10991 		bwn_phy_lp_bbinit_r2(mac);
10992 	else
10993 		bwn_phy_lp_bbinit_r01(mac);
10994 }
10995 
10996 static void
10997 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10998 {
10999 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11000 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11001 	struct bwn_softc *sc = mac->mac_sc;
11002 	struct ifnet *ifp = sc->sc_ifp;
11003 	struct ieee80211com *ic = ifp->if_l2com;
11004 
11005 	bwn_phy_lp_set_txgain(mac,
11006 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11007 	bwn_phy_lp_set_bbmult(mac, 150);
11008 }
11009 
11010 static void
11011 bwn_phy_lp_calib(struct bwn_mac *mac)
11012 {
11013 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11014 	struct bwn_softc *sc = mac->mac_sc;
11015 	struct ifnet *ifp = sc->sc_ifp;
11016 	struct ieee80211com *ic = ifp->if_l2com;
11017 	const struct bwn_rxcompco *rc = NULL;
11018 	struct bwn_txgain ogain;
11019 	int i, omode, oafeovr, orf, obbmult;
11020 	uint8_t mode, fc = 0;
11021 
11022 	if (plp->plp_chanfullcal != plp->plp_chan) {
11023 		plp->plp_chanfullcal = plp->plp_chan;
11024 		fc = 1;
11025 	}
11026 
11027 	bwn_mac_suspend(mac);
11028 
11029 	/* BlueTooth Coexistance Override */
11030 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11031 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11032 
11033 	if (mac->mac_phy.rev >= 2)
11034 		bwn_phy_lp_digflt_save(mac);
11035 	bwn_phy_lp_get_txpctlmode(mac);
11036 	mode = plp->plp_txpctlmode;
11037 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11038 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11039 		bwn_phy_lp_bugfix(mac);
11040 	if (mac->mac_phy.rev >= 2 && fc == 1) {
11041 		bwn_phy_lp_get_txpctlmode(mac);
11042 		omode = plp->plp_txpctlmode;
11043 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11044 		if (oafeovr)
11045 			ogain = bwn_phy_lp_get_txgain(mac);
11046 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11047 		obbmult = bwn_phy_lp_get_bbmult(mac);
11048 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11049 		if (oafeovr)
11050 			bwn_phy_lp_set_txgain(mac, &ogain);
11051 		bwn_phy_lp_set_bbmult(mac, obbmult);
11052 		bwn_phy_lp_set_txpctlmode(mac, omode);
11053 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11054 	}
11055 	bwn_phy_lp_set_txpctlmode(mac, mode);
11056 	if (mac->mac_phy.rev >= 2)
11057 		bwn_phy_lp_digflt_restore(mac);
11058 
11059 	/* do RX IQ Calculation; assumes that noise is true. */
11060 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11061 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11062 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11063 				rc = &bwn_rxcompco_5354[i];
11064 		}
11065 	} else if (mac->mac_phy.rev >= 2)
11066 		rc = &bwn_rxcompco_r2;
11067 	else {
11068 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11069 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11070 				rc = &bwn_rxcompco_r12[i];
11071 		}
11072 	}
11073 	if (rc == NULL)
11074 		goto fail;
11075 
11076 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11077 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11078 
11079 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11080 
11081 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11082 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11083 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11084 	} else {
11085 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11086 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11087 	}
11088 
11089 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11090 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11091 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11092 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11093 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11094 	bwn_phy_lp_set_deaf(mac, 0);
11095 	/* XXX no checking return value? */
11096 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11097 	bwn_phy_lp_clear_deaf(mac, 0);
11098 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11099 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11100 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11101 
11102 	/* disable RX GAIN override. */
11103 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11104 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11105 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11106 	if (mac->mac_phy.rev >= 2) {
11107 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11108 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11109 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11110 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11111 		}
11112 	} else {
11113 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11114 	}
11115 
11116 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11117 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11118 fail:
11119 	bwn_mac_enable(mac);
11120 }
11121 
11122 static void
11123 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11124 {
11125 
11126 	if (on) {
11127 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11128 		return;
11129 	}
11130 
11131 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11132 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11133 }
11134 
11135 static int
11136 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11137 {
11138 	static const struct bwn_b206x_chan *bc = NULL;
11139 	struct bwn_softc *sc = mac->mac_sc;
11140 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11141 	    tmp[6];
11142 	uint16_t old, scale, tmp16;
11143 	int i, div;
11144 
11145 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
11146 		if (bwn_b2063_chantable[i].bc_chan == chan) {
11147 			bc = &bwn_b2063_chantable[i];
11148 			break;
11149 		}
11150 	}
11151 	if (bc == NULL)
11152 		return (EINVAL);
11153 
11154 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11155 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11156 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11157 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11158 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11159 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11160 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11161 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11162 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11163 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11164 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11165 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11166 
11167 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
11168 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11169 
11170 	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11171 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11172 	freqref = freqxtal * 3;
11173 	div = (freqxtal <= 26000000 ? 1 : 2);
11174 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11175 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11176 		999999) / 1000000) + 1;
11177 
11178 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11179 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11180 	    0xfff8, timeout >> 2);
11181 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11182 	    0xff9f,timeout << 5);
11183 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11184 
11185 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11186 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11187 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11188 
11189 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11190 	    (timeoutref + 1)) - 1;
11191 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11192 	    0xf0, count >> 8);
11193 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11194 
11195 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
11196 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
11197 	while (tmp[1] >= freqref) {
11198 		tmp[0]++;
11199 		tmp[1] -= freqref;
11200 	}
11201 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11202 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11203 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11204 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11205 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11206 
11207 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11208 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11209 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11210 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11211 
11212 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11213 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11214 
11215 	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11216 		scale = 1;
11217 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11218 	} else {
11219 		scale = 0;
11220 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11221 	}
11222 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11223 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11224 
11225 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11226 	    (scale + 1);
11227 	if (tmp[5] > 150)
11228 		tmp[5] = 0;
11229 
11230 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11231 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11232 
11233 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11234 	if (freqxtal > 26000000)
11235 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11236 	else
11237 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11238 
11239 	if (val[0] == 45)
11240 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11241 	else
11242 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11243 
11244 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11245 	DELAY(1);
11246 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11247 
11248 	/* VCO Calibration */
11249 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11250 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11251 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11252 	DELAY(1);
11253 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11254 	DELAY(1);
11255 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11256 	DELAY(1);
11257 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11258 	DELAY(300);
11259 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11260 
11261 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11262 	return (0);
11263 }
11264 
11265 static int
11266 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11267 {
11268 	struct bwn_softc *sc = mac->mac_sc;
11269 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11270 	const struct bwn_b206x_chan *bc = NULL;
11271 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11272 	uint32_t tmp[9];
11273 	int i;
11274 
11275 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
11276 		if (bwn_b2062_chantable[i].bc_chan == chan) {
11277 			bc = &bwn_b2062_chantable[i];
11278 			break;
11279 		}
11280 	}
11281 
11282 	if (bc == NULL)
11283 		return (EINVAL);
11284 
11285 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11286 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11287 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11288 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11289 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11290 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11291 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11292 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11293 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11294 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11295 
11296 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11297 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11298 	bwn_phy_lp_b2062_reset_pllbias(mac);
11299 	tmp[0] = freqxtal / 1000;
11300 	tmp[1] = plp->plp_div * 1000;
11301 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11302 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
11303 		tmp[2] *= 2;
11304 	tmp[3] = 48 * tmp[0];
11305 	tmp[5] = tmp[2] / tmp[3];
11306 	tmp[6] = tmp[2] % tmp[3];
11307 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11308 	tmp[4] = tmp[6] * 0x100;
11309 	tmp[5] = tmp[4] / tmp[3];
11310 	tmp[6] = tmp[4] % tmp[3];
11311 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11312 	tmp[4] = tmp[6] * 0x100;
11313 	tmp[5] = tmp[4] / tmp[3];
11314 	tmp[6] = tmp[4] % tmp[3];
11315 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11316 	tmp[4] = tmp[6] * 0x100;
11317 	tmp[5] = tmp[4] / tmp[3];
11318 	tmp[6] = tmp[4] % tmp[3];
11319 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11320 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
11321 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11322 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11323 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11324 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11325 
11326 	bwn_phy_lp_b2062_vco_calib(mac);
11327 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11328 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11329 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11330 		bwn_phy_lp_b2062_reset_pllbias(mac);
11331 		bwn_phy_lp_b2062_vco_calib(mac);
11332 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11333 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11334 			return (EIO);
11335 		}
11336 	}
11337 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11338 	return (0);
11339 }
11340 
11341 static void
11342 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11343 {
11344 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11345 	uint16_t tmp = (channel == 14);
11346 
11347 	if (mac->mac_phy.rev < 2) {
11348 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11349 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11350 			bwn_phy_lp_set_rccap(mac);
11351 		return;
11352 	}
11353 
11354 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11355 }
11356 
11357 static void
11358 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11359 {
11360 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11361 	struct bwn_softc *sc = mac->mac_sc;
11362 	struct ifnet *ifp = sc->sc_ifp;
11363 	struct ieee80211com *ic = ifp->if_l2com;
11364 	uint16_t iso, tmp[3];
11365 
11366 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11367 
11368 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11369 		iso = plp->plp_txisoband_m;
11370 	else if (freq <= 5320)
11371 		iso = plp->plp_txisoband_l;
11372 	else if (freq <= 5700)
11373 		iso = plp->plp_txisoband_m;
11374 	else
11375 		iso = plp->plp_txisoband_h;
11376 
11377 	tmp[0] = ((iso - 26) / 12) << 12;
11378 	tmp[1] = tmp[0] + 0x1000;
11379 	tmp[2] = tmp[0] + 0x2000;
11380 
11381 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11382 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11383 }
11384 
11385 static void
11386 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11387 {
11388 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11389 	int i;
11390 	static const uint16_t addr[] = {
11391 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11392 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11393 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11394 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11395 		BWN_PHY_OFDM(0xcf),
11396 	};
11397 	static const uint16_t val[] = {
11398 		0xde5e, 0xe832, 0xe331, 0x4d26,
11399 		0x0026, 0x1420, 0x0020, 0xfe08,
11400 		0x0008,
11401 	};
11402 
11403 	for (i = 0; i < N(addr); i++) {
11404 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11405 		BWN_PHY_WRITE(mac, addr[i], val[i]);
11406 	}
11407 }
11408 
11409 static void
11410 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11411 {
11412 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11413 	struct bwn_softc *sc = mac->mac_sc;
11414 	uint16_t ctl;
11415 
11416 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11417 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11418 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11419 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11420 		break;
11421 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11422 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11423 		break;
11424 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11425 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11426 		break;
11427 	default:
11428 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11429 		device_printf(sc->sc_dev, "unknown command mode\n");
11430 		break;
11431 	}
11432 }
11433 
11434 static void
11435 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11436 {
11437 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11438 	uint16_t ctl;
11439 	uint8_t old;
11440 
11441 	bwn_phy_lp_get_txpctlmode(mac);
11442 	old = plp->plp_txpctlmode;
11443 	if (old == mode)
11444 		return;
11445 	plp->plp_txpctlmode = mode;
11446 
11447 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11448 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11449 		    plp->plp_tssiidx);
11450 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11451 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11452 
11453 		/* disable TX GAIN override */
11454 		if (mac->mac_phy.rev < 2)
11455 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11456 		else {
11457 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11458 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11459 		}
11460 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11461 
11462 		plp->plp_txpwridx = -1;
11463 	}
11464 	if (mac->mac_phy.rev >= 2) {
11465 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11466 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11467 		else
11468 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11469 	}
11470 
11471 	/* writes TX Power Control mode */
11472 	switch (plp->plp_txpctlmode) {
11473 	case BWN_PHYLP_TXPCTL_OFF:
11474 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11475 		break;
11476 	case BWN_PHYLP_TXPCTL_ON_HW:
11477 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11478 		break;
11479 	case BWN_PHYLP_TXPCTL_ON_SW:
11480 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11481 		break;
11482 	default:
11483 		ctl = 0;
11484 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11485 	}
11486 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11487 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11488 }
11489 
11490 static void
11491 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11492 {
11493 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11494 	const unsigned int size = 256;
11495 	struct bwn_txgain tg;
11496 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11497 	uint16_t tssinpt, tssiidx, value[2];
11498 	uint8_t mode;
11499 	int8_t txpwridx;
11500 
11501 	tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF,
11502 	    M_INTWAIT | M_ZERO);
11503 
11504 	bwn_phy_lp_get_txpctlmode(mac);
11505 	mode = plp->plp_txpctlmode;
11506 	txpwridx = plp->plp_txpwridx;
11507 	tssinpt = plp->plp_tssinpt;
11508 	tssiidx = plp->plp_tssiidx;
11509 
11510 	bwn_tab_read_multi(mac,
11511 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11512 	    BWN_TAB_4(7, 0x140), size, tabs);
11513 
11514 	bwn_phy_lp_tblinit(mac);
11515 	bwn_phy_lp_bbinit(mac);
11516 	bwn_phy_lp_txpctl_init(mac);
11517 	bwn_phy_lp_rf_onoff(mac, 1);
11518 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11519 
11520 	bwn_tab_write_multi(mac,
11521 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11522 	    BWN_TAB_4(7, 0x140), size, tabs);
11523 
11524 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11525 	plp->plp_tssinpt = tssinpt;
11526 	plp->plp_tssiidx = tssiidx;
11527 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11528 	if (txpwridx != -1) {
11529 		/* set TX power by index */
11530 		plp->plp_txpwridx = txpwridx;
11531 		bwn_phy_lp_get_txpctlmode(mac);
11532 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11533 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11534 		if (mac->mac_phy.rev >= 2) {
11535 			rxcomp = bwn_tab_read(mac,
11536 			    BWN_TAB_4(7, txpwridx + 320));
11537 			txgain = bwn_tab_read(mac,
11538 			    BWN_TAB_4(7, txpwridx + 192));
11539 			tg.tg_pad = (txgain >> 16) & 0xff;
11540 			tg.tg_gm = txgain & 0xff;
11541 			tg.tg_pga = (txgain >> 8) & 0xff;
11542 			tg.tg_dac = (rxcomp >> 28) & 0xff;
11543 			bwn_phy_lp_set_txgain(mac, &tg);
11544 		} else {
11545 			rxcomp = bwn_tab_read(mac,
11546 			    BWN_TAB_4(10, txpwridx + 320));
11547 			txgain = bwn_tab_read(mac,
11548 			    BWN_TAB_4(10, txpwridx + 192));
11549 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11550 			    0xf800, (txgain >> 4) & 0x7fff);
11551 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11552 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11553 		}
11554 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11555 
11556 		/* set TX IQCC */
11557 		value[0] = (rxcomp >> 10) & 0x3ff;
11558 		value[1] = rxcomp & 0x3ff;
11559 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11560 
11561 		coeff = bwn_tab_read(mac,
11562 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11563 		    BWN_TAB_4(10, txpwridx + 448));
11564 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11565 		if (mac->mac_phy.rev >= 2) {
11566 			rfpwr = bwn_tab_read(mac,
11567 			    BWN_TAB_4(7, txpwridx + 576));
11568 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11569 			    rfpwr & 0xffff);
11570 		}
11571 		bwn_phy_lp_set_txgain_override(mac);
11572 	}
11573 	if (plp->plp_rccap)
11574 		bwn_phy_lp_set_rccap(mac);
11575 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11576 	bwn_phy_lp_set_txpctlmode(mac, mode);
11577 	kfree(tabs, M_DEVBUF);
11578 }
11579 
11580 static void
11581 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11582 {
11583 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11584 	int i;
11585 	static const uint16_t addr[] = {
11586 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11587 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11588 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11589 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11590 		BWN_PHY_OFDM(0xcf),
11591 	};
11592 
11593 	for (i = 0; i < N(addr); i++)
11594 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11595 }
11596 
11597 static void
11598 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11599 {
11600 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11601 
11602 	if (mac->mac_phy.rev < 2) {
11603 		bwn_phy_lp_tblinit_r01(mac);
11604 		bwn_phy_lp_tblinit_txgain(mac);
11605 		bwn_phy_lp_set_gaintbl(mac, freq);
11606 		return;
11607 	}
11608 
11609 	bwn_phy_lp_tblinit_r2(mac);
11610 	bwn_phy_lp_tblinit_txgain(mac);
11611 }
11612 
11613 struct bwn_wpair {
11614 	uint16_t		reg;
11615 	uint16_t		value;
11616 };
11617 
11618 struct bwn_smpair {
11619 	uint16_t		offset;
11620 	uint16_t		mask;
11621 	uint16_t		set;
11622 };
11623 
11624 static void
11625 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11626 {
11627 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11628 	struct bwn_softc *sc = mac->mac_sc;
11629 	struct ifnet *ifp = sc->sc_ifp;
11630 	struct ieee80211com *ic = ifp->if_l2com;
11631 	static const struct bwn_wpair v1[] = {
11632 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
11633 		{ BWN_PHY_AFE_CTL, 0x8800 },
11634 		{ BWN_PHY_AFE_CTL_OVR, 0 },
11635 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
11636 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
11637 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
11638 		{ BWN_PHY_OFDM(0xf9), 0 },
11639 		{ BWN_PHY_TR_LOOKUP_1, 0 }
11640 	};
11641 	static const struct bwn_smpair v2[] = {
11642 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11643 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11644 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11645 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11646 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11647 	};
11648 	static const struct bwn_smpair v3[] = {
11649 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11650 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11651 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11652 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11653 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11654 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11655 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11656 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11657 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11658 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11659 
11660 	};
11661 	int i;
11662 
11663 	for (i = 0; i < N(v1); i++)
11664 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11665 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11666 	for (i = 0; i < N(v2); i++)
11667 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11668 
11669 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11670 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11671 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11672 	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11673 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11674 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11675 	} else {
11676 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11677 	}
11678 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11679 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11680 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11681 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11682 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11683 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11684 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11685 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11686 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11687 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11688 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11689 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11690 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11691 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11692 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11693 	} else {
11694 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11695 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11696 	}
11697 	for (i = 0; i < N(v3); i++)
11698 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11699 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11700 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11701 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11702 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11703 	}
11704 
11705 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11706 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11707 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11708 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11709 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11710 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11711 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11712 	} else
11713 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11714 
11715 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11716 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11717 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11718 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11719 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11720 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11721 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11722 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11723 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11724 
11725 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11726 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11727 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11728 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11729 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11730 	}
11731 
11732 	bwn_phy_lp_digflt_save(mac);
11733 }
11734 
11735 static void
11736 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11737 {
11738 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11739 	struct bwn_softc *sc = mac->mac_sc;
11740 	struct ifnet *ifp = sc->sc_ifp;
11741 	struct ieee80211com *ic = ifp->if_l2com;
11742 	static const struct bwn_smpair v1[] = {
11743 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11744 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11745 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11746 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11747 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11748 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11749 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11750 	};
11751 	static const struct bwn_smpair v2[] = {
11752 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11753 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11754 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11755 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11756 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11757 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11758 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11759 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11760 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11761 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11762 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11763 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11764 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11765 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11766 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11767 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11768 	};
11769 	static const struct bwn_smpair v3[] = {
11770 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11771 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11772 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11773 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11774 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11775 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11776 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11777 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11778 	};
11779 	static const struct bwn_smpair v4[] = {
11780 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11781 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11782 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11783 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11784 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11785 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11786 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11787 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11788 	};
11789 	static const struct bwn_smpair v5[] = {
11790 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11791 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11792 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11793 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11794 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11795 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11796 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11797 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11798 	};
11799 	int i;
11800 	uint16_t tmp, tmp2;
11801 
11802 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11803 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11804 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11805 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11806 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11807 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11808 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11809 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11810 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11811 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11812 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11813 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11814 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11815 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11816 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11817 	for (i = 0; i < N(v1); i++)
11818 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11819 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11820 	    0xff00, plp->plp_rxpwroffset);
11821 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11822 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11823 	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11824 		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11825 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11826 		if (mac->mac_phy.rev == 0)
11827 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11828 			    0xffcf, 0x0010);
11829 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11830 	} else {
11831 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11832 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11833 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11834 	}
11835 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11836 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11837 	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11838 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11839 	else
11840 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11841 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11842 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11843 	    0xfff9, (plp->plp_bxarch << 1));
11844 	if (mac->mac_phy.rev == 1 &&
11845 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11846 		for (i = 0; i < N(v2); i++)
11847 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11848 			    v2[i].set);
11849 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11850 	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11851 	    ((mac->mac_phy.rev == 0) &&
11852 	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11853 		for (i = 0; i < N(v3); i++)
11854 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11855 			    v3[i].set);
11856 	} else if (mac->mac_phy.rev == 1 ||
11857 		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11858 		for (i = 0; i < N(v4); i++)
11859 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11860 			    v4[i].set);
11861 	} else {
11862 		for (i = 0; i < N(v5); i++)
11863 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11864 			    v5[i].set);
11865 	}
11866 	if (mac->mac_phy.rev == 1 &&
11867 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11868 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11869 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11870 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11871 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11872 	}
11873 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11874 	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11875 	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11876 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11877 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11878 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11879 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11880 	}
11881 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11882 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11883 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11884 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11885 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11886 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11887 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11888 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11889 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11890 	} else {
11891 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11892 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11893 	}
11894 	if (mac->mac_phy.rev == 1) {
11895 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11896 		tmp2 = (tmp & 0x03e0) >> 5;
11897 		tmp2 |= tmp2 << 5;
11898 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11899 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11900 		tmp2 = (tmp & 0x1f00) >> 8;
11901 		tmp2 |= tmp2 << 5;
11902 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11903 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11904 		tmp2 = tmp & 0x00ff;
11905 		tmp2 |= tmp << 8;
11906 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11907 	}
11908 }
11909 
11910 struct bwn_b2062_freq {
11911 	uint16_t		freq;
11912 	uint8_t			value[6];
11913 };
11914 
11915 static void
11916 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11917 {
11918 #define	CALC_CTL7(freq, div)						\
11919 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11920 #define	CALC_CTL18(freq, div)						\
11921 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11922 #define	CALC_CTL19(freq, div)						\
11923 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11924 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11925 	struct bwn_softc *sc = mac->mac_sc;
11926 	struct ifnet *ifp = sc->sc_ifp;
11927 	struct ieee80211com *ic = ifp->if_l2com;
11928 	static const struct bwn_b2062_freq freqdata_tab[] = {
11929 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
11930 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
11931 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
11932 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
11933 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
11934 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
11935 	};
11936 	static const struct bwn_wpair v1[] = {
11937 		{ BWN_B2062_N_TXCTL3, 0 },
11938 		{ BWN_B2062_N_TXCTL4, 0 },
11939 		{ BWN_B2062_N_TXCTL5, 0 },
11940 		{ BWN_B2062_N_TXCTL6, 0 },
11941 		{ BWN_B2062_N_PDNCTL0, 0x40 },
11942 		{ BWN_B2062_N_PDNCTL0, 0 },
11943 		{ BWN_B2062_N_CALIB_TS, 0x10 },
11944 		{ BWN_B2062_N_CALIB_TS, 0 }
11945 	};
11946 	const struct bwn_b2062_freq *f = NULL;
11947 	uint32_t xtalfreq, ref;
11948 	unsigned int i;
11949 
11950 	bwn_phy_lp_b2062_tblinit(mac);
11951 
11952 	for (i = 0; i < N(v1); i++)
11953 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11954 	if (mac->mac_phy.rev > 0)
11955 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11956 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11957 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11958 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11959 	else
11960 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11961 
11962 	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11963 	    ("%s:%d: fail", __func__, __LINE__));
11964 	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11965 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11966 
11967 	if (xtalfreq <= 30000000) {
11968 		plp->plp_div = 1;
11969 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11970 	} else {
11971 		plp->plp_div = 2;
11972 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11973 	}
11974 
11975 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11976 	    CALC_CTL7(xtalfreq, plp->plp_div));
11977 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11978 	    CALC_CTL18(xtalfreq, plp->plp_div));
11979 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11980 	    CALC_CTL19(xtalfreq, plp->plp_div));
11981 
11982 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11983 	ref &= 0xffff;
11984 	for (i = 0; i < N(freqdata_tab); i++) {
11985 		if (ref < freqdata_tab[i].freq) {
11986 			f = &freqdata_tab[i];
11987 			break;
11988 		}
11989 	}
11990 	if (f == NULL)
11991 		f = &freqdata_tab[N(freqdata_tab) - 1];
11992 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11993 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11994 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11995 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11996 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11997 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11998 #undef CALC_CTL7
11999 #undef CALC_CTL18
12000 #undef CALC_CTL19
12001 }
12002 
12003 static void
12004 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12005 {
12006 
12007 	bwn_phy_lp_b2063_tblinit(mac);
12008 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12009 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12010 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12011 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12012 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12013 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12014 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12015 	if (mac->mac_phy.rev == 2) {
12016 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12017 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12018 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12019 	} else {
12020 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12021 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12022 	}
12023 }
12024 
12025 static void
12026 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12027 {
12028 	struct bwn_softc *sc = mac->mac_sc;
12029 	static const struct bwn_wpair v1[] = {
12030 		{ BWN_B2063_RX_BB_SP8, 0x0 },
12031 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12032 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12033 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
12034 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
12035 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
12036 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
12037 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
12038 	};
12039 	static const struct bwn_wpair v2[] = {
12040 		{ BWN_B2063_TX_BB_SP3, 0x0 },
12041 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12042 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12043 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
12044 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
12045 	};
12046 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12047 	int i;
12048 	uint8_t tmp;
12049 
12050 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12051 
12052 	for (i = 0; i < 2; i++)
12053 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12054 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12055 	for (i = 2; i < N(v1); i++)
12056 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12057 	for (i = 0; i < 10000; i++) {
12058 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12059 			break;
12060 		DELAY(1000);
12061 	}
12062 
12063 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12064 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12065 
12066 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12067 
12068 	for (i = 0; i < N(v2); i++)
12069 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12070 	if (freqxtal == 24000000) {
12071 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12072 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12073 	} else {
12074 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12075 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12076 	}
12077 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12078 	for (i = 0; i < 10000; i++) {
12079 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12080 			break;
12081 		DELAY(1000);
12082 	}
12083 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12084 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12085 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12086 }
12087 
12088 static void
12089 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12090 {
12091 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12092 	struct bwn_softc *sc = mac->mac_sc;
12093 	struct bwn_phy_lp_iq_est ie;
12094 	struct bwn_txgain tx_gains;
12095 	static const uint32_t pwrtbl[21] = {
12096 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12097 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12098 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12099 		0x0004c, 0x0002c, 0x0001a,
12100 	};
12101 	uint32_t npwr, ipwr, sqpwr, tmp;
12102 	int loopback, i, j, sum, error;
12103 	uint16_t save[7];
12104 	uint8_t txo, bbmult, txpctlmode;
12105 
12106 	error = bwn_phy_lp_switch_channel(mac, 7);
12107 	if (error)
12108 		device_printf(sc->sc_dev,
12109 		    "failed to change channel to 7 (%d)\n", error);
12110 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12111 	bbmult = bwn_phy_lp_get_bbmult(mac);
12112 	if (txo)
12113 		tx_gains = bwn_phy_lp_get_txgain(mac);
12114 
12115 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12116 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12117 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12118 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12119 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12120 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12121 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12122 
12123 	bwn_phy_lp_get_txpctlmode(mac);
12124 	txpctlmode = plp->plp_txpctlmode;
12125 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12126 
12127 	/* disable CRS */
12128 	bwn_phy_lp_set_deaf(mac, 1);
12129 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
12130 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12131 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12132 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12133 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12134 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12135 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12136 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12137 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12138 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12139 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12140 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12141 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12142 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12143 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12144 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12145 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12146 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12147 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12148 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12149 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12150 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12151 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12152 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12153 
12154 	loopback = bwn_phy_lp_loopback(mac);
12155 	if (loopback == -1)
12156 		goto done;
12157 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
12158 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12159 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12160 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12161 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12162 
12163 	tmp = 0;
12164 	memset(&ie, 0, sizeof(ie));
12165 	for (i = 128; i <= 159; i++) {
12166 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12167 		sum = 0;
12168 		for (j = 5; j <= 25; j++) {
12169 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12170 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12171 				goto done;
12172 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12173 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12174 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12175 			    12);
12176 			sum += ((ipwr - npwr) * (ipwr - npwr));
12177 			if ((i == 128) || (sum < tmp)) {
12178 				plp->plp_rccap = i;
12179 				tmp = sum;
12180 			}
12181 		}
12182 	}
12183 	bwn_phy_lp_ddfs_turnoff(mac);
12184 done:
12185 	/* restore CRS */
12186 	bwn_phy_lp_clear_deaf(mac, 1);
12187 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12188 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12189 
12190 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12191 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12192 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12193 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12194 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12195 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12196 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12197 
12198 	bwn_phy_lp_set_bbmult(mac, bbmult);
12199 	if (txo)
12200 		bwn_phy_lp_set_txgain(mac, &tx_gains);
12201 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12202 	if (plp->plp_rccap)
12203 		bwn_phy_lp_set_rccap(mac);
12204 }
12205 
12206 static void
12207 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12208 {
12209 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12210 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12211 
12212 	if (mac->mac_phy.rev == 1)
12213 		rc_cap = MIN(rc_cap + 5, 15);
12214 
12215 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12216 	    MAX(plp->plp_rccap - 4, 0x80));
12217 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12218 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12219 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12220 }
12221 
12222 static uint32_t
12223 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12224 {
12225 	uint32_t i, q, r;
12226 
12227 	if (div == 0)
12228 		return (0);
12229 
12230 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12231 		q <<= 1;
12232 		if (r << 1 >= div) {
12233 			q++;
12234 			r = (r << 1) - div;
12235 		}
12236 	}
12237 	if (r << 1 >= div)
12238 		q++;
12239 	return (q);
12240 }
12241 
12242 static void
12243 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12244 {
12245 	struct bwn_softc *sc = mac->mac_sc;
12246 
12247 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12248 	DELAY(20);
12249 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12250 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12251 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12252 	} else {
12253 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12254 	}
12255 	DELAY(5);
12256 }
12257 
12258 static void
12259 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12260 {
12261 
12262 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12263 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12264 	DELAY(200);
12265 }
12266 
12267 static void
12268 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12269 {
12270 #define	FLAG_A	0x01
12271 #define	FLAG_G	0x02
12272 	struct bwn_softc *sc = mac->mac_sc;
12273 	struct ifnet *ifp = sc->sc_ifp;
12274 	struct ieee80211com *ic = ifp->if_l2com;
12275 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12276 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12277 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12278 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12279 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12280 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12281 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12282 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12283 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12284 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12285 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12286 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12287 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12288 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12289 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12290 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12291 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12292 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12293 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12294 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12295 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12296 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12297 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12298 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12299 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12300 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12301 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12302 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12303 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12304 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12305 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12306 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12307 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12308 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12309 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12310 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12311 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12312 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12313 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12314 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12315 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12316 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12317 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12318 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12319 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12320 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12321 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12322 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12323 	};
12324 	const struct bwn_b206x_rfinit_entry *br;
12325 	unsigned int i;
12326 
12327 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12328 		br = &bwn_b2062_init_tab[i];
12329 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12330 			if (br->br_flags & FLAG_G)
12331 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12332 		} else {
12333 			if (br->br_flags & FLAG_A)
12334 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12335 		}
12336 	}
12337 #undef FLAG_A
12338 #undef FLAG_B
12339 }
12340 
12341 static void
12342 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12343 {
12344 #define	FLAG_A	0x01
12345 #define	FLAG_G	0x02
12346 	struct bwn_softc *sc = mac->mac_sc;
12347 	struct ifnet *ifp = sc->sc_ifp;
12348 	struct ieee80211com *ic = ifp->if_l2com;
12349 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12350 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12351 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12352 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12353 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12354 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12355 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12356 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12357 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12358 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12359 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12360 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12361 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12362 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12363 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12364 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12365 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12366 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12367 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12368 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12369 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12370 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12371 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12372 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12373 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12374 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12375 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12376 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12377 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12378 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12379 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12380 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12381 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12382 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12383 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12384 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12385 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12386 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12387 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12388 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12389 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12390 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12391 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12392 	};
12393 	const struct bwn_b206x_rfinit_entry *br;
12394 	unsigned int i;
12395 
12396 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12397 		br = &bwn_b2063_init_tab[i];
12398 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12399 			if (br->br_flags & FLAG_G)
12400 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12401 		} else {
12402 			if (br->br_flags & FLAG_A)
12403 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12404 		}
12405 	}
12406 #undef FLAG_A
12407 #undef FLAG_B
12408 }
12409 
12410 static void
12411 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12412     int count, void *_data)
12413 {
12414 	unsigned int i;
12415 	uint32_t offset, type;
12416 	uint8_t *data = _data;
12417 
12418 	type = BWN_TAB_GETTYPE(typenoffset);
12419 	offset = BWN_TAB_GETOFFSET(typenoffset);
12420 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12421 
12422 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12423 
12424 	for (i = 0; i < count; i++) {
12425 		switch (type) {
12426 		case BWN_TAB_8BIT:
12427 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12428 			data++;
12429 			break;
12430 		case BWN_TAB_16BIT:
12431 			*((uint16_t *)data) = BWN_PHY_READ(mac,
12432 			    BWN_PHY_TABLEDATALO);
12433 			data += 2;
12434 			break;
12435 		case BWN_TAB_32BIT:
12436 			*((uint32_t *)data) = BWN_PHY_READ(mac,
12437 			    BWN_PHY_TABLEDATAHI);
12438 			*((uint32_t *)data) <<= 16;
12439 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
12440 			    BWN_PHY_TABLEDATALO);
12441 			data += 4;
12442 			break;
12443 		default:
12444 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12445 		}
12446 	}
12447 }
12448 
12449 static void
12450 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12451     int count, const void *_data)
12452 {
12453 	uint32_t offset, type, value;
12454 	const uint8_t *data = _data;
12455 	unsigned int i;
12456 
12457 	type = BWN_TAB_GETTYPE(typenoffset);
12458 	offset = BWN_TAB_GETOFFSET(typenoffset);
12459 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12460 
12461 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12462 
12463 	for (i = 0; i < count; i++) {
12464 		switch (type) {
12465 		case BWN_TAB_8BIT:
12466 			value = *data;
12467 			data++;
12468 			KASSERT(!(value & ~0xff),
12469 			    ("%s:%d: fail", __func__, __LINE__));
12470 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12471 			break;
12472 		case BWN_TAB_16BIT:
12473 			value = *((const uint16_t *)data);
12474 			data += 2;
12475 			KASSERT(!(value & ~0xffff),
12476 			    ("%s:%d: fail", __func__, __LINE__));
12477 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12478 			break;
12479 		case BWN_TAB_32BIT:
12480 			value = *((const uint32_t *)data);
12481 			data += 4;
12482 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12483 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12484 			break;
12485 		default:
12486 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12487 		}
12488 	}
12489 }
12490 
12491 static struct bwn_txgain
12492 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12493 {
12494 	struct bwn_txgain tg;
12495 	uint16_t tmp;
12496 
12497 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12498 	if (mac->mac_phy.rev < 2) {
12499 		tmp = BWN_PHY_READ(mac,
12500 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12501 		tg.tg_gm = tmp & 0x0007;
12502 		tg.tg_pga = (tmp & 0x0078) >> 3;
12503 		tg.tg_pad = (tmp & 0x780) >> 7;
12504 		return (tg);
12505 	}
12506 
12507 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12508 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12509 	tg.tg_gm = tmp & 0xff;
12510 	tg.tg_pga = (tmp >> 8) & 0xff;
12511 	return (tg);
12512 }
12513 
12514 static uint8_t
12515 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12516 {
12517 
12518 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12519 }
12520 
12521 static void
12522 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12523 {
12524 	uint16_t pa;
12525 
12526 	if (mac->mac_phy.rev < 2) {
12527 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12528 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12529 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12530 		bwn_phy_lp_set_txgain_override(mac);
12531 		return;
12532 	}
12533 
12534 	pa = bwn_phy_lp_get_pa_gain(mac);
12535 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12536 	    (tg->tg_pga << 8) | tg->tg_gm);
12537 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12538 	    tg->tg_pad | (pa << 6));
12539 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12540 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12541 	    tg->tg_pad | (pa << 8));
12542 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12543 	bwn_phy_lp_set_txgain_override(mac);
12544 }
12545 
12546 static void
12547 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12548 {
12549 
12550 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12551 }
12552 
12553 static void
12554 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12555 {
12556 	uint16_t trsw = (tx << 1) | rx;
12557 
12558 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12559 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12560 }
12561 
12562 static void
12563 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12564 {
12565 	struct bwn_softc *sc = mac->mac_sc;
12566 	struct ifnet *ifp = sc->sc_ifp;
12567 	struct ieee80211com *ic = ifp->if_l2com;
12568 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12569 
12570 	if (mac->mac_phy.rev < 2) {
12571 		trsw = gain & 0x1;
12572 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12573 		ext_lna = (gain & 2) >> 1;
12574 
12575 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12576 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12577 		    0xfbff, ext_lna << 10);
12578 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12579 		    0xf7ff, ext_lna << 11);
12580 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12581 	} else {
12582 		low_gain = gain & 0xffff;
12583 		high_gain = (gain >> 16) & 0xf;
12584 		ext_lna = (gain >> 21) & 0x1;
12585 		trsw = ~(gain >> 20) & 0x1;
12586 
12587 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12588 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12589 		    0xfdff, ext_lna << 9);
12590 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12591 		    0xfbff, ext_lna << 10);
12592 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12593 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12594 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12595 			tmp = (gain >> 2) & 0x3;
12596 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12597 			    0xe7ff, tmp<<11);
12598 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12599 			    tmp << 3);
12600 		}
12601 	}
12602 
12603 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12604 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12605 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12606 	if (mac->mac_phy.rev >= 2) {
12607 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12608 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12609 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12610 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12611 		}
12612 		return;
12613 	}
12614 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12615 }
12616 
12617 static void
12618 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12619 {
12620 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12621 
12622 	if (user)
12623 		plp->plp_crsusr_off = 1;
12624 	else
12625 		plp->plp_crssys_off = 1;
12626 
12627 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12628 }
12629 
12630 static void
12631 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12632 {
12633 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12634 	struct bwn_softc *sc = mac->mac_sc;
12635 	struct ifnet *ifp = sc->sc_ifp;
12636 	struct ieee80211com *ic = ifp->if_l2com;
12637 
12638 	if (user)
12639 		plp->plp_crsusr_off = 0;
12640 	else
12641 		plp->plp_crssys_off = 0;
12642 
12643 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
12644 		return;
12645 
12646 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12647 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12648 	else
12649 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12650 }
12651 
12652 static unsigned int
12653 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12654 {
12655 	/* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12656 	static uint8_t sqrt_table[256] = {
12657 		10, 14, 17, 20, 22, 24, 26, 28,
12658 		30, 31, 33, 34, 36, 37, 38, 40,
12659 		41, 42, 43, 44, 45, 46, 47, 48,
12660 		50, 50, 51, 52, 53, 54, 55, 56,
12661 		57, 58, 59, 60, 60, 61, 62, 63,
12662 		64, 64, 65, 66, 67, 67, 68, 69,
12663 		70, 70, 71, 72, 72, 73, 74, 74,
12664 		75, 76, 76, 77, 78, 78, 79, 80,
12665 		80, 81, 81, 82, 83, 83, 84, 84,
12666 		85, 86, 86, 87, 87, 88, 88, 89,
12667 		90, 90, 91, 91, 92, 92, 93, 93,
12668 		94, 94, 95, 95, 96, 96, 97, 97,
12669 		98, 98, 99, 100, 100, 100, 101, 101,
12670 		102, 102, 103, 103, 104, 104, 105, 105,
12671 		106, 106, 107, 107, 108, 108, 109, 109,
12672 		110, 110, 110, 111, 111, 112, 112, 113,
12673 		113, 114, 114, 114, 115, 115, 116, 116,
12674 		117, 117, 117, 118, 118, 119, 119, 120,
12675 		120, 120, 121, 121, 122, 122, 122, 123,
12676 		123, 124, 124, 124, 125, 125, 126, 126,
12677 		126, 127, 127, 128, 128, 128, 129, 129,
12678 		130, 130, 130, 131, 131, 131, 132, 132,
12679 		133, 133, 133, 134, 134, 134, 135, 135,
12680 		136, 136, 136, 137, 137, 137, 138, 138,
12681 		138, 139, 139, 140, 140, 140, 141, 141,
12682 		141, 142, 142, 142, 143, 143, 143, 144,
12683 		144, 144, 145, 145, 145, 146, 146, 146,
12684 		147, 147, 147, 148, 148, 148, 149, 149,
12685 		150, 150, 150, 150, 151, 151, 151, 152,
12686 		152, 152, 153, 153, 153, 154, 154, 154,
12687 		155, 155, 155, 156, 156, 156, 157, 157,
12688 		157, 158, 158, 158, 159, 159, 159, 160
12689 	};
12690 
12691 	if (x == 0)
12692 		return (0);
12693 	if (x >= 256) {
12694 		unsigned int tmp;
12695 
12696 		for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12697 			/* do nothing */ ;
12698 		return (tmp);
12699 	}
12700 	return (sqrt_table[x - 1] / 10);
12701 }
12702 
12703 static int
12704 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12705 {
12706 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
12707 	int _t;								\
12708 	_t = _x - 20;							\
12709 	if (_t >= 0) {							\
12710 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12711 	} else {							\
12712 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12713 	}								\
12714 } while (0)
12715 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
12716 	int _t;								\
12717 	_t = _x - 11;							\
12718 	if (_t >= 0)							\
12719 		_v = (_y << (31 - _x)) / (_z >> _t);			\
12720 	else								\
12721 		_v = (_y << (31 - _x)) / (_z << -_t);			\
12722 } while (0)
12723 	struct bwn_phy_lp_iq_est ie;
12724 	uint16_t v0, v1;
12725 	int tmp[2], ret;
12726 
12727 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12728 	v0 = v1 >> 8;
12729 	v1 |= 0xff;
12730 
12731 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12732 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12733 
12734 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12735 	if (ret == 0)
12736 		goto done;
12737 
12738 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12739 		ret = 0;
12740 		goto done;
12741 	}
12742 
12743 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12744 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12745 
12746 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12747 	v0 = tmp[0] >> 3;
12748 	v1 = tmp[1] >> 4;
12749 done:
12750 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12751 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12752 	return ret;
12753 #undef CALC_COEFF
12754 #undef CALC_COEFF2
12755 }
12756 
12757 static void
12758 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12759 {
12760 	static const uint16_t noisescale[] = {
12761 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12762 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12763 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12764 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12765 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12766 	};
12767 	static const uint16_t crsgainnft[] = {
12768 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12769 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12770 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12771 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12772 		0x013d,
12773 	};
12774 	static const uint16_t filterctl[] = {
12775 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12776 		0xff53, 0x0127,
12777 	};
12778 	static const uint32_t psctl[] = {
12779 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12780 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12781 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12782 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12783 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12784 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12785 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12786 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12787 	};
12788 	static const uint16_t ofdmcckgain_r0[] = {
12789 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12790 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12791 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12792 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12793 		0x755d,
12794 	};
12795 	static const uint16_t ofdmcckgain_r1[] = {
12796 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12797 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12798 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12799 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12800 		0x755d,
12801 	};
12802 	static const uint16_t gaindelta[] = {
12803 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12804 		0x0000,
12805 	};
12806 	static const uint32_t txpwrctl[] = {
12807 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12808 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12809 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12810 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12811 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12812 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12813 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12814 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12815 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12816 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12817 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12818 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12819 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000,
12843 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12844 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12845 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12846 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12847 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12848 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12849 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12850 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12851 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12852 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12853 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12854 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12855 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12856 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12857 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12858 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12859 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12860 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12861 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12862 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12863 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12864 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12865 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12866 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12867 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12868 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12869 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12870 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12871 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12872 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12873 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12874 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12875 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12876 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12877 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12878 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12879 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12880 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12881 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12882 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12883 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12884 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12885 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12886 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12887 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12888 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12889 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12890 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12891 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12892 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12893 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12894 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12895 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12896 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12897 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12898 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12899 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12900 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12901 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12902 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12903 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12904 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12905 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12906 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12907 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12908 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12909 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12910 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12911 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12912 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12913 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12914 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12915 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12916 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12917 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12918 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12919 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12920 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12921 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12922 		0x00000702,
12923 	};
12924 
12925 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12926 
12927 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12928 	    bwn_tab_sigsq_tbl);
12929 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12930 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12931 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12932 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12933 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12934 	    bwn_tab_pllfrac_tbl);
12935 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12936 	    bwn_tabl_iqlocal_tbl);
12937 	if (mac->mac_phy.rev == 0) {
12938 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12939 		    ofdmcckgain_r0);
12940 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12941 		    ofdmcckgain_r0);
12942 	} else {
12943 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12944 		    ofdmcckgain_r1);
12945 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12946 		    ofdmcckgain_r1);
12947 	}
12948 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12949 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12950 }
12951 
12952 static void
12953 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12954 {
12955 	struct bwn_softc *sc = mac->mac_sc;
12956 	int i;
12957 	static const uint16_t noisescale[] = {
12958 		0x00a4, 0x00a4, 0x00a4, 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, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12962 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12963 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12964 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12965 	};
12966 	static const uint32_t filterctl[] = {
12967 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12968 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12969 	};
12970 	static const uint32_t psctl[] = {
12971 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12972 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12973 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12974 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12975 	};
12976 	static const uint32_t gainidx[] = {
12977 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12978 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12979 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12980 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12981 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12982 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12983 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12984 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12985 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12986 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12987 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12988 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12989 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12990 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12991 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12992 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12993 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12994 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12995 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12996 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12997 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12998 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12999 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13000 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13001 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13002 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13003 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13004 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13005 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13006 		0x0000001a, 0x64ca55ad, 0x0000001a
13007 	};
13008 	static const uint16_t auxgainidx[] = {
13009 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13010 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13011 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13012 		0x0004, 0x0016
13013 	};
13014 	static const uint16_t swctl[] = {
13015 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13016 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13017 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13018 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13019 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13020 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13021 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13022 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13023 	};
13024 	static const uint8_t hf[] = {
13025 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13026 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13027 	};
13028 	static const uint32_t gainval[] = {
13029 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13030 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13031 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13032 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13033 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13034 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13035 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13036 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13037 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13038 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13039 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13040 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13041 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13042 		0x000000f1, 0x00000000, 0x00000000
13043 	};
13044 	static const uint16_t gain[] = {
13045 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13046 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13047 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13048 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13049 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13050 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13055 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13056 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13057 	};
13058 	static const uint32_t papdeps[] = {
13059 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13060 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13061 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13062 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13063 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13064 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13065 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13066 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13067 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13068 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13069 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13070 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13071 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13072 	};
13073 	static const uint32_t papdmult[] = {
13074 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13075 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13076 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13077 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13078 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13079 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13080 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13081 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13082 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13083 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13084 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13085 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13086 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13087 	};
13088 	static const uint32_t gainidx_a0[] = {
13089 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13090 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13091 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13092 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13093 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13094 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13095 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13096 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13097 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13098 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13099 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13100 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13101 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13102 	};
13103 	static const uint16_t auxgainidx_a0[] = {
13104 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13105 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13106 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13107 		0x0002, 0x0014
13108 	};
13109 	static const uint32_t gainval_a0[] = {
13110 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13111 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13112 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13113 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13114 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13115 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13116 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13117 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13118 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13119 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13120 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13121 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13122 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13123 		0x000000f7, 0x00000000, 0x00000000
13124 	};
13125 	static const uint16_t gain_a0[] = {
13126 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13127 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13128 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13129 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13130 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13131 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 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 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13136 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13137 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13138 	};
13139 
13140 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13141 
13142 	for (i = 0; i < 704; i++)
13143 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13144 
13145 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13146 	    bwn_tab_sigsq_tbl);
13147 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13148 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13149 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13150 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13151 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13152 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13153 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13154 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13155 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13156 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13157 	    bwn_tab_pllfrac_tbl);
13158 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13159 	    bwn_tabl_iqlocal_tbl);
13160 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13161 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13162 
13163 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13164 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
13165 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13166 		    gainidx_a0);
13167 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13168 		    auxgainidx_a0);
13169 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13170 		    gainval_a0);
13171 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13172 	}
13173 }
13174 
13175 static void
13176 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13177 {
13178 	struct bwn_softc *sc = mac->mac_sc;
13179 	struct ifnet *ifp = sc->sc_ifp;
13180 	struct ieee80211com *ic = ifp->if_l2com;
13181 	static struct bwn_txgain_entry txgain_r2[] = {
13182 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13183 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13184 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13185 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13186 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13187 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13188 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13189 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13190 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13191 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13192 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13193 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13194 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13195 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13196 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13197 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13198 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13199 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13200 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13201 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13202 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13203 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13204 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13205 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13206 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13207 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13208 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13209 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13210 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13211 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13212 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13213 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13214 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13215 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13216 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13217 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13218 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13219 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13220 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13221 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13222 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13223 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13224 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13225 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13226 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13227 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13228 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13229 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13230 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13231 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13232 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13233 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13234 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13235 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13236 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13237 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13238 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13239 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13240 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13241 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13242 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13243 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13244 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13245 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13246 	};
13247 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13248 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13249 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13250 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13251 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13252 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13253 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13254 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13255 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13256 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13257 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13258 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13259 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13260 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13261 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13262 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13263 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13264 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13265 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13266 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13267 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13268 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13269 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13270 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13271 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13272 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13273 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13274 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13275 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13276 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13277 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13278 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13279 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13280 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13281 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13282 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13283 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13284 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13285 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13286 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13287 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13288 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13289 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13290 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13291 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13292 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13293 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13294 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13295 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13296 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13297 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13298 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13299 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13300 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13301 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13302 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13303 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13304 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13305 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13306 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13307 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13308 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13309 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13310 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13311 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13312 	};
13313 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13314 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13315 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13316 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13317 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13318 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13319 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13320 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13321 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13322 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13323 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13324 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13325 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13326 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13327 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13328 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13329 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13330 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13331 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13332 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13333 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13334 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13335 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13336 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13337 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13338 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13339 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13340 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13341 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13342 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13343 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13344 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13345 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13346 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13347 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13348 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13349 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13350 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13351 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13352 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13353 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13354 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13355 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13356 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13357 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13358 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13359 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13360 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13361 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13362 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13363 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13364 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13365 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13366 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13367 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13368 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13369 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13370 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13371 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13372 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13373 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13374 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13375 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13376 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13377 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13378 	};
13379 	static struct bwn_txgain_entry txgain_r0[] = {
13380 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13381 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13382 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13383 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13384 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13385 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13386 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13387 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13388 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13389 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13390 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13391 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13392 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13393 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13394 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13395 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13396 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13397 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13398 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13399 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13400 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13401 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13402 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13403 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13404 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13405 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13406 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13407 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13408 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13409 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13410 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13411 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13412 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13413 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13414 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13415 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13416 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13417 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13418 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13419 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13420 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13421 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13422 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13423 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13424 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13425 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13426 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13427 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13428 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13429 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13430 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13431 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13432 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13433 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13434 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13435 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13436 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13437 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13438 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13439 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13440 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13441 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13442 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13443 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13444 	};
13445 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13446 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13447 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13448 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13449 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13450 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13451 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13452 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13453 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13454 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13455 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13456 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13457 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13458 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13459 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13460 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13461 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13462 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13463 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13464 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13465 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13466 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13467 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13468 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13469 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13470 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13471 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13472 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13473 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13474 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13475 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13476 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13477 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13478 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13479 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13480 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13481 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13482 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13483 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13484 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13485 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13486 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13487 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13488 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13489 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13490 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13491 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13492 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13493 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13494 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13495 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13496 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13497 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13498 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13499 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13500 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13501 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13502 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13503 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13504 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13505 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13506 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13507 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13508 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13509 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13510 	};
13511 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13512 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13513 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13514 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13515 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13516 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13517 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13518 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13519 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13520 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13521 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13522 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13523 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13524 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13525 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13526 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13527 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13528 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13529 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13530 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13531 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13532 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13533 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13534 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13535 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13536 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13537 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13538 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13539 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13540 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13541 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13542 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13543 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13544 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13545 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13546 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13547 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13548 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13549 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13550 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13551 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13552 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13553 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13554 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13555 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13556 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13557 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13558 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13559 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13560 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13561 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13562 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13563 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13564 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13565 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13566 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13567 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13568 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13569 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13570 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13571 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13572 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13573 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13574 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13575 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13576 	};
13577 	static struct bwn_txgain_entry txgain_r1[] = {
13578 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13579 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13580 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13581 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13582 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13583 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13584 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13585 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13586 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13587 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13588 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13589 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13590 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13591 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13592 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13593 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13594 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13595 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13596 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13597 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13598 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13599 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13600 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13601 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13602 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13603 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13604 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13605 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13606 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13607 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13608 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13609 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13610 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13611 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13612 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13613 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13614 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13615 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13616 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13617 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13618 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13619 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13620 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13621 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13622 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13623 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13624 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13625 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13626 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13627 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13628 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13629 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13630 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13631 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13632 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13633 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13634 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13635 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13636 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13637 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13638 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13639 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13640 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13641 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13642 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13643 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13644 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13645 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13646 		{ 7, 11, 6, 0, 71 }
13647 	};
13648 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13649 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13650 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13651 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13652 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13653 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13654 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13655 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13656 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13657 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13658 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13659 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13660 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13661 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13662 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13663 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13664 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13665 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13666 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13667 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13668 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13669 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13670 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13671 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13672 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13673 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13674 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13675 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13676 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13677 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13678 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13679 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13680 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13681 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13682 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13683 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13684 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13685 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13686 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13687 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13688 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13689 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13690 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13691 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13692 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13693 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13694 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13695 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13696 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13697 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13698 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13699 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13700 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13701 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13702 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13703 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13704 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13705 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13706 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13707 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13708 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13709 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13710 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13711 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13712 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13713 	};
13714 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13715 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13716 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13717 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13718 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13719 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13720 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13721 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13722 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13723 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13724 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13725 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13726 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13727 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13728 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13729 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13730 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13731 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13732 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13733 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13734 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13735 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13736 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13737 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13738 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13739 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13740 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13741 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13742 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13743 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13744 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13745 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13746 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13747 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13748 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13749 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13750 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13751 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13752 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13753 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13754 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13755 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13756 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13757 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13758 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13759 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13760 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13761 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13762 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13763 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13764 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13765 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13766 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13767 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13768 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13769 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13770 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13771 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13772 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13773 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13774 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13775 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13776 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13777 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13778 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13779 	};
13780 
13781 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13782 		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13783 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13784 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13785 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13786 			    txgain_2ghz_r2);
13787 		else
13788 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13789 			    txgain_5ghz_r2);
13790 		return;
13791 	}
13792 
13793 	if (mac->mac_phy.rev == 0) {
13794 		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13795 		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13796 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13797 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13798 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13799 			    txgain_2ghz_r0);
13800 		else
13801 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13802 			    txgain_5ghz_r0);
13803 		return;
13804 	}
13805 
13806 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13807 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13808 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13809 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13810 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13811 	else
13812 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13813 }
13814 
13815 static void
13816 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13817 {
13818 	uint32_t offset, type;
13819 
13820 	type = BWN_TAB_GETTYPE(typeoffset);
13821 	offset = BWN_TAB_GETOFFSET(typeoffset);
13822 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13823 
13824 	switch (type) {
13825 	case BWN_TAB_8BIT:
13826 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13827 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13828 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13829 		break;
13830 	case BWN_TAB_16BIT:
13831 		KASSERT(!(value & ~0xffff),
13832 		    ("%s:%d: fail", __func__, __LINE__));
13833 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13834 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13835 		break;
13836 	case BWN_TAB_32BIT:
13837 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13838 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13839 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13840 		break;
13841 	default:
13842 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13843 	}
13844 }
13845 
13846 static int
13847 bwn_phy_lp_loopback(struct bwn_mac *mac)
13848 {
13849 	struct bwn_phy_lp_iq_est ie;
13850 	int i, index = -1;
13851 	uint32_t tmp;
13852 
13853 	memset(&ie, 0, sizeof(ie));
13854 
13855 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
13856 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13857 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13858 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13859 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13860 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13861 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13862 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13863 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13864 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13865 	for (i = 0; i < 32; i++) {
13866 		bwn_phy_lp_set_rxgain_idx(mac, i);
13867 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13868 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13869 			continue;
13870 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13871 		if ((tmp > 4000) && (tmp < 10000)) {
13872 			index = i;
13873 			break;
13874 		}
13875 	}
13876 	bwn_phy_lp_ddfs_turnoff(mac);
13877 	return (index);
13878 }
13879 
13880 static void
13881 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13882 {
13883 
13884 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13885 }
13886 
13887 static void
13888 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13889     int incr1, int incr2, int scale_idx)
13890 {
13891 
13892 	bwn_phy_lp_ddfs_turnoff(mac);
13893 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13894 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13895 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13896 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13897 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13898 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13899 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13900 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13901 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13902 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13903 }
13904 
13905 static uint8_t
13906 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13907     struct bwn_phy_lp_iq_est *ie)
13908 {
13909 	int i;
13910 
13911 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13912 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13913 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13914 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13915 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13916 
13917 	for (i = 0; i < 500; i++) {
13918 		if (!(BWN_PHY_READ(mac,
13919 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13920 			break;
13921 		DELAY(1000);
13922 	}
13923 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13924 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13925 		return 0;
13926 	}
13927 
13928 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13929 	ie->ie_iqprod <<= 16;
13930 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13931 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13932 	ie->ie_ipwr <<= 16;
13933 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13934 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13935 	ie->ie_qpwr <<= 16;
13936 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13937 
13938 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13939 	return 1;
13940 }
13941 
13942 static uint32_t
13943 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13944 {
13945 	uint32_t offset, type, value;
13946 
13947 	type = BWN_TAB_GETTYPE(typeoffset);
13948 	offset = BWN_TAB_GETOFFSET(typeoffset);
13949 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13950 
13951 	switch (type) {
13952 	case BWN_TAB_8BIT:
13953 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13954 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13955 		break;
13956 	case BWN_TAB_16BIT:
13957 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13958 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13959 		break;
13960 	case BWN_TAB_32BIT:
13961 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13962 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13963 		value <<= 16;
13964 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13965 		break;
13966 	default:
13967 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13968 		value = 0;
13969 	}
13970 
13971 	return (value);
13972 }
13973 
13974 static void
13975 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13976 {
13977 
13978 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13979 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13980 }
13981 
13982 static void
13983 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13984 {
13985 	uint16_t ctl;
13986 
13987 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13988 	ctl |= dac << 7;
13989 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13990 }
13991 
13992 static void
13993 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13994 {
13995 
13996 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13997 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13998 }
13999 
14000 static void
14001 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14002 {
14003 
14004 	if (mac->mac_phy.rev < 2)
14005 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14006 	else {
14007 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14008 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14009 	}
14010 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14011 }
14012 
14013 static uint16_t
14014 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14015 {
14016 
14017 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14018 }
14019 
14020 static uint8_t
14021 bwn_nbits(int32_t val)
14022 {
14023 	uint32_t tmp;
14024 	uint8_t nbits = 0;
14025 
14026 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
14027 		nbits++;
14028 	return (nbits);
14029 }
14030 
14031 static void
14032 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14033     struct bwn_txgain_entry *table)
14034 {
14035 	int i;
14036 
14037 	for (i = offset; i < count; i++)
14038 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14039 }
14040 
14041 static void
14042 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14043     struct bwn_txgain_entry data)
14044 {
14045 
14046 	if (mac->mac_phy.rev >= 2)
14047 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14048 	else
14049 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14050 }
14051 
14052 static void
14053 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14054     struct bwn_txgain_entry te)
14055 {
14056 	struct bwn_softc *sc = mac->mac_sc;
14057 	struct ifnet *ifp = sc->sc_ifp;
14058 	struct ieee80211com *ic = ifp->if_l2com;
14059 	uint32_t tmp;
14060 
14061 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14062 
14063 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14064 	if (mac->mac_phy.rev >= 3) {
14065 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14066 		    (0x10 << 24) : (0x70 << 24));
14067 	} else {
14068 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14069 		    (0x14 << 24) : (0x7f << 24));
14070 	}
14071 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14072 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14073 	    te.te_bbmult << 20 | te.te_dac << 28);
14074 }
14075 
14076 static void
14077 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14078     struct bwn_txgain_entry te)
14079 {
14080 
14081 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14082 
14083 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14084 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14085 	    te.te_dac);
14086 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14087 }
14088 
14089 static void
14090 bwn_sysctl_node(struct bwn_softc *sc)
14091 {
14092 	struct bwn_mac *mac;
14093 	struct bwn_stats *stats;
14094 	struct sysctl_ctx_list *ctx;
14095 	struct sysctl_oid *tree;
14096 
14097 	/* XXX assume that count of MAC is only 1. */
14098 
14099 	if ((mac = sc->sc_curmac) == NULL)
14100 		return;
14101 	stats = &mac->mac_stats;
14102 
14103 	ctx = device_get_sysctl_ctx(sc->sc_dev);
14104 	tree = device_get_sysctl_tree(sc->sc_dev);
14105 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14106 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14107 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14108 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14109 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14110 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14111 
14112 #ifdef BWN_DEBUG
14113 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14114 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14115 #endif
14116 }
14117 
14118 static device_method_t bwn_methods[] = {
14119 	/* Device interface */
14120 	DEVMETHOD(device_probe,		bwn_probe),
14121 	DEVMETHOD(device_attach,	bwn_attach),
14122 	DEVMETHOD(device_detach,	bwn_detach),
14123 	DEVMETHOD(device_suspend,	bwn_suspend),
14124 	DEVMETHOD(device_resume,	bwn_resume),
14125 	DEVMETHOD_END
14126 };
14127 static driver_t bwn_driver = {
14128 	"bwn",
14129 	bwn_methods,
14130 	sizeof(struct bwn_softc)
14131 };
14132 static devclass_t bwn_devclass;
14133 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL);
14134 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14135 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
14136 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
14137 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
14138