xref: /dragonfly/sys/dev/netif/bwn/bwn/if_bwn.c (revision f503b4c4)
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 	if (sc->sc_sysctl_tree) {
1138 		sysctl_ctx_free(&sc->sc_sysctl_ctx);
1139 		sc->sc_sysctl_tree = NULL;
1140 	}
1141 
1142 	wlan_serialize_exit();
1143 	return (0);
1144 }
1145 
1146 static int
1147 bwn_attach_pre(struct bwn_softc *sc)
1148 {
1149 	struct ifnet *ifp;
1150 	int error = 0;
1151 
1152 	TAILQ_INIT(&sc->sc_maclist);
1153 	callout_init(&sc->sc_rfswitch_ch);
1154 	callout_init(&sc->sc_task_ch);
1155 	callout_init(&sc->sc_watchdog_ch);
1156 
1157 	sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK,
1158 		taskqueue_thread_enqueue, &sc->sc_tq);
1159 	taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
1160 		"%s taskq", device_get_nameunit(sc->sc_dev));
1161 
1162 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1163 	if (ifp == NULL) {
1164 		device_printf(sc->sc_dev, "can not if_alloc()\n");
1165 		error = ENOSPC;
1166 		goto fail;
1167 	}
1168 
1169 	/* set these up early for if_printf use */
1170 	if_initname(ifp, device_get_name(sc->sc_dev),
1171 	    device_get_unit(sc->sc_dev));
1172 
1173 	/* prepare sysctl tree for use in sub modules */
1174 	sysctl_ctx_init(&sc->sc_sysctl_ctx);
1175 	sc->sc_sysctl_tree = SYSCTL_ADD_NODE(&sc->sc_sysctl_ctx,
1176 		SYSCTL_STATIC_CHILDREN(_hw),
1177 		OID_AUTO,
1178 		device_get_nameunit(sc->sc_dev),
1179 		CTLFLAG_RD, 0, "");
1180 
1181 	ifp->if_softc = sc;
1182 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1183 	ifp->if_init = bwn_init;
1184 	ifp->if_ioctl = bwn_ioctl;
1185 	ifp->if_start = bwn_start;
1186 	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
1187 
1188 	return (0);
1189 
1190 fail:
1191 	return (error);
1192 }
1193 
1194 static void
1195 bwn_sprom_bugfixes(device_t dev)
1196 {
1197 #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
1198 	((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&		\
1199 	 (siba_get_pci_device(dev) == _device) &&			\
1200 	 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&	\
1201 	 (siba_get_pci_subdevice(dev) == _subdevice))
1202 
1203 	if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1204 	    siba_get_pci_subdevice(dev) == 0x4e &&
1205 	    siba_get_pci_revid(dev) > 0x40)
1206 		siba_sprom_set_bf_lo(dev,
1207 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1208 	if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1209 	    siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1210 		siba_sprom_set_bf_lo(dev,
1211 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1212 	if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1213 		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1214 		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1215 		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1216 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1217 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1218 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1219 		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1220 			siba_sprom_set_bf_lo(dev,
1221 			    siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1222 	}
1223 #undef	BWN_ISDEV
1224 }
1225 
1226 static int
1227 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
1228 	  struct ucred *cr __unused)
1229 {
1230 #define IS_RUNNING(ifp) \
1231         ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1232 	struct bwn_softc *sc = ifp->if_softc;
1233 	struct ieee80211com *ic = ifp->if_l2com;
1234 	struct ifreq *ifr = (struct ifreq *)data;
1235 	int error = 0;
1236 
1237 	switch (cmd) {
1238 	case SIOCSIFFLAGS:
1239 		if (IS_RUNNING(ifp)) {
1240 			bwn_update_promisc(ifp);
1241 		} else if (ifp->if_flags & IFF_UP) {
1242 			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1243 				bwn_init(sc);
1244 			}
1245 		} else
1246 			bwn_stop(sc, 1);
1247 		break;
1248 	case SIOCGIFMEDIA:
1249 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1250 		break;
1251 	case SIOCGIFADDR:
1252 		error = ether_ioctl(ifp, cmd, data);
1253 		break;
1254 	default:
1255 		error = EINVAL;
1256 		break;
1257 	}
1258 	return (error);
1259 }
1260 
1261 static void
1262 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1263 {
1264 	wlan_assert_serialized();
1265 	bwn_start_locked(ifp);
1266 }
1267 
1268 static void
1269 bwn_start_locked(struct ifnet *ifp)
1270 {
1271 	struct bwn_softc *sc = ifp->if_softc;
1272 	struct bwn_mac *mac = sc->sc_curmac;
1273 	struct ieee80211_frame *wh;
1274 	struct ieee80211_node *ni;
1275 	struct ieee80211_key *k;
1276 	struct mbuf *m;
1277 
1278 	wlan_assert_serialized();
1279 
1280 	if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL ||
1281 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
1282 		return;
1283 
1284 	for (;;) {
1285 		m = ifq_dequeue(&ifp->if_snd);	/* XXX: LOCK */
1286 		if (m == NULL)
1287 			break;
1288 
1289 		if (bwn_tx_isfull(sc, m))
1290 			break;
1291 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1292 		if (ni == NULL) {
1293 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
1294 			m_freem(m);
1295 			ifp->if_oerrors++;
1296 			continue;
1297 		}
1298 		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1299 		wh = mtod(m, struct ieee80211_frame *);
1300 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1301 			k = ieee80211_crypto_encap(ni, m);
1302 			if (k == NULL) {
1303 				ieee80211_free_node(ni);
1304 				m_freem(m);
1305 				ifp->if_oerrors++;
1306 				continue;
1307 			}
1308 		}
1309 		wh = NULL;	/* Catch any invalid use */
1310 
1311 		if (bwn_tx_start(sc, ni, m) != 0) {
1312 			if (ni != NULL)
1313 				ieee80211_free_node(ni);
1314 			ifp->if_oerrors++;
1315 			continue;
1316 		}
1317 
1318 		sc->sc_watchdog_timer = 5;
1319 	}
1320 }
1321 
1322 static int
1323 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1324 {
1325 	struct bwn_dma_ring *dr;
1326 	struct bwn_mac *mac = sc->sc_curmac;
1327 	struct bwn_pio_txqueue *tq;
1328 	struct ifnet *ifp = sc->sc_ifp;
1329 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1330 
1331 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1332 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1333 		if (dr->dr_stop == 1 ||
1334 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1335 			dr->dr_stop = 1;
1336 			goto full;
1337 		}
1338 	} else {
1339 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1340 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1341 		    pktlen > (tq->tq_size - tq->tq_used)) {
1342 			tq->tq_stop = 1;
1343 			goto full;
1344 		}
1345 	}
1346 	return (0);
1347 full:
1348 	ifq_prepend(&ifp->if_snd, m);
1349 	ifq_set_oactive(&ifp->if_snd);
1350 	return (1);
1351 }
1352 
1353 static int
1354 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1355 {
1356 	struct bwn_mac *mac = sc->sc_curmac;
1357 	int error;
1358 
1359 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1360 		m_freem(m);
1361 		return (ENXIO);
1362 	}
1363 
1364 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1365 	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1366 	if (error) {
1367 		m_freem(m);
1368 		return (error);
1369 	}
1370 	return (0);
1371 }
1372 
1373 static int
1374 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1375 {
1376 	struct bwn_pio_txpkt *tp;
1377 	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1378 	struct bwn_softc *sc = mac->mac_sc;
1379 	struct bwn_txhdr txhdr;
1380 	struct mbuf *m_new;
1381 	uint32_t ctl32;
1382 	int error;
1383 	uint16_t ctl16;
1384 
1385 	/* XXX TODO send packets after DTIM */
1386 
1387 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1388 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1389 	tp->tp_ni = ni;
1390 	tp->tp_m = m;
1391 
1392 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1393 	if (error) {
1394 		device_printf(sc->sc_dev, "tx fail\n");
1395 		return (error);
1396 	}
1397 
1398 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1399 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1400 	tq->tq_free--;
1401 
1402 	if (siba_get_revid(sc->sc_dev) >= 8) {
1403 		/*
1404 		 * XXX please removes m_defrag(9)
1405 		 */
1406 		m_new = m_defrag(m, M_INTWAIT);
1407 		if (m_new == NULL) {
1408 			device_printf(sc->sc_dev,
1409 			    "%s: can't defrag TX buffer\n",
1410 			    __func__);
1411 			return (ENOBUFS);
1412 		}
1413 		if (m_new->m_next != NULL)
1414 			device_printf(sc->sc_dev,
1415 			    "TODO: fragmented packets for PIO\n");
1416 		tp->tp_m = m_new;
1417 
1418 		/* send HEADER */
1419 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1420 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1421 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1422 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1423 		/* send BODY */
1424 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1425 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1426 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1427 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1428 	} else {
1429 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1430 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1431 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1432 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1433 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1434 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1435 		    ctl16 | BWN_PIO_TXCTL_EOF);
1436 	}
1437 
1438 	return (0);
1439 }
1440 
1441 static struct bwn_pio_txqueue *
1442 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1443 {
1444 
1445 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1446 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1447 
1448 	switch (prio) {
1449 	case 0:
1450 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1451 	case 1:
1452 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1453 	case 2:
1454 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1455 	case 3:
1456 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1457 	}
1458 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1459 	return (NULL);
1460 }
1461 
1462 static int
1463 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1464 {
1465 #define	BWN_GET_TXHDRCACHE(slot)					\
1466 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)])
1467 	struct bwn_dma *dma = &mac->mac_method.dma;
1468 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1469 	struct bwn_dmadesc_generic *desc;
1470 	struct bwn_dmadesc_meta *mt;
1471 	struct bwn_softc *sc = mac->mac_sc;
1472 	struct ifnet *ifp = sc->sc_ifp;
1473 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1474 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1475 
1476 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1477 
1478 	/* XXX send after DTIM */
1479 
1480 	slot = bwn_dma_getslot(dr);
1481 	dr->getdesc(dr, slot, &desc, &mt);
1482 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1483 	    ("%s:%d: fail", __func__, __LINE__));
1484 
1485 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1486 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1487 	    BWN_DMA_COOKIE(dr, slot));
1488 	if (error)
1489 		goto fail;
1490 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1491 	    BUS_DMASYNC_PREWRITE);
1492 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1493 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1494 	    BUS_DMASYNC_PREWRITE);
1495 
1496 	slot = bwn_dma_getslot(dr);
1497 	dr->getdesc(dr, slot, &desc, &mt);
1498 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1499 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1500 	mt->mt_m = m;
1501 	mt->mt_ni = ni;
1502 
1503 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1504 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1505 	if (error && error != EFBIG) {
1506 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1507 		    __func__, error);
1508 		goto fail;
1509 	}
1510 	if (error) {    /* error == EFBIG */
1511 		struct mbuf *m_new;
1512 
1513 		m_new = m_defrag(m, M_INTWAIT);
1514 		if (m_new == NULL) {
1515 			if_printf(ifp, "%s: can't defrag TX buffer\n",
1516 			    __func__);
1517 			error = ENOBUFS;
1518 			goto fail;
1519 		} else {
1520 			m = m_new;
1521 		}
1522 
1523 		mt->mt_m = m;
1524 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1525 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1526 		if (error) {
1527 			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1528 			    __func__, error);
1529 			goto fail;
1530 		}
1531 	}
1532 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1533 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1534 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1535 	    BUS_DMASYNC_PREWRITE);
1536 
1537 	/* XXX send after DTIM */
1538 
1539 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1540 	return (0);
1541 fail:
1542 	dr->dr_curslot = backup[0];
1543 	dr->dr_usedslot = backup[1];
1544 	return (error);
1545 #undef BWN_GET_TXHDRCACHE
1546 }
1547 
1548 static void
1549 bwn_watchdog(void *arg)
1550 {
1551 	struct bwn_softc *sc = arg;
1552 	struct ifnet *ifp = sc->sc_ifp;
1553 
1554 	wlan_serialize_enter();
1555 
1556 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1557 		if_printf(ifp, "device timeout\n");
1558 		ifp->if_oerrors++;
1559 	}
1560 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
1561 	wlan_serialize_exit();
1562 }
1563 
1564 static int
1565 bwn_attach_core(struct bwn_mac *mac)
1566 {
1567 	struct bwn_softc *sc = mac->mac_sc;
1568 	int error, have_bg = 0, have_a = 0;
1569 	uint32_t high;
1570 
1571 	KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1572 	    ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1573 
1574 	siba_powerup(sc->sc_dev, 0);
1575 
1576 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1577 	bwn_reset_core(mac,
1578 	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1579 	error = bwn_phy_getinfo(mac, high);
1580 	if (error)
1581 		goto fail;
1582 
1583 	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1584 	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1585 	if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1586 	    siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1587 	    siba_get_pci_device(sc->sc_dev) != 0x4324) {
1588 		have_a = have_bg = 0;
1589 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1590 			have_a = 1;
1591 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1592 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1593 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1594 			have_bg = 1;
1595 		else
1596 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1597 			    mac->mac_phy.type));
1598 	}
1599 	/* XXX turns off PHY A because it's not supported */
1600 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1601 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1602 		have_a = 0;
1603 		have_bg = 1;
1604 	}
1605 
1606 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1607 		mac->mac_phy.attach = bwn_phy_g_attach;
1608 		mac->mac_phy.detach = bwn_phy_g_detach;
1609 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1610 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1611 		mac->mac_phy.init = bwn_phy_g_init;
1612 		mac->mac_phy.exit = bwn_phy_g_exit;
1613 		mac->mac_phy.phy_read = bwn_phy_g_read;
1614 		mac->mac_phy.phy_write = bwn_phy_g_write;
1615 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1616 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1617 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1618 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1619 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1620 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1621 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1622 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1623 		mac->mac_phy.set_im = bwn_phy_g_im;
1624 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1625 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1626 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1627 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1628 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1629 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1630 		mac->mac_phy.init = bwn_phy_lp_init;
1631 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1632 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1633 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1634 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1635 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1636 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1637 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1638 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1639 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1640 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1641 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1642 	} else {
1643 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1644 		    mac->mac_phy.type);
1645 		error = ENXIO;
1646 		goto fail;
1647 	}
1648 
1649 	mac->mac_phy.gmode = have_bg;
1650 	if (mac->mac_phy.attach != NULL) {
1651 		error = mac->mac_phy.attach(mac);
1652 		if (error) {
1653 			device_printf(sc->sc_dev, "failed\n");
1654 			goto fail;
1655 		}
1656 	}
1657 
1658 	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1659 
1660 	error = bwn_chiptest(mac);
1661 	if (error)
1662 		goto fail;
1663 	error = bwn_setup_channels(mac, have_bg, have_a);
1664 	if (error) {
1665 		device_printf(sc->sc_dev, "failed to setup channels\n");
1666 		goto fail;
1667 	}
1668 
1669 	if (sc->sc_curmac == NULL)
1670 		sc->sc_curmac = mac;
1671 
1672 	wlan_assert_serialized();
1673 	wlan_serialize_exit();
1674 	error = bwn_dma_attach(mac);
1675 	wlan_serialize_enter();
1676 	if (error != 0) {
1677 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1678 		goto fail;
1679 	}
1680 
1681 	mac->mac_phy.switch_analog(mac, 0);
1682 
1683 	siba_dev_down(sc->sc_dev, 0);
1684 fail:
1685 	siba_powerdown(sc->sc_dev);
1686 	return (error);
1687 }
1688 
1689 static void
1690 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1691 {
1692 	struct bwn_softc *sc = mac->mac_sc;
1693 	uint32_t low, ctl;
1694 
1695 	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1696 
1697 	siba_dev_up(sc->sc_dev, flags);
1698 	DELAY(2000);
1699 
1700 	low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1701 	    ~BWN_TGSLOW_PHYRESET;
1702 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1703 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1704 	DELAY(1000);
1705 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1706 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1707 	DELAY(1000);
1708 
1709 	if (mac->mac_phy.switch_analog != NULL)
1710 		mac->mac_phy.switch_analog(mac, 1);
1711 
1712 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1713 	if (flags & BWN_TGSLOW_SUPPORT_G)
1714 		ctl |= BWN_MACCTL_GMODE;
1715 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1716 }
1717 
1718 static int
1719 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1720 {
1721 	struct bwn_phy *phy = &mac->mac_phy;
1722 	struct bwn_softc *sc = mac->mac_sc;
1723 	uint32_t tmp;
1724 
1725 	/* PHY */
1726 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1727 	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1728 	phy->rf_on = 1;
1729 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1730 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1731 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1732 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1733 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1734 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1735 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1736 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1737 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1738 		goto unsupphy;
1739 
1740 	/* RADIO */
1741 	if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1742 		if (siba_get_chiprev(sc->sc_dev) == 0)
1743 			tmp = 0x3205017f;
1744 		else if (siba_get_chiprev(sc->sc_dev) == 1)
1745 			tmp = 0x4205017f;
1746 		else
1747 			tmp = 0x5205017f;
1748 	} else {
1749 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1750 		tmp = BWN_READ_2(mac, BWN_RFDATALO);
1751 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1752 		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1753 	}
1754 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1755 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1756 	phy->rf_manuf = (tmp & 0x00000fff);
1757 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1758 		goto unsupradio;
1759 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1760 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1761 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1762 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1763 	    (phy->type == BWN_PHYTYPE_N &&
1764 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1765 	    (phy->type == BWN_PHYTYPE_LP &&
1766 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1767 		goto unsupradio;
1768 
1769 	return (0);
1770 unsupphy:
1771 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1772 	    "analog %#x)\n",
1773 	    phy->type, phy->rev, phy->analog);
1774 	return (ENXIO);
1775 unsupradio:
1776 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1777 	    "rev %#x)\n",
1778 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1779 	return (ENXIO);
1780 }
1781 
1782 static int
1783 bwn_chiptest(struct bwn_mac *mac)
1784 {
1785 #define	TESTVAL0	0x55aaaa55
1786 #define	TESTVAL1	0xaa5555aa
1787 	struct bwn_softc *sc = mac->mac_sc;
1788 	uint32_t v, backup;
1789 
1790 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1791 
1792 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1793 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1794 		goto error;
1795 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1796 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1797 		goto error;
1798 
1799 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1800 
1801 	if ((siba_get_revid(sc->sc_dev) >= 3) &&
1802 	    (siba_get_revid(sc->sc_dev) <= 10)) {
1803 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1804 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1805 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1806 			goto error;
1807 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1808 			goto error;
1809 	}
1810 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1811 
1812 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1813 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1814 		goto error;
1815 
1816 	return (0);
1817 error:
1818 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1819 	return (ENODEV);
1820 }
1821 
1822 #define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1823 #define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1824 
1825 static int
1826 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1827 {
1828 	struct bwn_softc *sc = mac->mac_sc;
1829 	struct ifnet *ifp = sc->sc_ifp;
1830 	struct ieee80211com *ic = ifp->if_l2com;
1831 
1832 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1833 	ic->ic_nchans = 0;
1834 
1835 	if (have_bg)
1836 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1837 		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1838 	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1839 		if (have_a)
1840 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1841 			    &ic->ic_nchans, &bwn_chantable_n,
1842 			    IEEE80211_CHAN_HTA);
1843 	} else {
1844 		if (have_a)
1845 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1846 			    &ic->ic_nchans, &bwn_chantable_a,
1847 			    IEEE80211_CHAN_A);
1848 	}
1849 
1850 	mac->mac_phy.supports_2ghz = have_bg;
1851 	mac->mac_phy.supports_5ghz = have_a;
1852 
1853 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1854 }
1855 
1856 static uint32_t
1857 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1858 {
1859 	uint32_t ret;
1860 
1861 	if (way == BWN_SHARED) {
1862 		KASSERT((offset & 0x0001) == 0,
1863 		    ("%s:%d warn", __func__, __LINE__));
1864 		if (offset & 0x0003) {
1865 			bwn_shm_ctlword(mac, way, offset >> 2);
1866 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1867 			ret <<= 16;
1868 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1869 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1870 			goto out;
1871 		}
1872 		offset >>= 2;
1873 	}
1874 	bwn_shm_ctlword(mac, way, offset);
1875 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1876 out:
1877 	return (ret);
1878 }
1879 
1880 static uint16_t
1881 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1882 {
1883 	uint16_t ret;
1884 
1885 	if (way == BWN_SHARED) {
1886 		KASSERT((offset & 0x0001) == 0,
1887 		    ("%s:%d warn", __func__, __LINE__));
1888 		if (offset & 0x0003) {
1889 			bwn_shm_ctlword(mac, way, offset >> 2);
1890 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1891 			goto out;
1892 		}
1893 		offset >>= 2;
1894 	}
1895 	bwn_shm_ctlword(mac, way, offset);
1896 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1897 out:
1898 
1899 	return (ret);
1900 }
1901 
1902 static void
1903 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1904     uint16_t offset)
1905 {
1906 	uint32_t control;
1907 
1908 	control = way;
1909 	control <<= 16;
1910 	control |= offset;
1911 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1912 }
1913 
1914 static void
1915 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1916     uint32_t value)
1917 {
1918 	if (way == BWN_SHARED) {
1919 		KASSERT((offset & 0x0001) == 0,
1920 		    ("%s:%d warn", __func__, __LINE__));
1921 		if (offset & 0x0003) {
1922 			bwn_shm_ctlword(mac, way, offset >> 2);
1923 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1924 				    (value >> 16) & 0xffff);
1925 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1926 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1927 			return;
1928 		}
1929 		offset >>= 2;
1930 	}
1931 	bwn_shm_ctlword(mac, way, offset);
1932 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1933 }
1934 
1935 static void
1936 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1937     uint16_t value)
1938 {
1939 	if (way == BWN_SHARED) {
1940 		KASSERT((offset & 0x0001) == 0,
1941 		    ("%s:%d warn", __func__, __LINE__));
1942 		if (offset & 0x0003) {
1943 			bwn_shm_ctlword(mac, way, offset >> 2);
1944 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1945 			return;
1946 		}
1947 		offset >>= 2;
1948 	}
1949 	bwn_shm_ctlword(mac, way, offset);
1950 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1951 }
1952 
1953 static void
1954 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1955     int txpow)
1956 {
1957 
1958 	c->ic_freq = freq;
1959 	c->ic_flags = flags;
1960 	c->ic_ieee = ieee;
1961 	c->ic_minpower = 0;
1962 	c->ic_maxpower = 2 * txpow;
1963 	c->ic_maxregpower = txpow;
1964 }
1965 
1966 static void
1967 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1968     const struct bwn_channelinfo *ci, int flags)
1969 {
1970 	struct ieee80211_channel *c;
1971 	int i;
1972 
1973 	c = &chans[*nchans];
1974 
1975 	for (i = 0; i < ci->nchannels; i++) {
1976 		const struct bwn_channel *hc;
1977 
1978 		hc = &ci->channels[i];
1979 		if (*nchans >= maxchans)
1980 			break;
1981 		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1982 		c++, (*nchans)++;
1983 		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1984 			/* g channel have a separate b-only entry */
1985 			if (*nchans >= maxchans)
1986 				break;
1987 			c[0] = c[-1];
1988 			c[-1].ic_flags = IEEE80211_CHAN_B;
1989 			c++, (*nchans)++;
1990 		}
1991 		if (flags == IEEE80211_CHAN_HTG) {
1992 			/* HT g channel have a separate g-only entry */
1993 			if (*nchans >= maxchans)
1994 				break;
1995 			c[-1].ic_flags = IEEE80211_CHAN_G;
1996 			c[0] = c[-1];
1997 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1998 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
1999 			c++, (*nchans)++;
2000 		}
2001 		if (flags == IEEE80211_CHAN_HTA) {
2002 			/* HT a channel have a separate a-only entry */
2003 			if (*nchans >= maxchans)
2004 				break;
2005 			c[-1].ic_flags = IEEE80211_CHAN_A;
2006 			c[0] = c[-1];
2007 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2008 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
2009 			c++, (*nchans)++;
2010 		}
2011 	}
2012 }
2013 
2014 static int
2015 bwn_phy_g_attach(struct bwn_mac *mac)
2016 {
2017 	struct bwn_softc *sc = mac->mac_sc;
2018 	struct bwn_phy *phy = &mac->mac_phy;
2019 	struct bwn_phy_g *pg = &phy->phy_g;
2020 	unsigned int i;
2021 	int16_t pab0, pab1, pab2;
2022 	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2023 	int8_t bg;
2024 
2025 	bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2026 	pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2027 	pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2028 	pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2029 
2030 	if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2031 		device_printf(sc->sc_dev, "not supported anymore\n");
2032 
2033 	pg->pg_flags = 0;
2034 	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2035 	    pab2 == -1) {
2036 		pg->pg_idletssi = 52;
2037 		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2038 		return (0);
2039 	}
2040 
2041 	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2042 	pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO);
2043 	for (i = 0; i < 64; i++) {
2044 		int32_t m1, m2, f, q, delta;
2045 		int8_t j = 0;
2046 
2047 		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2048 		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2049 		f = 256;
2050 
2051 		do {
2052 			if (j > 15) {
2053 				device_printf(sc->sc_dev,
2054 				    "failed to generate tssi2dBm\n");
2055 				kfree(pg->pg_tssi2dbm, M_DEVBUF);
2056 				return (ENOMEM);
2057 			}
2058 			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2059 			    f, 2048);
2060 			delta = abs(q - f);
2061 			f = q;
2062 			j++;
2063 		} while (delta >= 2);
2064 
2065 		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2066 		    128);
2067 	}
2068 
2069 	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2070 	return (0);
2071 }
2072 
2073 static void
2074 bwn_phy_g_detach(struct bwn_mac *mac)
2075 {
2076 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2077 
2078 	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2079 		kfree(pg->pg_tssi2dbm, M_DEVBUF);
2080 		pg->pg_tssi2dbm = NULL;
2081 	}
2082 	pg->pg_flags = 0;
2083 }
2084 
2085 static void
2086 bwn_phy_g_init_pre(struct bwn_mac *mac)
2087 {
2088 	struct bwn_phy *phy = &mac->mac_phy;
2089 	struct bwn_phy_g *pg = &phy->phy_g;
2090 	void *tssi2dbm;
2091 	int idletssi;
2092 	unsigned int i;
2093 
2094 	tssi2dbm = pg->pg_tssi2dbm;
2095 	idletssi = pg->pg_idletssi;
2096 
2097 	memset(pg, 0, sizeof(*pg));
2098 
2099 	pg->pg_tssi2dbm = tssi2dbm;
2100 	pg->pg_idletssi = idletssi;
2101 
2102 	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2103 
2104 	for (i = 0; i < N(pg->pg_nrssi); i++)
2105 		pg->pg_nrssi[i] = -1000;
2106 	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2107 		pg->pg_nrssi_lt[i] = i;
2108 	pg->pg_lofcal = 0xffff;
2109 	pg->pg_initval = 0xffff;
2110 	pg->pg_immode = BWN_IMMODE_NONE;
2111 	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2112 	pg->pg_avgtssi = 0xff;
2113 
2114 	pg->pg_loctl.tx_bias = 0xff;
2115 	TAILQ_INIT(&pg->pg_loctl.calib_list);
2116 }
2117 
2118 static int
2119 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2120 {
2121 	struct bwn_phy *phy = &mac->mac_phy;
2122 	struct bwn_phy_g *pg = &phy->phy_g;
2123 	struct bwn_softc *sc = mac->mac_sc;
2124 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2125 	static const struct bwn_rfatt rfatt0[] = {
2126 		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
2127 		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2128 		{ 3, 1 }, { 4, 1 }
2129 	};
2130 	static const struct bwn_rfatt rfatt1[] = {
2131 		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2132 		{ 14, 1 }
2133 	};
2134 	static const struct bwn_rfatt rfatt2[] = {
2135 		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2136 		{ 9, 1 }
2137 	};
2138 	static const struct bwn_bbatt bbatt_0[] = {
2139 		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2140 	};
2141 
2142 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2143 
2144 	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2145 		pg->pg_bbatt.att = 0;
2146 	else
2147 		pg->pg_bbatt.att = 2;
2148 
2149 	/* prepare Radio Attenuation */
2150 	pg->pg_rfatt.padmix = 0;
2151 
2152 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2153 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2154 		if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2155 			pg->pg_rfatt.att = 2;
2156 			goto done;
2157 		} else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2158 			pg->pg_rfatt.att = 3;
2159 			goto done;
2160 		}
2161 	}
2162 
2163 	if (phy->type == BWN_PHYTYPE_A) {
2164 		pg->pg_rfatt.att = 0x60;
2165 		goto done;
2166 	}
2167 
2168 	switch (phy->rf_ver) {
2169 	case 0x2050:
2170 		switch (phy->rf_rev) {
2171 		case 0:
2172 			pg->pg_rfatt.att = 5;
2173 			goto done;
2174 		case 1:
2175 			if (phy->type == BWN_PHYTYPE_G) {
2176 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2177 				    SIBA_BOARDVENDOR_BCM &&
2178 				    siba_get_pci_subdevice(sc->sc_dev) ==
2179 				    SIBA_BOARD_BCM4309G &&
2180 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2181 					pg->pg_rfatt.att = 3;
2182 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2183 				    SIBA_BOARDVENDOR_BCM &&
2184 				    siba_get_pci_subdevice(sc->sc_dev) ==
2185 				    SIBA_BOARD_BU4306)
2186 					pg->pg_rfatt.att = 3;
2187 				else
2188 					pg->pg_rfatt.att = 1;
2189 			} else {
2190 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2191 				    SIBA_BOARDVENDOR_BCM &&
2192 				    siba_get_pci_subdevice(sc->sc_dev) ==
2193 				    SIBA_BOARD_BCM4309G &&
2194 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2195 					pg->pg_rfatt.att = 7;
2196 				else
2197 					pg->pg_rfatt.att = 6;
2198 			}
2199 			goto done;
2200 		case 2:
2201 			if (phy->type == BWN_PHYTYPE_G) {
2202 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2203 				    SIBA_BOARDVENDOR_BCM &&
2204 				    siba_get_pci_subdevice(sc->sc_dev) ==
2205 				    SIBA_BOARD_BCM4309G &&
2206 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2207 					pg->pg_rfatt.att = 3;
2208 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2209 				    SIBA_BOARDVENDOR_BCM &&
2210 				    siba_get_pci_subdevice(sc->sc_dev) ==
2211 				    SIBA_BOARD_BU4306)
2212 					pg->pg_rfatt.att = 5;
2213 				else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2214 					pg->pg_rfatt.att = 4;
2215 				else
2216 					pg->pg_rfatt.att = 3;
2217 			} else
2218 				pg->pg_rfatt.att = 6;
2219 			goto done;
2220 		case 3:
2221 			pg->pg_rfatt.att = 5;
2222 			goto done;
2223 		case 4:
2224 		case 5:
2225 			pg->pg_rfatt.att = 1;
2226 			goto done;
2227 		case 6:
2228 		case 7:
2229 			pg->pg_rfatt.att = 5;
2230 			goto done;
2231 		case 8:
2232 			pg->pg_rfatt.att = 0xa;
2233 			pg->pg_rfatt.padmix = 1;
2234 			goto done;
2235 		case 9:
2236 		default:
2237 			pg->pg_rfatt.att = 5;
2238 			goto done;
2239 		}
2240 		break;
2241 	case 0x2053:
2242 		switch (phy->rf_rev) {
2243 		case 1:
2244 			pg->pg_rfatt.att = 6;
2245 			goto done;
2246 		}
2247 		break;
2248 	}
2249 	pg->pg_rfatt.att = 5;
2250 done:
2251 	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2252 
2253 	if (!bwn_has_hwpctl(mac)) {
2254 		lo->rfatt.array = rfatt0;
2255 		lo->rfatt.len = N(rfatt0);
2256 		lo->rfatt.min = 0;
2257 		lo->rfatt.max = 9;
2258 		goto genbbatt;
2259 	}
2260 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2261 		lo->rfatt.array = rfatt1;
2262 		lo->rfatt.len = N(rfatt1);
2263 		lo->rfatt.min = 0;
2264 		lo->rfatt.max = 14;
2265 		goto genbbatt;
2266 	}
2267 	lo->rfatt.array = rfatt2;
2268 	lo->rfatt.len = N(rfatt2);
2269 	lo->rfatt.min = 0;
2270 	lo->rfatt.max = 9;
2271 genbbatt:
2272 	lo->bbatt.array = bbatt_0;
2273 	lo->bbatt.len = N(bbatt_0);
2274 	lo->bbatt.min = 0;
2275 	lo->bbatt.max = 8;
2276 
2277 	BWN_READ_4(mac, BWN_MACCTL);
2278 	if (phy->rev == 1) {
2279 		phy->gmode = 0;
2280 		bwn_reset_core(mac, 0);
2281 		bwn_phy_g_init_sub(mac);
2282 		phy->gmode = 1;
2283 		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2284 	}
2285 	return (0);
2286 }
2287 
2288 static uint16_t
2289 bwn_phy_g_txctl(struct bwn_mac *mac)
2290 {
2291 	struct bwn_phy *phy = &mac->mac_phy;
2292 
2293 	if (phy->rf_ver != 0x2050)
2294 		return (0);
2295 	if (phy->rf_rev == 1)
2296 		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2297 	if (phy->rf_rev < 6)
2298 		return (BWN_TXCTL_PA2DB);
2299 	if (phy->rf_rev == 8)
2300 		return (BWN_TXCTL_TXMIX);
2301 	return (0);
2302 }
2303 
2304 static int
2305 bwn_phy_g_init(struct bwn_mac *mac)
2306 {
2307 
2308 	bwn_phy_g_init_sub(mac);
2309 	return (0);
2310 }
2311 
2312 static void
2313 bwn_phy_g_exit(struct bwn_mac *mac)
2314 {
2315 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2316 	struct bwn_lo_calib *cal, *tmp;
2317 
2318 	if (lo == NULL)
2319 		return;
2320 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2321 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2322 		kfree(cal, M_DEVBUF);
2323 	}
2324 }
2325 
2326 static uint16_t
2327 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2328 {
2329 
2330 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2331 	return (BWN_READ_2(mac, BWN_PHYDATA));
2332 }
2333 
2334 static void
2335 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2336 {
2337 
2338 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2339 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
2340 }
2341 
2342 static uint16_t
2343 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2344 {
2345 
2346 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2347 	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2348 	return (BWN_READ_2(mac, BWN_RFDATALO));
2349 }
2350 
2351 static void
2352 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2353 {
2354 
2355 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2356 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
2357 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
2358 }
2359 
2360 static int
2361 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2362 {
2363 
2364 	return (mac->mac_phy.rev >= 6);
2365 }
2366 
2367 static void
2368 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2369 {
2370 	struct bwn_phy *phy = &mac->mac_phy;
2371 	struct bwn_phy_g *pg = &phy->phy_g;
2372 	unsigned int channel;
2373 	uint16_t rfover, rfoverval;
2374 
2375 	if (on) {
2376 		if (phy->rf_on)
2377 			return;
2378 
2379 		BWN_PHY_WRITE(mac, 0x15, 0x8000);
2380 		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2381 		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2382 		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2383 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2384 			    pg->pg_radioctx_over);
2385 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2386 			    pg->pg_radioctx_overval);
2387 			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2388 		}
2389 		channel = phy->chan;
2390 		bwn_phy_g_switch_chan(mac, 6, 1);
2391 		bwn_phy_g_switch_chan(mac, channel, 0);
2392 		return;
2393 	}
2394 
2395 	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2396 	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2397 	pg->pg_radioctx_over = rfover;
2398 	pg->pg_radioctx_overval = rfoverval;
2399 	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2400 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2401 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2402 }
2403 
2404 static int
2405 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2406 {
2407 
2408 	if ((newchan < 1) || (newchan > 14))
2409 		return (EINVAL);
2410 	bwn_phy_g_switch_chan(mac, newchan, 0);
2411 
2412 	return (0);
2413 }
2414 
2415 static uint32_t
2416 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2417 {
2418 
2419 	return (1);
2420 }
2421 
2422 static void
2423 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2424 {
2425 	struct bwn_phy *phy = &mac->mac_phy;
2426 	uint64_t hf;
2427 	int autodiv = 0;
2428 	uint16_t tmp;
2429 
2430 	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2431 		autodiv = 1;
2432 
2433 	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2434 	bwn_hf_write(mac, hf);
2435 
2436 	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2437 	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2438 	    ((autodiv ? BWN_ANTAUTO1 : antenna)
2439 		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
2440 
2441 	if (autodiv) {
2442 		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2443 		if (antenna == BWN_ANTAUTO1)
2444 			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2445 		else
2446 			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2447 		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2448 	}
2449 	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2450 	if (autodiv)
2451 		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2452 	else
2453 		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2454 	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2455 	if (phy->rev >= 2) {
2456 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2457 		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2458 		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2459 		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2460 		    0x15);
2461 		if (phy->rev == 2)
2462 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2463 		else
2464 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2465 			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2466 			    8);
2467 	}
2468 	if (phy->rev >= 6)
2469 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2470 
2471 	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2472 	bwn_hf_write(mac, hf);
2473 }
2474 
2475 static int
2476 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2477 {
2478 	struct bwn_phy *phy = &mac->mac_phy;
2479 	struct bwn_phy_g *pg = &phy->phy_g;
2480 
2481 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2482 	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2483 
2484 	if (phy->rev == 0 || !phy->gmode)
2485 		return (ENODEV);
2486 
2487 	pg->pg_aci_wlan_automatic = 0;
2488 	return (0);
2489 }
2490 
2491 static int
2492 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2493 {
2494 	struct bwn_phy *phy = &mac->mac_phy;
2495 	struct bwn_phy_g *pg = &phy->phy_g;
2496 	struct bwn_softc *sc = mac->mac_sc;
2497 	unsigned int tssi;
2498 	int cck, ofdm;
2499 	int power;
2500 	int rfatt, bbatt;
2501 	unsigned int max;
2502 
2503 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2504 
2505 	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2506 	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2507 	if (cck < 0 && ofdm < 0) {
2508 		if (ignore_tssi == 0)
2509 			return (BWN_TXPWR_RES_DONE);
2510 		cck = 0;
2511 		ofdm = 0;
2512 	}
2513 	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2514 	if (pg->pg_avgtssi != 0xff)
2515 		tssi = (tssi + pg->pg_avgtssi) / 2;
2516 	pg->pg_avgtssi = tssi;
2517 	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2518 
2519 	max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2520 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2521 		max -= 3;
2522 	if (max >= 120) {
2523 		device_printf(sc->sc_dev, "invalid max TX-power value\n");
2524 		max = 80;
2525 		siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2526 	}
2527 
2528 	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2529 	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2530 	     tssi, 0x00), 0x3f)]);
2531 	if (power == 0)
2532 		return (BWN_TXPWR_RES_DONE);
2533 
2534 	rfatt = -((power + 7) / 8);
2535 	bbatt = (-(power / 2)) - (4 * rfatt);
2536 	if ((rfatt == 0) && (bbatt == 0))
2537 		return (BWN_TXPWR_RES_DONE);
2538 	pg->pg_bbatt_delta = bbatt;
2539 	pg->pg_rfatt_delta = rfatt;
2540 	return (BWN_TXPWR_RES_NEED_ADJUST);
2541 }
2542 
2543 static void
2544 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2545 {
2546 	struct bwn_phy *phy = &mac->mac_phy;
2547 	struct bwn_phy_g *pg = &phy->phy_g;
2548 	struct bwn_softc *sc = mac->mac_sc;
2549 	int rfatt, bbatt;
2550 	uint8_t txctl;
2551 
2552 	bwn_mac_suspend(mac);
2553 
2554 	bbatt = pg->pg_bbatt.att;
2555 	bbatt += pg->pg_bbatt_delta;
2556 	rfatt = pg->pg_rfatt.att;
2557 	rfatt += pg->pg_rfatt_delta;
2558 
2559 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2560 	txctl = pg->pg_txctl;
2561 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2562 		if (rfatt <= 1) {
2563 			if (txctl == 0) {
2564 				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2565 				rfatt += 2;
2566 				bbatt += 2;
2567 			} else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2568 			    BWN_BFL_PACTRL) {
2569 				bbatt += 4 * (rfatt - 2);
2570 				rfatt = 2;
2571 			}
2572 		} else if (rfatt > 4 && txctl) {
2573 			txctl = 0;
2574 			if (bbatt < 3) {
2575 				rfatt -= 3;
2576 				bbatt += 2;
2577 			} else {
2578 				rfatt -= 2;
2579 				bbatt -= 2;
2580 			}
2581 		}
2582 	}
2583 	pg->pg_txctl = txctl;
2584 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2585 	pg->pg_rfatt.att = rfatt;
2586 	pg->pg_bbatt.att = bbatt;
2587 
2588 	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2589 
2590 	bwn_phy_lock(mac);
2591 	bwn_rf_lock(mac);
2592 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2593 	    pg->pg_txctl);
2594 	bwn_rf_unlock(mac);
2595 	bwn_phy_unlock(mac);
2596 
2597 	bwn_mac_enable(mac);
2598 }
2599 
2600 static void
2601 bwn_phy_g_task_15s(struct bwn_mac *mac)
2602 {
2603 	struct bwn_phy *phy = &mac->mac_phy;
2604 	struct bwn_phy_g *pg = &phy->phy_g;
2605 	struct bwn_softc *sc = mac->mac_sc;
2606 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2607 	unsigned long expire, now;
2608 	struct bwn_lo_calib *cal, *tmp;
2609 	uint8_t expired = 0;
2610 
2611 	bwn_mac_suspend(mac);
2612 
2613 	if (lo == NULL)
2614 		goto fail;
2615 
2616 	BWN_GETTIME(now);
2617 	if (bwn_has_hwpctl(mac)) {
2618 		expire = now - BWN_LO_PWRVEC_EXPIRE;
2619 		if (time_before(lo->pwr_vec_read_time, expire)) {
2620 			bwn_lo_get_powervector(mac);
2621 			bwn_phy_g_dc_lookup_init(mac, 0);
2622 		}
2623 		goto fail;
2624 	}
2625 
2626 	expire = now - BWN_LO_CALIB_EXPIRE;
2627 	TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2628 		if (!time_before(cal->calib_time, expire))
2629 			continue;
2630 		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2631 		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2632 			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2633 			expired = 1;
2634 		}
2635 
2636 		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2637 		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2638 		    cal->ctl.i, cal->ctl.q);
2639 
2640 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2641 		kfree(cal, M_DEVBUF);
2642 	}
2643 	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2644 		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2645 		    &pg->pg_rfatt);
2646 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
2647 			device_printf(sc->sc_dev,
2648 			    "failed to recalibrate LO\n");
2649 			goto fail;
2650 		}
2651 		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2652 		bwn_lo_write(mac, &cal->ctl);
2653 	}
2654 
2655 fail:
2656 	bwn_mac_enable(mac);
2657 }
2658 
2659 static void
2660 bwn_phy_g_task_60s(struct bwn_mac *mac)
2661 {
2662 	struct bwn_phy *phy = &mac->mac_phy;
2663 	struct bwn_softc *sc = mac->mac_sc;
2664 	uint8_t old = phy->chan;
2665 
2666 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2667 		return;
2668 
2669 	bwn_mac_suspend(mac);
2670 	bwn_nrssi_slope_11g(mac);
2671 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2672 		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2673 		bwn_switch_channel(mac, old);
2674 	}
2675 	bwn_mac_enable(mac);
2676 }
2677 
2678 static void
2679 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2680 {
2681 
2682 	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2683 }
2684 
2685 static int
2686 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2687 	const struct ieee80211_bpf_params *params)
2688 {
2689 	struct ieee80211com *ic = ni->ni_ic;
2690 	struct ifnet *ifp = ic->ic_ifp;
2691 	struct bwn_softc *sc = ifp->if_softc;
2692 	struct bwn_mac *mac = sc->sc_curmac;
2693 
2694 	if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2695 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
2696 		ieee80211_free_node(ni);
2697 		m_freem(m);
2698 		return (ENETDOWN);
2699 	}
2700 
2701 	if (bwn_tx_isfull(sc, m)) {
2702 		ieee80211_free_node(ni);
2703 		m_freem(m);
2704 		ifp->if_oerrors++;
2705 		return (ENOBUFS);
2706 	}
2707 
2708 	if (bwn_tx_start(sc, ni, m) != 0) {
2709 		if (ni != NULL)
2710 			ieee80211_free_node(ni);
2711 		ifp->if_oerrors++;
2712 	}
2713 	sc->sc_watchdog_timer = 5;
2714 	return (0);
2715 }
2716 
2717 /*
2718  * Callback from the 802.11 layer to update the slot time
2719  * based on the current setting.  We use it to notify the
2720  * firmware of ERP changes and the f/w takes care of things
2721  * like slot time and preamble.
2722  */
2723 static void
2724 bwn_updateslot(struct ifnet *ifp)
2725 {
2726 	struct bwn_softc *sc = ifp->if_softc;
2727 	struct ieee80211com *ic = ifp->if_l2com;
2728 	struct bwn_mac *mac;
2729 
2730 	if (ifp->if_flags & IFF_RUNNING) {
2731 		mac = (struct bwn_mac *)sc->sc_curmac;
2732 		bwn_set_slot_time(mac,
2733 		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2734 	}
2735 }
2736 
2737 /*
2738  * Callback from the 802.11 layer after a promiscuous mode change.
2739  * Note this interface does not check the operating mode as this
2740  * is an internal callback and we are expected to honor the current
2741  * state (e.g. this is used for setting the interface in promiscuous
2742  * mode when operating in hostap mode to do ACS).
2743  */
2744 static void
2745 bwn_update_promisc(struct ifnet *ifp)
2746 {
2747 	struct bwn_softc *sc = ifp->if_softc;
2748 	struct bwn_mac *mac = sc->sc_curmac;
2749 
2750 	mac = sc->sc_curmac;
2751 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2752 		if (ifp->if_flags & IFF_PROMISC)
2753 			sc->sc_filters |= BWN_MACCTL_PROMISC;
2754 		else
2755 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2756 		bwn_set_opmode(mac);
2757 	}
2758 }
2759 
2760 /*
2761  * Callback from the 802.11 layer to update WME parameters.
2762  */
2763 static int
2764 bwn_wme_update(struct ieee80211com *ic)
2765 {
2766 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2767 	struct bwn_mac *mac = sc->sc_curmac;
2768 	struct wmeParams *wmep;
2769 	int i;
2770 
2771 	mac = sc->sc_curmac;
2772 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2773 		bwn_mac_suspend(mac);
2774 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
2775 			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2776 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2777 		}
2778 		bwn_mac_enable(mac);
2779 	}
2780 	return (0);
2781 }
2782 
2783 static void
2784 bwn_scan_start(struct ieee80211com *ic)
2785 {
2786 	struct ifnet *ifp = ic->ic_ifp;
2787 	struct bwn_softc *sc = ifp->if_softc;
2788 	struct bwn_mac *mac;
2789 
2790 	mac = sc->sc_curmac;
2791 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2792 		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2793 		bwn_set_opmode(mac);
2794 		/* disable CFP update during scan */
2795 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2796 	}
2797 }
2798 
2799 static void
2800 bwn_scan_end(struct ieee80211com *ic)
2801 {
2802 	struct ifnet *ifp = ic->ic_ifp;
2803 	struct bwn_softc *sc = ifp->if_softc;
2804 	struct bwn_mac *mac;
2805 
2806 	mac = sc->sc_curmac;
2807 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2808 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2809 		bwn_set_opmode(mac);
2810 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2811 	}
2812 }
2813 
2814 static void
2815 bwn_set_channel(struct ieee80211com *ic)
2816 {
2817 	struct ifnet *ifp = ic->ic_ifp;
2818 	struct bwn_softc *sc = ifp->if_softc;
2819 	struct bwn_mac *mac = sc->sc_curmac;
2820 	struct bwn_phy *phy = &mac->mac_phy;
2821 	int chan, error;
2822 
2823 	error = bwn_switch_band(sc, ic->ic_curchan);
2824 	if (error)
2825 		goto fail;
2826 	bwn_mac_suspend(mac);
2827 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2828 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2829 	if (chan != phy->chan)
2830 		bwn_switch_channel(mac, chan);
2831 
2832 	/* TX power level */
2833 	if (ic->ic_curchan->ic_maxpower != 0 &&
2834 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
2835 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2836 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2837 		    BWN_TXPWR_IGNORE_TSSI);
2838 	}
2839 
2840 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2841 	if (phy->set_antenna)
2842 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2843 
2844 	if (sc->sc_rf_enabled != phy->rf_on) {
2845 		if (sc->sc_rf_enabled) {
2846 			bwn_rf_turnon(mac);
2847 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2848 				device_printf(sc->sc_dev,
2849 				    "please turn on the RF switch\n");
2850 		} else
2851 			bwn_rf_turnoff(mac);
2852 	}
2853 
2854 	bwn_mac_enable(mac);
2855 
2856 fail:
2857 	/*
2858 	 * Setup radio tap channel freq and flags
2859 	 */
2860 	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2861 		htole16(ic->ic_curchan->ic_freq);
2862 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2863 		htole16(ic->ic_curchan->ic_flags & 0xffff);
2864 }
2865 
2866 static struct ieee80211vap *
2867 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2868     enum ieee80211_opmode opmode, int flags,
2869     const uint8_t bssid[IEEE80211_ADDR_LEN],
2870     const uint8_t mac0[IEEE80211_ADDR_LEN])
2871 {
2872 	struct ifnet *ifp = ic->ic_ifp;
2873 	struct bwn_softc *sc = ifp->if_softc;
2874 	struct ieee80211vap *vap;
2875 	struct bwn_vap *bvp;
2876 	uint8_t mac[IEEE80211_ADDR_LEN];
2877 
2878 	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
2879 		return NULL;
2880 
2881 	IEEE80211_ADDR_COPY(mac, mac0);
2882 	switch (opmode) {
2883 	case IEEE80211_M_HOSTAP:
2884 	case IEEE80211_M_MBSS:
2885 	case IEEE80211_M_STA:
2886 	case IEEE80211_M_WDS:
2887 	case IEEE80211_M_MONITOR:
2888 	case IEEE80211_M_IBSS:
2889 	case IEEE80211_M_AHDEMO:
2890 		break;
2891 	default:
2892 		return (NULL);
2893 	}
2894 
2895 	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2896 
2897 	bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap),
2898 	    M_80211_VAP, M_INTWAIT | M_ZERO);
2899 	vap = &bvp->bv_vap;
2900 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2901 	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2902 	/* override with driver methods */
2903 	bvp->bv_newstate = vap->iv_newstate;
2904 	vap->iv_newstate = bwn_newstate;
2905 
2906 	/* override max aid so sta's cannot assoc when we're out of sta id's */
2907 	vap->iv_max_aid = BWN_STAID_MAX;
2908 
2909 	ieee80211_ratectl_init(vap);
2910 
2911 	/* complete setup */
2912 	ieee80211_vap_attach(vap, ieee80211_media_change,
2913 	    ieee80211_media_status);
2914 	ic->ic_opmode = opmode;
2915 	return (vap);
2916 }
2917 
2918 static void
2919 bwn_vap_delete(struct ieee80211vap *vap)
2920 {
2921 	struct bwn_vap *bvp = BWN_VAP(vap);
2922 
2923 	ieee80211_ratectl_deinit(vap);
2924 	ieee80211_vap_detach(vap);
2925 	kfree(bvp, M_80211_VAP);
2926 }
2927 
2928 static void
2929 bwn_init(void *arg)
2930 {
2931 	struct bwn_softc *sc = arg;
2932 	struct ifnet *ifp = sc->sc_ifp;
2933 	struct ieee80211com *ic = ifp->if_l2com;
2934 	int error = 0;
2935 
2936 	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2937 		__func__, ifp->if_flags);
2938 
2939 	wlan_assert_serialized();
2940 	error = bwn_init_locked(sc);
2941 
2942 	if (error == 0)
2943 		ieee80211_start_all(ic);	/* start all vap's */
2944 }
2945 
2946 static int
2947 bwn_init_locked(struct bwn_softc *sc)
2948 {
2949 	struct bwn_mac *mac;
2950 	struct ifnet *ifp = sc->sc_ifp;
2951 	int error;
2952 
2953 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2954 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2955 	sc->sc_filters = 0;
2956 	bwn_wme_clear(sc);
2957 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2958 	sc->sc_rf_enabled = 1;
2959 
2960 	mac = sc->sc_curmac;
2961 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2962 		error = bwn_core_init(mac);
2963 		if (error != 0)
2964 			return (error);
2965 	}
2966 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
2967 		bwn_core_start(mac);
2968 
2969 	bwn_set_opmode(mac);
2970 	bwn_set_pretbtt(mac);
2971 	bwn_spu_setdelay(mac, 0);
2972 	bwn_set_macaddr(mac);
2973 
2974 	ifp->if_flags |= IFF_RUNNING;
2975 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2976 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2977 
2978 	return (0);
2979 }
2980 
2981 static void
2982 bwn_stop(struct bwn_softc *sc, int statechg)
2983 {
2984 
2985 	wlan_assert_serialized();
2986 	bwn_stop_locked(sc, statechg);
2987 }
2988 
2989 static void
2990 bwn_stop_locked(struct bwn_softc *sc, int statechg)
2991 {
2992 	struct bwn_mac *mac = sc->sc_curmac;
2993 	struct ifnet *ifp = sc->sc_ifp;
2994 
2995 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2996 		/* XXX FIXME opmode not based on VAP */
2997 		bwn_set_opmode(mac);
2998 		bwn_set_macaddr(mac);
2999 	}
3000 
3001 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3002 		bwn_core_stop(mac);
3003 
3004 	callout_stop(&sc->sc_led_blink_ch);
3005 	sc->sc_led_blinking = 0;
3006 
3007 	bwn_core_exit(mac);
3008 	sc->sc_rf_enabled = 0;
3009 
3010 	ifp->if_flags &= ~IFF_RUNNING;
3011 	ifq_clr_oactive(&ifp->if_snd);
3012 }
3013 
3014 static void
3015 bwn_wme_clear(struct bwn_softc *sc)
3016 {
3017 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
3018 	struct wmeParams *p;
3019 	unsigned int i;
3020 
3021 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3022 	    ("%s:%d: fail", __func__, __LINE__));
3023 
3024 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
3025 		p = &(sc->sc_wmeParams[i]);
3026 
3027 		switch (bwn_wme_shm_offsets[i]) {
3028 		case BWN_WME_VOICE:
3029 			p->wmep_txopLimit = 0;
3030 			p->wmep_aifsn = 2;
3031 			/* XXX FIXME: log2(cwmin) */
3032 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3033 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3034 			break;
3035 		case BWN_WME_VIDEO:
3036 			p->wmep_txopLimit = 0;
3037 			p->wmep_aifsn = 2;
3038 			/* XXX FIXME: log2(cwmin) */
3039 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3040 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3041 			break;
3042 		case BWN_WME_BESTEFFORT:
3043 			p->wmep_txopLimit = 0;
3044 			p->wmep_aifsn = 3;
3045 			/* XXX FIXME: log2(cwmin) */
3046 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3047 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3048 			break;
3049 		case BWN_WME_BACKGROUND:
3050 			p->wmep_txopLimit = 0;
3051 			p->wmep_aifsn = 7;
3052 			/* XXX FIXME: log2(cwmin) */
3053 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3054 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3055 			break;
3056 		default:
3057 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3058 		}
3059 	}
3060 }
3061 
3062 static int
3063 bwn_core_init(struct bwn_mac *mac)
3064 {
3065 	struct bwn_softc *sc = mac->mac_sc;
3066 	uint64_t hf;
3067 	int error;
3068 
3069 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3070 	    ("%s:%d: fail", __func__, __LINE__));
3071 
3072 	siba_powerup(sc->sc_dev, 0);
3073 	if (!siba_dev_isup(sc->sc_dev))
3074 		bwn_reset_core(mac,
3075 		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3076 
3077 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3078 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3079 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3080 	BWN_GETTIME(mac->mac_phy.nexttime);
3081 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3082 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3083 	mac->mac_stats.link_noise = -95;
3084 	mac->mac_reason_intr = 0;
3085 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
3086 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3087 #ifdef BWN_DEBUG
3088 	if (sc->sc_debug & BWN_DEBUG_XMIT)
3089 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3090 #endif
3091 	mac->mac_suspended = 1;
3092 	mac->mac_task_state = 0;
3093 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3094 
3095 	mac->mac_phy.init_pre(mac);
3096 
3097 	siba_pcicore_intr(sc->sc_dev);
3098 
3099 	siba_fix_imcfglobug(sc->sc_dev);
3100 	bwn_bt_disable(mac);
3101 	if (mac->mac_phy.prepare_hw) {
3102 		error = mac->mac_phy.prepare_hw(mac);
3103 		if (error)
3104 			goto fail0;
3105 	}
3106 	error = bwn_chip_init(mac);
3107 	if (error)
3108 		goto fail0;
3109 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3110 	    siba_get_revid(sc->sc_dev));
3111 	hf = bwn_hf_read(mac);
3112 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3113 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3114 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3115 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3116 		if (mac->mac_phy.rev == 1)
3117 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3118 	}
3119 	if (mac->mac_phy.rf_ver == 0x2050) {
3120 		if (mac->mac_phy.rf_rev < 6)
3121 			hf |= BWN_HF_FORCE_VCO_RECALC;
3122 		if (mac->mac_phy.rf_rev == 6)
3123 			hf |= BWN_HF_4318_TSSI;
3124 	}
3125 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3126 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3127 	if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3128 	    (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3129 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3130 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3131 	bwn_hf_write(mac, hf);
3132 
3133 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3134 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3135 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3136 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3137 
3138 	bwn_rate_init(mac);
3139 	bwn_set_phytxctl(mac);
3140 
3141 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3142 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3143 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3144 
3145 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3146 		bwn_pio_init(mac);
3147 	else
3148 		bwn_dma_init(mac);
3149 	bwn_wme_init(mac);
3150 	bwn_spu_setdelay(mac, 1);
3151 	bwn_bt_enable(mac);
3152 
3153 	siba_powerup(sc->sc_dev,
3154 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3155 	bwn_set_macaddr(mac);
3156 	bwn_crypt_init(mac);
3157 
3158 	/* XXX LED initializatin */
3159 
3160 	mac->mac_status = BWN_MAC_STATUS_INITED;
3161 
3162 	return (error);
3163 
3164 fail0:
3165 	siba_powerdown(sc->sc_dev);
3166 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3167 	    ("%s:%d: fail", __func__, __LINE__));
3168 	return (error);
3169 }
3170 
3171 static void
3172 bwn_core_start(struct bwn_mac *mac)
3173 {
3174 	struct bwn_softc *sc = mac->mac_sc;
3175 	uint32_t tmp;
3176 
3177 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3178 	    ("%s:%d: fail", __func__, __LINE__));
3179 
3180 	if (siba_get_revid(sc->sc_dev) < 5)
3181 		return;
3182 
3183 	while (1) {
3184 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3185 		if (!(tmp & 0x00000001))
3186 			break;
3187 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3188 	}
3189 
3190 	bwn_mac_enable(mac);
3191 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3192 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3193 
3194 	mac->mac_status = BWN_MAC_STATUS_STARTED;
3195 }
3196 
3197 static void
3198 bwn_core_exit(struct bwn_mac *mac)
3199 {
3200 	struct bwn_softc *sc = mac->mac_sc;
3201 	uint32_t macctl;
3202 
3203 	wlan_assert_serialized();
3204 
3205 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3206 	    ("%s:%d: fail", __func__, __LINE__));
3207 
3208 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
3209 		return;
3210 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
3211 
3212 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3213 	macctl &= ~BWN_MACCTL_MCODE_RUN;
3214 	macctl |= BWN_MACCTL_MCODE_JMP0;
3215 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3216 
3217 	bwn_dma_stop(mac);
3218 	bwn_pio_stop(mac);
3219 	bwn_chip_exit(mac);
3220 	mac->mac_phy.switch_analog(mac, 0);
3221 	siba_dev_down(sc->sc_dev, 0);
3222 	siba_powerdown(sc->sc_dev);
3223 }
3224 
3225 static void
3226 bwn_bt_disable(struct bwn_mac *mac)
3227 {
3228 	struct bwn_softc *sc = mac->mac_sc;
3229 
3230 	(void)sc;
3231 	/* XXX do nothing yet */
3232 }
3233 
3234 static int
3235 bwn_chip_init(struct bwn_mac *mac)
3236 {
3237 	struct bwn_softc *sc = mac->mac_sc;
3238 	struct bwn_phy *phy = &mac->mac_phy;
3239 	uint32_t macctl;
3240 	int error;
3241 
3242 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3243 	if (phy->gmode)
3244 		macctl |= BWN_MACCTL_GMODE;
3245 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3246 
3247 	error = bwn_fw_fillinfo(mac);
3248 	if (error)
3249 		return (error);
3250 	error = bwn_fw_loaducode(mac);
3251 	if (error)
3252 		return (error);
3253 
3254 	error = bwn_gpio_init(mac);
3255 	if (error)
3256 		return (error);
3257 
3258 	error = bwn_fw_loadinitvals(mac);
3259 	if (error) {
3260 		siba_gpio_set(sc->sc_dev, 0);
3261 		return (error);
3262 	}
3263 	phy->switch_analog(mac, 1);
3264 	error = bwn_phy_init(mac);
3265 	if (error) {
3266 		siba_gpio_set(sc->sc_dev, 0);
3267 		return (error);
3268 	}
3269 	if (phy->set_im)
3270 		phy->set_im(mac, BWN_IMMODE_NONE);
3271 	if (phy->set_antenna)
3272 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
3273 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3274 
3275 	if (phy->type == BWN_PHYTYPE_B)
3276 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3277 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
3278 	if (siba_get_revid(sc->sc_dev) < 5)
3279 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
3280 
3281 	BWN_WRITE_4(mac, BWN_MACCTL,
3282 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3283 	BWN_WRITE_4(mac, BWN_MACCTL,
3284 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3285 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3286 
3287 	bwn_set_opmode(mac);
3288 	if (siba_get_revid(sc->sc_dev) < 3) {
3289 		BWN_WRITE_2(mac, 0x060e, 0x0000);
3290 		BWN_WRITE_2(mac, 0x0610, 0x8000);
3291 		BWN_WRITE_2(mac, 0x0604, 0x0000);
3292 		BWN_WRITE_2(mac, 0x0606, 0x0200);
3293 	} else {
3294 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
3295 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
3296 	}
3297 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3298 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00);
3299 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3300 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3301 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3302 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3303 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3304 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3305 	    siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3306 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3307 	return (error);
3308 }
3309 
3310 /* read hostflags */
3311 static uint64_t
3312 bwn_hf_read(struct bwn_mac *mac)
3313 {
3314 	uint64_t ret;
3315 
3316 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3317 	ret <<= 16;
3318 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3319 	ret <<= 16;
3320 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3321 	return (ret);
3322 }
3323 
3324 static void
3325 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3326 {
3327 
3328 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3329 	    (value & 0x00000000ffffull));
3330 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3331 	    (value & 0x0000ffff0000ull) >> 16);
3332 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3333 	    (value & 0xffff00000000ULL) >> 32);
3334 }
3335 
3336 static void
3337 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3338 {
3339 
3340 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3341 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3342 }
3343 
3344 static void
3345 bwn_rate_init(struct bwn_mac *mac)
3346 {
3347 
3348 	switch (mac->mac_phy.type) {
3349 	case BWN_PHYTYPE_A:
3350 	case BWN_PHYTYPE_G:
3351 	case BWN_PHYTYPE_LP:
3352 	case BWN_PHYTYPE_N:
3353 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3354 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3355 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3356 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3357 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3358 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3359 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3360 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
3361 			break;
3362 		/* FALLTHROUGH */
3363 	case BWN_PHYTYPE_B:
3364 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3365 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3366 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3367 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3368 		break;
3369 	default:
3370 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3371 	}
3372 }
3373 
3374 static void
3375 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3376 {
3377 	uint16_t offset;
3378 
3379 	if (ofdm) {
3380 		offset = 0x480;
3381 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3382 	} else {
3383 		offset = 0x4c0;
3384 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3385 	}
3386 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3387 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
3388 }
3389 
3390 static uint8_t
3391 bwn_plcp_getcck(const uint8_t bitrate)
3392 {
3393 
3394 	switch (bitrate) {
3395 	case BWN_CCK_RATE_1MB:
3396 		return (0x0a);
3397 	case BWN_CCK_RATE_2MB:
3398 		return (0x14);
3399 	case BWN_CCK_RATE_5MB:
3400 		return (0x37);
3401 	case BWN_CCK_RATE_11MB:
3402 		return (0x6e);
3403 	}
3404 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3405 	return (0);
3406 }
3407 
3408 static uint8_t
3409 bwn_plcp_getofdm(const uint8_t bitrate)
3410 {
3411 
3412 	switch (bitrate) {
3413 	case BWN_OFDM_RATE_6MB:
3414 		return (0xb);
3415 	case BWN_OFDM_RATE_9MB:
3416 		return (0xf);
3417 	case BWN_OFDM_RATE_12MB:
3418 		return (0xa);
3419 	case BWN_OFDM_RATE_18MB:
3420 		return (0xe);
3421 	case BWN_OFDM_RATE_24MB:
3422 		return (0x9);
3423 	case BWN_OFDM_RATE_36MB:
3424 		return (0xd);
3425 	case BWN_OFDM_RATE_48MB:
3426 		return (0x8);
3427 	case BWN_OFDM_RATE_54MB:
3428 		return (0xc);
3429 	}
3430 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3431 	return (0);
3432 }
3433 
3434 static void
3435 bwn_set_phytxctl(struct bwn_mac *mac)
3436 {
3437 	uint16_t ctl;
3438 
3439 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3440 	    BWN_TX_PHY_TXPWR);
3441 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3442 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3443 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3444 }
3445 
3446 static void
3447 bwn_pio_init(struct bwn_mac *mac)
3448 {
3449 	struct bwn_pio *pio = &mac->mac_method.pio;
3450 
3451 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3452 	    & ~BWN_MACCTL_BIGENDIAN);
3453 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3454 
3455 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3456 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3457 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3458 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3459 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3460 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3461 }
3462 
3463 static void
3464 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3465     int index)
3466 {
3467 	struct bwn_pio_txpkt *tp;
3468 	struct bwn_softc *sc = mac->mac_sc;
3469 	unsigned int i;
3470 
3471 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3472 	tq->tq_index = index;
3473 
3474 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3475 	if (siba_get_revid(sc->sc_dev) >= 8)
3476 		tq->tq_size = 1920;
3477 	else {
3478 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3479 		tq->tq_size -= 80;
3480 	}
3481 
3482 	TAILQ_INIT(&tq->tq_pktlist);
3483 	for (i = 0; i < N(tq->tq_pkts); i++) {
3484 		tp = &(tq->tq_pkts[i]);
3485 		tp->tp_index = i;
3486 		tp->tp_queue = tq;
3487 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3488 	}
3489 }
3490 
3491 static uint16_t
3492 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3493 {
3494 	struct bwn_softc *sc = mac->mac_sc;
3495 	static const uint16_t bases[] = {
3496 		BWN_PIO_BASE0,
3497 		BWN_PIO_BASE1,
3498 		BWN_PIO_BASE2,
3499 		BWN_PIO_BASE3,
3500 		BWN_PIO_BASE4,
3501 		BWN_PIO_BASE5,
3502 		BWN_PIO_BASE6,
3503 		BWN_PIO_BASE7,
3504 	};
3505 	static const uint16_t bases_rev11[] = {
3506 		BWN_PIO11_BASE0,
3507 		BWN_PIO11_BASE1,
3508 		BWN_PIO11_BASE2,
3509 		BWN_PIO11_BASE3,
3510 		BWN_PIO11_BASE4,
3511 		BWN_PIO11_BASE5,
3512 	};
3513 
3514 	if (siba_get_revid(sc->sc_dev) >= 11) {
3515 		if (index >= N(bases_rev11))
3516 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
3517 		return (bases_rev11[index]);
3518 	}
3519 	if (index >= N(bases))
3520 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
3521 	return (bases[index]);
3522 }
3523 
3524 static void
3525 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3526     int index)
3527 {
3528 	struct bwn_softc *sc = mac->mac_sc;
3529 
3530 	prq->prq_mac = mac;
3531 	prq->prq_rev = siba_get_revid(sc->sc_dev);
3532 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3533 	bwn_dma_rxdirectfifo(mac, index, 1);
3534 }
3535 
3536 static void
3537 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3538 {
3539 	if (tq == NULL)
3540 		return;
3541 	bwn_pio_cancel_tx_packets(tq);
3542 }
3543 
3544 static void
3545 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3546 {
3547 
3548 	bwn_destroy_pioqueue_tx(pio);
3549 }
3550 
3551 static uint16_t
3552 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3553     uint16_t offset)
3554 {
3555 
3556 	return (BWN_READ_2(mac, tq->tq_base + offset));
3557 }
3558 
3559 static void
3560 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3561 {
3562 	uint32_t ctl;
3563 	int type;
3564 	uint16_t base;
3565 
3566 	type = bwn_dma_mask2type(bwn_dma_mask(mac));
3567 	base = bwn_dma_base(type, idx);
3568 	if (type == BWN_DMA_64BIT) {
3569 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3570 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3571 		if (enable)
3572 			ctl |= BWN_DMA64_RXDIRECTFIFO;
3573 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3574 	} else {
3575 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3576 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3577 		if (enable)
3578 			ctl |= BWN_DMA32_RXDIRECTFIFO;
3579 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3580 	}
3581 }
3582 
3583 static uint64_t
3584 bwn_dma_mask(struct bwn_mac *mac)
3585 {
3586 	uint32_t tmp;
3587 	uint16_t base;
3588 
3589 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3590 	if (tmp & SIBA_TGSHIGH_DMA64)
3591 		return (BWN_DMA_BIT_MASK(64));
3592 	base = bwn_dma_base(0, 0);
3593 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3594 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3595 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
3596 		return (BWN_DMA_BIT_MASK(32));
3597 
3598 	return (BWN_DMA_BIT_MASK(30));
3599 }
3600 
3601 static int
3602 bwn_dma_mask2type(uint64_t dmamask)
3603 {
3604 
3605 	if (dmamask == BWN_DMA_BIT_MASK(30))
3606 		return (BWN_DMA_30BIT);
3607 	if (dmamask == BWN_DMA_BIT_MASK(32))
3608 		return (BWN_DMA_32BIT);
3609 	if (dmamask == BWN_DMA_BIT_MASK(64))
3610 		return (BWN_DMA_64BIT);
3611 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3612 	return (BWN_DMA_30BIT);
3613 }
3614 
3615 static void
3616 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3617 {
3618 	struct bwn_pio_txpkt *tp;
3619 	unsigned int i;
3620 
3621 	for (i = 0; i < N(tq->tq_pkts); i++) {
3622 		tp = &(tq->tq_pkts[i]);
3623 		if (tp->tp_m) {
3624 			m_freem(tp->tp_m);
3625 			tp->tp_m = NULL;
3626 		}
3627 	}
3628 }
3629 
3630 static uint16_t
3631 bwn_dma_base(int type, int controller_idx)
3632 {
3633 	static const uint16_t map64[] = {
3634 		BWN_DMA64_BASE0,
3635 		BWN_DMA64_BASE1,
3636 		BWN_DMA64_BASE2,
3637 		BWN_DMA64_BASE3,
3638 		BWN_DMA64_BASE4,
3639 		BWN_DMA64_BASE5,
3640 	};
3641 	static const uint16_t map32[] = {
3642 		BWN_DMA32_BASE0,
3643 		BWN_DMA32_BASE1,
3644 		BWN_DMA32_BASE2,
3645 		BWN_DMA32_BASE3,
3646 		BWN_DMA32_BASE4,
3647 		BWN_DMA32_BASE5,
3648 	};
3649 
3650 	if (type == BWN_DMA_64BIT) {
3651 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3652 		    ("%s:%d: fail", __func__, __LINE__));
3653 		return (map64[controller_idx]);
3654 	}
3655 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3656 	    ("%s:%d: fail", __func__, __LINE__));
3657 	return (map32[controller_idx]);
3658 }
3659 
3660 static void
3661 bwn_dma_init(struct bwn_mac *mac)
3662 {
3663 	struct bwn_dma *dma = &mac->mac_method.dma;
3664 
3665 	/* setup TX DMA channels. */
3666 	bwn_dma_setup(dma->wme[WME_AC_BK]);
3667 	bwn_dma_setup(dma->wme[WME_AC_BE]);
3668 	bwn_dma_setup(dma->wme[WME_AC_VI]);
3669 	bwn_dma_setup(dma->wme[WME_AC_VO]);
3670 	bwn_dma_setup(dma->mcast);
3671 	/* setup RX DMA channel. */
3672 	bwn_dma_setup(dma->rx);
3673 }
3674 
3675 static struct bwn_dma_ring *
3676 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3677     int for_tx, int type)
3678 {
3679 	struct bwn_dma *dma = &mac->mac_method.dma;
3680 	struct bwn_dma_ring *dr;
3681 	struct bwn_dmadesc_generic *desc;
3682 	struct bwn_dmadesc_meta *mt;
3683 	struct bwn_softc *sc = mac->mac_sc;
3684 	int error, i;
3685 
3686 	dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO);
3687 	dr->dr_numslots = BWN_RXRING_SLOTS;
3688 	if (for_tx)
3689 		dr->dr_numslots = BWN_TXRING_SLOTS;
3690 
3691 	dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3692 	    M_DEVBUF, M_INTWAIT | M_ZERO);
3693 
3694 	dr->dr_type = type;
3695 	dr->dr_mac = mac;
3696 	dr->dr_base = bwn_dma_base(type, controller_index);
3697 	dr->dr_index = controller_index;
3698 	if (type == BWN_DMA_64BIT) {
3699 		dr->getdesc = bwn_dma_64_getdesc;
3700 		dr->setdesc = bwn_dma_64_setdesc;
3701 		dr->start_transfer = bwn_dma_64_start_transfer;
3702 		dr->suspend = bwn_dma_64_suspend;
3703 		dr->resume = bwn_dma_64_resume;
3704 		dr->get_curslot = bwn_dma_64_get_curslot;
3705 		dr->set_curslot = bwn_dma_64_set_curslot;
3706 	} else {
3707 		dr->getdesc = bwn_dma_32_getdesc;
3708 		dr->setdesc = bwn_dma_32_setdesc;
3709 		dr->start_transfer = bwn_dma_32_start_transfer;
3710 		dr->suspend = bwn_dma_32_suspend;
3711 		dr->resume = bwn_dma_32_resume;
3712 		dr->get_curslot = bwn_dma_32_get_curslot;
3713 		dr->set_curslot = bwn_dma_32_set_curslot;
3714 	}
3715 	if (for_tx) {
3716 		dr->dr_tx = 1;
3717 		dr->dr_curslot = -1;
3718 	} else {
3719 		if (dr->dr_index == 0) {
3720 			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3721 			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3722 		} else
3723 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3724 	}
3725 
3726 	error = bwn_dma_allocringmemory(dr);
3727 	if (error)
3728 		goto fail1;
3729 
3730 	if (for_tx) {
3731 		/*
3732 		 * Assumption: BWN_TXRING_SLOTS can be divided by
3733 		 * BWN_TX_SLOTS_PER_FRAME
3734 		 */
3735 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3736 		    ("%s:%d: fail", __func__, __LINE__));
3737 
3738 		/*
3739 		 * Create TX ring DMA stuffs
3740 		 */
3741 		dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag,
3742 		    4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3743 		    BWN_MAX_HDRSIZE(mac),
3744 		    BUS_DMA_WAITOK | BUS_DMA_ZERO,
3745 		    &dr->dr_txring_dtag, &dr->dr_txring_dmap,
3746 		    &dr->dr_txring_paddr);
3747 		if (dr->dr_txhdr_cache == NULL) {
3748 			device_printf(sc->sc_dev,
3749 			    "can't create TX ring DMA memory\n");
3750 			goto fail1;
3751 		}
3752 
3753 		for (i = 0; i < dr->dr_numslots; i += 2) {
3754 			dr->getdesc(dr, i, &desc, &mt);
3755 
3756 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3757 			mt->mt_m = NULL;
3758 			mt->mt_ni = NULL;
3759 			mt->mt_islast = 0;
3760 			mt->mt_dmap = dr->dr_txring_dmap;
3761 			mt->mt_paddr = dr->dr_txring_paddr +
3762 			    (i / BWN_TX_SLOTS_PER_FRAME) *
3763 			    BWN_MAX_HDRSIZE(mac);
3764 
3765 			dr->getdesc(dr, i + 1, &desc, &mt);
3766 
3767 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3768 			mt->mt_m = NULL;
3769 			mt->mt_ni = NULL;
3770 			mt->mt_islast = 1;
3771 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
3772 			    &mt->mt_dmap);
3773 			if (error) {
3774 				device_printf(sc->sc_dev,
3775 				     "can't create RX buf DMA map\n");
3776 				goto fail2;
3777 			}
3778 		}
3779 	} else {
3780 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3781 		    &dr->dr_spare_dmap);
3782 		if (error) {
3783 			device_printf(sc->sc_dev,
3784 			    "can't create RX buf DMA map\n");
3785 			goto out;		/* XXX wrong! */
3786 		}
3787 
3788 		for (i = 0; i < dr->dr_numslots; i++) {
3789 			dr->getdesc(dr, i, &desc, &mt);
3790 
3791 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3792 			    &mt->mt_dmap);
3793 			if (error) {
3794 				device_printf(sc->sc_dev,
3795 				    "can't create RX buf DMA map\n");
3796 				goto out;	/* XXX wrong! */
3797 			}
3798 			error = bwn_dma_newbuf(dr, desc, mt, 1);
3799 			if (error) {
3800 				device_printf(sc->sc_dev,
3801 				    "failed to allocate RX buf\n");
3802 				goto out;	/* XXX wrong! */
3803 			}
3804 		}
3805 
3806 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3807 		    BUS_DMASYNC_PREWRITE);
3808 
3809 		dr->dr_usedslot = dr->dr_numslots;
3810 	}
3811 
3812       out:
3813 	return (dr);
3814 
3815 fail2:
3816 	/* XXX free up dma allocations */
3817 fail1:
3818 	kfree(dr->dr_meta, M_DEVBUF);
3819 	kfree(dr, M_DEVBUF);
3820 	return (NULL);
3821 }
3822 
3823 static void
3824 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3825 {
3826 
3827 	if (dr == NULL)
3828 		return;
3829 
3830 	bwn_dma_free_descbufs(*dr);
3831 	bwn_dma_free_ringmemory(*dr);
3832 
3833 	if ((*dr)->dr_meta != NULL)
3834 		kfree((*dr)->dr_meta, M_DEVBUF);
3835 	kfree(*dr, M_DEVBUF);
3836 
3837 	*dr = NULL;
3838 }
3839 
3840 static void
3841 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3842     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3843 {
3844 	struct bwn_dmadesc32 *desc;
3845 
3846 	*meta = &(dr->dr_meta[slot]);
3847 	desc = dr->dr_ring_descbase;
3848 	desc = &(desc[slot]);
3849 
3850 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3851 }
3852 
3853 static void
3854 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3855     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3856     int start, int end, int irq)
3857 {
3858 	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3859 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3860 	uint32_t addr, addrext, ctl;
3861 	int slot;
3862 
3863 	slot = (int)(&(desc->dma.dma32) - descbase);
3864 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3865 	    ("%s:%d: fail", __func__, __LINE__));
3866 
3867 	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3868 	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3869 	addr |= siba_dma_translation(sc->sc_dev);
3870 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3871 	if (slot == dr->dr_numslots - 1)
3872 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
3873 	if (start)
3874 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
3875 	if (end)
3876 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
3877 	if (irq)
3878 		ctl |= BWN_DMA32_DCTL_IRQ;
3879 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3880 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
3881 
3882 	desc->dma.dma32.control = htole32(ctl);
3883 	desc->dma.dma32.address = htole32(addr);
3884 }
3885 
3886 static void
3887 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3888 {
3889 
3890 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3891 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3892 }
3893 
3894 static void
3895 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3896 {
3897 
3898 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3899 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3900 }
3901 
3902 static void
3903 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3904 {
3905 
3906 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3907 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3908 }
3909 
3910 static int
3911 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3912 {
3913 	uint32_t val;
3914 
3915 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3916 	val &= BWN_DMA32_RXDPTR;
3917 
3918 	return (val / sizeof(struct bwn_dmadesc32));
3919 }
3920 
3921 static void
3922 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3923 {
3924 
3925 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3926 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3927 }
3928 
3929 static void
3930 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3931     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3932 {
3933 	struct bwn_dmadesc64 *desc;
3934 
3935 	*meta = &(dr->dr_meta[slot]);
3936 	desc = dr->dr_ring_descbase;
3937 	desc = &(desc[slot]);
3938 
3939 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3940 }
3941 
3942 static void
3943 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3944     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3945     int start, int end, int irq)
3946 {
3947 	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3948 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3949 	int slot;
3950 	uint32_t ctl0 = 0, ctl1 = 0;
3951 	uint32_t addrlo, addrhi;
3952 	uint32_t addrext;
3953 
3954 	slot = (int)(&(desc->dma.dma64) - descbase);
3955 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3956 	    ("%s:%d: fail", __func__, __LINE__));
3957 
3958 	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3959 	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3960 	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3961 	    30;
3962 	addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3963 	if (slot == dr->dr_numslots - 1)
3964 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3965 	if (start)
3966 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3967 	if (end)
3968 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3969 	if (irq)
3970 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
3971 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3972 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3973 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
3974 
3975 	desc->dma.dma64.control0 = htole32(ctl0);
3976 	desc->dma.dma64.control1 = htole32(ctl1);
3977 	desc->dma.dma64.address_low = htole32(addrlo);
3978 	desc->dma.dma64.address_high = htole32(addrhi);
3979 }
3980 
3981 static void
3982 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3983 {
3984 
3985 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3986 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3987 }
3988 
3989 static void
3990 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3991 {
3992 
3993 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3994 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3995 }
3996 
3997 static void
3998 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3999 {
4000 
4001 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4002 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4003 }
4004 
4005 static int
4006 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4007 {
4008 	uint32_t val;
4009 
4010 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4011 	val &= BWN_DMA64_RXSTATDPTR;
4012 
4013 	return (val / sizeof(struct bwn_dmadesc64));
4014 }
4015 
4016 static void
4017 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4018 {
4019 
4020 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4021 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4022 }
4023 
4024 static int
4025 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4026 {
4027 	struct bwn_mac *mac = dr->dr_mac;
4028 	struct bwn_dma *dma = &mac->mac_method.dma;
4029 	struct bwn_softc *sc = mac->mac_sc;
4030 	int error;
4031 
4032 	error = bus_dma_tag_create(dma->parent_dtag,
4033 			    BWN_ALIGN, 0,
4034 			    BUS_SPACE_MAXADDR,
4035 			    BUS_SPACE_MAXADDR,
4036 			    NULL, NULL,
4037 			    BWN_DMA_RINGMEMSIZE,
4038 			    1,
4039 			    BUS_SPACE_MAXSIZE_32BIT,
4040 			    0,
4041 			    &dr->dr_ring_dtag);
4042 	if (error) {
4043 		device_printf(sc->sc_dev,
4044 		    "can't create TX ring DMA tag: TODO frees\n");
4045 		return (-1);
4046 	}
4047 
4048 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
4049 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4050 	    &dr->dr_ring_dmap);
4051 	if (error) {
4052 		device_printf(sc->sc_dev,
4053 		    "can't allocate DMA mem: TODO frees\n");
4054 		return (-1);
4055 	}
4056 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4057 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4058 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0);
4059 	if (error) {
4060 		device_printf(sc->sc_dev,
4061 		    "can't load DMA mem: TODO free\n");
4062 		return (-1);
4063 	}
4064 
4065 	return (0);
4066 }
4067 
4068 static void
4069 bwn_dma_setup(struct bwn_dma_ring *dr)
4070 {
4071 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
4072 	uint64_t ring64;
4073 	uint32_t addrext, ring32, value;
4074 	uint32_t trans = siba_dma_translation(sc->sc_dev);
4075 
4076 	if (dr->dr_tx) {
4077 		dr->dr_curslot = -1;
4078 
4079 		if (dr->dr_type == BWN_DMA_64BIT) {
4080 			ring64 = (uint64_t)(dr->dr_ring_dmabase);
4081 			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4082 			    >> 30;
4083 			value = BWN_DMA64_TXENABLE;
4084 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4085 			    & BWN_DMA64_TXADDREXT_MASK;
4086 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4087 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4088 			    (ring64 & 0xffffffff));
4089 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4090 			    ((ring64 >> 32) &
4091 			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4092 		} else {
4093 			ring32 = (uint32_t)(dr->dr_ring_dmabase);
4094 			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4095 			value = BWN_DMA32_TXENABLE;
4096 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4097 			    & BWN_DMA32_TXADDREXT_MASK;
4098 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4099 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4100 			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4101 		}
4102 		return;
4103 	}
4104 
4105 	/*
4106 	 * set for RX
4107 	 */
4108 	dr->dr_usedslot = dr->dr_numslots;
4109 
4110 	if (dr->dr_type == BWN_DMA_64BIT) {
4111 		ring64 = (uint64_t)(dr->dr_ring_dmabase);
4112 		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4113 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4114 		value |= BWN_DMA64_RXENABLE;
4115 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4116 		    & BWN_DMA64_RXADDREXT_MASK;
4117 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4118 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4119 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4120 		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4121 		    | (trans << 1));
4122 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4123 		    sizeof(struct bwn_dmadesc64));
4124 	} else {
4125 		ring32 = (uint32_t)(dr->dr_ring_dmabase);
4126 		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4127 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4128 		value |= BWN_DMA32_RXENABLE;
4129 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4130 		    & BWN_DMA32_RXADDREXT_MASK;
4131 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4132 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4133 		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4134 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4135 		    sizeof(struct bwn_dmadesc32));
4136 	}
4137 }
4138 
4139 static void
4140 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4141 {
4142 
4143 	if (dr->dr_tx) {
4144 		bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap);
4145 		if (dr->dr_txhdr_cache != NULL)
4146 			bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache,
4147 			    dr->dr_txring_dmap);
4148 		bus_dma_tag_destroy(dr->dr_txring_dtag);
4149 	}
4150 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4151 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4152 	    dr->dr_ring_dmap);
4153 	bus_dma_tag_destroy(dr->dr_ring_dtag);
4154 }
4155 
4156 static void
4157 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4158 {
4159 
4160 	if (dr->dr_tx) {
4161 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4162 		if (dr->dr_type == BWN_DMA_64BIT) {
4163 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4164 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4165 		} else
4166 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4167 	} else {
4168 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4169 		if (dr->dr_type == BWN_DMA_64BIT) {
4170 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4171 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4172 		} else
4173 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4174 	}
4175 }
4176 
4177 static void
4178 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4179 {
4180 	struct bwn_dmadesc_generic *desc;
4181 	struct bwn_dmadesc_meta *meta;
4182 	struct bwn_mac *mac = dr->dr_mac;
4183 	struct bwn_dma *dma = &mac->mac_method.dma;
4184 	struct bwn_softc *sc = mac->mac_sc;
4185 	int i;
4186 
4187 	if (!dr->dr_usedslot)
4188 		return;
4189 	for (i = 0; i < dr->dr_numslots; i++) {
4190 		dr->getdesc(dr, i, &desc, &meta);
4191 
4192 		if (meta->mt_m == NULL) {
4193 			if (!dr->dr_tx)
4194 				device_printf(sc->sc_dev, "%s: not TX?\n",
4195 				    __func__);
4196 			continue;
4197 		}
4198 		if (dr->dr_tx) {
4199 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
4200 				/* Nothing */
4201 			} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
4202 				bus_dmamap_unload(dma->txbuf_dtag,
4203 				    meta->mt_dmap);
4204 			}
4205 		} else
4206 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4207 		bwn_dma_free_descbuf(dr, meta);
4208 	}
4209 }
4210 
4211 static int
4212 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4213     int type)
4214 {
4215 	struct bwn_softc *sc = mac->mac_sc;
4216 	uint32_t value;
4217 	int i;
4218 	uint16_t offset;
4219 
4220 	for (i = 0; i < 10; i++) {
4221 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4222 		    BWN_DMA32_TXSTATUS;
4223 		value = BWN_READ_4(mac, base + offset);
4224 		if (type == BWN_DMA_64BIT) {
4225 			value &= BWN_DMA64_TXSTAT;
4226 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
4227 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4228 			    value == BWN_DMA64_TXSTAT_STOPPED)
4229 				break;
4230 		} else {
4231 			value &= BWN_DMA32_TXSTATE;
4232 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
4233 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4234 			    value == BWN_DMA32_TXSTAT_STOPPED)
4235 				break;
4236 		}
4237 		DELAY(1000);
4238 	}
4239 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4240 	BWN_WRITE_4(mac, base + offset, 0);
4241 	for (i = 0; i < 10; i++) {
4242 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4243 						   BWN_DMA32_TXSTATUS;
4244 		value = BWN_READ_4(mac, base + offset);
4245 		if (type == BWN_DMA_64BIT) {
4246 			value &= BWN_DMA64_TXSTAT;
4247 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
4248 				i = -1;
4249 				break;
4250 			}
4251 		} else {
4252 			value &= BWN_DMA32_TXSTATE;
4253 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
4254 				i = -1;
4255 				break;
4256 			}
4257 		}
4258 		DELAY(1000);
4259 	}
4260 	if (i != -1) {
4261 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4262 		return (ENODEV);
4263 	}
4264 	DELAY(1000);
4265 
4266 	return (0);
4267 }
4268 
4269 static int
4270 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4271     int type)
4272 {
4273 	struct bwn_softc *sc = mac->mac_sc;
4274 	uint32_t value;
4275 	int i;
4276 	uint16_t offset;
4277 
4278 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4279 	BWN_WRITE_4(mac, base + offset, 0);
4280 	for (i = 0; i < 10; i++) {
4281 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4282 		    BWN_DMA32_RXSTATUS;
4283 		value = BWN_READ_4(mac, base + offset);
4284 		if (type == BWN_DMA_64BIT) {
4285 			value &= BWN_DMA64_RXSTAT;
4286 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
4287 				i = -1;
4288 				break;
4289 			}
4290 		} else {
4291 			value &= BWN_DMA32_RXSTATE;
4292 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
4293 				i = -1;
4294 				break;
4295 			}
4296 		}
4297 		DELAY(1000);
4298 	}
4299 	if (i != -1) {
4300 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4301 		return (ENODEV);
4302 	}
4303 
4304 	return (0);
4305 }
4306 
4307 static void
4308 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4309     struct bwn_dmadesc_meta *meta)
4310 {
4311 
4312 	if (meta->mt_m != NULL) {
4313 		m_freem(meta->mt_m);
4314 		meta->mt_m = NULL;
4315 	}
4316 	if (meta->mt_ni != NULL) {
4317 		ieee80211_free_node(meta->mt_ni);
4318 		meta->mt_ni = NULL;
4319 	}
4320 }
4321 
4322 static void
4323 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4324 {
4325 	struct bwn_rxhdr4 *rxhdr;
4326 	unsigned char *frame;
4327 
4328 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
4329 	rxhdr->frame_len = 0;
4330 
4331 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4332 	    sizeof(struct bwn_plcp6) + 2,
4333 	    ("%s:%d: fail", __func__, __LINE__));
4334 	frame = mtod(m, char *) + dr->dr_frameoffset;
4335 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4336 }
4337 
4338 static uint8_t
4339 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4340 {
4341 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4342 
4343 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4344 	    == 0xff);
4345 }
4346 
4347 static void
4348 bwn_wme_init(struct bwn_mac *mac)
4349 {
4350 
4351 	bwn_wme_load(mac);
4352 
4353 	/* enable WME support. */
4354 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4355 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4356 	    BWN_IFSCTL_USE_EDCF);
4357 }
4358 
4359 static void
4360 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4361 {
4362 	struct bwn_softc *sc = mac->mac_sc;
4363 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4364 	uint16_t delay;	/* microsec */
4365 
4366 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4367 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4368 		delay = 500;
4369 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4370 		delay = max(delay, (uint16_t)2400);
4371 
4372 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4373 }
4374 
4375 static void
4376 bwn_bt_enable(struct bwn_mac *mac)
4377 {
4378 	struct bwn_softc *sc = mac->mac_sc;
4379 	uint64_t hf;
4380 
4381 	if (bwn_bluetooth == 0)
4382 		return;
4383 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4384 		return;
4385 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4386 		return;
4387 
4388 	hf = bwn_hf_read(mac);
4389 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4390 		hf |= BWN_HF_BT_COEXISTALT;
4391 	else
4392 		hf |= BWN_HF_BT_COEXIST;
4393 	bwn_hf_write(mac, hf);
4394 }
4395 
4396 static void
4397 bwn_set_macaddr(struct bwn_mac *mac)
4398 {
4399 
4400 	bwn_mac_write_bssid(mac);
4401 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4402 }
4403 
4404 static void
4405 bwn_clear_keys(struct bwn_mac *mac)
4406 {
4407 	int i;
4408 
4409 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
4410 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4411 		    ("%s:%d: fail", __func__, __LINE__));
4412 
4413 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4414 		    NULL, BWN_SEC_KEYSIZE, NULL);
4415 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4416 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4417 			    NULL, BWN_SEC_KEYSIZE, NULL);
4418 		}
4419 		mac->mac_key[i].keyconf = NULL;
4420 	}
4421 }
4422 
4423 static void
4424 bwn_crypt_init(struct bwn_mac *mac)
4425 {
4426 	struct bwn_softc *sc = mac->mac_sc;
4427 
4428 	mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4429 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4430 	    ("%s:%d: fail", __func__, __LINE__));
4431 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4432 	mac->mac_ktp *= 2;
4433 	if (siba_get_revid(sc->sc_dev) >= 5)
4434 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4435 	bwn_clear_keys(mac);
4436 }
4437 
4438 static void
4439 bwn_chip_exit(struct bwn_mac *mac)
4440 {
4441 	struct bwn_softc *sc = mac->mac_sc;
4442 
4443 	bwn_phy_exit(mac);
4444 	siba_gpio_set(sc->sc_dev, 0);
4445 }
4446 
4447 static int
4448 bwn_fw_fillinfo(struct bwn_mac *mac)
4449 {
4450 	int error;
4451 
4452 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4453 	if (error == 0)
4454 		return (0);
4455 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4456 	if (error == 0)
4457 		return (0);
4458 	return (error);
4459 }
4460 
4461 static int
4462 bwn_gpio_init(struct bwn_mac *mac)
4463 {
4464 	struct bwn_softc *sc = mac->mac_sc;
4465 	uint32_t mask = 0x1f, set = 0xf, value;
4466 
4467 	BWN_WRITE_4(mac, BWN_MACCTL,
4468 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4469 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
4470 	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4471 
4472 	if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4473 		mask |= 0x0060;
4474 		set |= 0x0060;
4475 	}
4476 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4477 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
4478 		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4479 		mask |= 0x0200;
4480 		set |= 0x0200;
4481 	}
4482 	if (siba_get_revid(sc->sc_dev) >= 2)
4483 		mask |= 0x0010;
4484 
4485 	value = siba_gpio_get(sc->sc_dev);
4486 	if (value == -1)
4487 		return (0);
4488 	siba_gpio_set(sc->sc_dev, (value & mask) | set);
4489 
4490 	return (0);
4491 }
4492 
4493 static int
4494 bwn_fw_loadinitvals(struct bwn_mac *mac)
4495 {
4496 #define	GETFWOFFSET(fwp, offset)				\
4497 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4498 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
4499 	const struct bwn_fwhdr *hdr;
4500 	struct bwn_fw *fw = &mac->mac_fw;
4501 	int error;
4502 
4503 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4504 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4505 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4506 	if (error)
4507 		return (error);
4508 	if (fw->initvals_band.fw) {
4509 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4510 		error = bwn_fwinitvals_write(mac,
4511 		    GETFWOFFSET(fw->initvals_band, hdr_len),
4512 		    be32toh(hdr->size),
4513 		    fw->initvals_band.fw->datasize - hdr_len);
4514 	}
4515 	return (error);
4516 #undef GETFWOFFSET
4517 }
4518 
4519 static int
4520 bwn_phy_init(struct bwn_mac *mac)
4521 {
4522 	struct bwn_softc *sc = mac->mac_sc;
4523 	int error;
4524 
4525 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4526 	mac->mac_phy.rf_onoff(mac, 1);
4527 	error = mac->mac_phy.init(mac);
4528 	if (error) {
4529 		device_printf(sc->sc_dev, "PHY init failed\n");
4530 		goto fail0;
4531 	}
4532 	error = bwn_switch_channel(mac,
4533 	    mac->mac_phy.get_default_chan(mac));
4534 	if (error) {
4535 		device_printf(sc->sc_dev,
4536 		    "failed to switch default channel\n");
4537 		goto fail1;
4538 	}
4539 	return (0);
4540 fail1:
4541 	if (mac->mac_phy.exit)
4542 		mac->mac_phy.exit(mac);
4543 fail0:
4544 	mac->mac_phy.rf_onoff(mac, 0);
4545 
4546 	return (error);
4547 }
4548 
4549 static void
4550 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4551 {
4552 	uint16_t ant;
4553 	uint16_t tmp;
4554 
4555 	ant = bwn_ant2phy(antenna);
4556 
4557 	/* For ACK/CTS */
4558 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4559 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4560 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4561 	/* For Probe Resposes */
4562 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4563 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4564 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4565 }
4566 
4567 static void
4568 bwn_set_opmode(struct bwn_mac *mac)
4569 {
4570 	struct bwn_softc *sc = mac->mac_sc;
4571 	struct ifnet *ifp = sc->sc_ifp;
4572 	struct ieee80211com *ic = ifp->if_l2com;
4573 	uint32_t ctl;
4574 	uint16_t cfp_pretbtt;
4575 
4576 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4577 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4578 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4579 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4580 	ctl |= BWN_MACCTL_STA;
4581 
4582 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4583 	    ic->ic_opmode == IEEE80211_M_MBSS)
4584 		ctl |= BWN_MACCTL_HOSTAP;
4585 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
4586 		ctl &= ~BWN_MACCTL_STA;
4587 	ctl |= sc->sc_filters;
4588 
4589 	if (siba_get_revid(sc->sc_dev) <= 4)
4590 		ctl |= BWN_MACCTL_PROMISC;
4591 
4592 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4593 
4594 	cfp_pretbtt = 2;
4595 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4596 		if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4597 		    siba_get_chiprev(sc->sc_dev) == 3)
4598 			cfp_pretbtt = 100;
4599 		else
4600 			cfp_pretbtt = 50;
4601 	}
4602 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4603 }
4604 
4605 static int
4606 bwn_dma_gettype(struct bwn_mac *mac)
4607 {
4608 	uint32_t tmp;
4609 	uint16_t base;
4610 
4611 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4612 	if (tmp & SIBA_TGSHIGH_DMA64)
4613 		return (BWN_DMA_64BIT);
4614 	base = bwn_dma_base(0, 0);
4615 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4616 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4617 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
4618 		return (BWN_DMA_32BIT);
4619 
4620 	return (BWN_DMA_30BIT);
4621 }
4622 
4623 static void
4624 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4625 {
4626 	if (!error) {
4627 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4628 		*((bus_addr_t *)arg) = seg->ds_addr;
4629 	}
4630 }
4631 
4632 static void
4633 bwn_phy_g_init_sub(struct bwn_mac *mac)
4634 {
4635 	struct bwn_phy *phy = &mac->mac_phy;
4636 	struct bwn_phy_g *pg = &phy->phy_g;
4637 	struct bwn_softc *sc = mac->mac_sc;
4638 	uint16_t i, tmp;
4639 
4640 	if (phy->rev == 1)
4641 		bwn_phy_init_b5(mac);
4642 	else
4643 		bwn_phy_init_b6(mac);
4644 
4645 	if (phy->rev >= 2 || phy->gmode)
4646 		bwn_phy_init_a(mac);
4647 
4648 	if (phy->rev >= 2) {
4649 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4650 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4651 	}
4652 	if (phy->rev == 2) {
4653 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4654 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4655 	}
4656 	if (phy->rev > 5) {
4657 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4658 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4659 	}
4660 	if (phy->gmode || phy->rev >= 2) {
4661 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4662 		tmp &= BWN_PHYVER_VERSION;
4663 		if (tmp == 3 || tmp == 5) {
4664 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4665 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4666 		}
4667 		if (tmp == 5) {
4668 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4669 			    0x1f00);
4670 		}
4671 	}
4672 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4673 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4674 	if (phy->rf_rev == 8) {
4675 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4676 		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4677 	}
4678 	if (BWN_HAS_LOOPBACK(phy))
4679 		bwn_loopback_calcgain(mac);
4680 
4681 	if (phy->rf_rev != 8) {
4682 		if (pg->pg_initval == 0xffff)
4683 			pg->pg_initval = bwn_rf_init_bcm2050(mac);
4684 		else
4685 			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4686 	}
4687 	bwn_lo_g_init(mac);
4688 	if (BWN_HAS_TXMAG(phy)) {
4689 		BWN_RF_WRITE(mac, 0x52,
4690 		    (BWN_RF_READ(mac, 0x52) & 0xff00)
4691 		    | pg->pg_loctl.tx_bias |
4692 		    pg->pg_loctl.tx_magn);
4693 	} else {
4694 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4695 	}
4696 	if (phy->rev >= 6) {
4697 		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4698 		    (pg->pg_loctl.tx_bias << 12));
4699 	}
4700 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4701 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4702 	else
4703 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4704 	if (phy->rev < 2)
4705 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4706 	else
4707 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4708 	if (phy->gmode || phy->rev >= 2) {
4709 		bwn_lo_g_adjust(mac);
4710 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4711 	}
4712 
4713 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4714 		for (i = 0; i < 64; i++) {
4715 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4716 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4717 			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4718 			    -32), 31));
4719 		}
4720 		bwn_nrssi_threshold(mac);
4721 	} else if (phy->gmode || phy->rev >= 2) {
4722 		if (pg->pg_nrssi[0] == -1000) {
4723 			KASSERT(pg->pg_nrssi[1] == -1000,
4724 			    ("%s:%d: fail", __func__, __LINE__));
4725 			bwn_nrssi_slope_11g(mac);
4726 		} else
4727 			bwn_nrssi_threshold(mac);
4728 	}
4729 	if (phy->rf_rev == 8)
4730 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4731 	bwn_phy_hwpctl_init(mac);
4732 	if ((siba_get_chipid(sc->sc_dev) == 0x4306
4733 	     && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4734 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4735 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4736 	}
4737 }
4738 
4739 static uint8_t
4740 bwn_has_hwpctl(struct bwn_mac *mac)
4741 {
4742 
4743 	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4744 		return (0);
4745 	return (mac->mac_phy.use_hwpctl(mac));
4746 }
4747 
4748 static void
4749 bwn_phy_init_b5(struct bwn_mac *mac)
4750 {
4751 	struct bwn_phy *phy = &mac->mac_phy;
4752 	struct bwn_phy_g *pg = &phy->phy_g;
4753 	struct bwn_softc *sc = mac->mac_sc;
4754 	uint16_t offset, value;
4755 	uint8_t old_channel;
4756 
4757 	if (phy->analog == 1)
4758 		BWN_RF_SET(mac, 0x007a, 0x0050);
4759 	if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4760 	    (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4761 		value = 0x2120;
4762 		for (offset = 0x00a8; offset < 0x00c7; offset++) {
4763 			BWN_PHY_WRITE(mac, offset, value);
4764 			value += 0x202;
4765 		}
4766 	}
4767 	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4768 	if (phy->rf_ver == 0x2050)
4769 		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4770 
4771 	if (phy->gmode || phy->rev >= 2) {
4772 		if (phy->rf_ver == 0x2050) {
4773 			BWN_RF_SET(mac, 0x007a, 0x0020);
4774 			BWN_RF_SET(mac, 0x0051, 0x0004);
4775 		}
4776 		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4777 
4778 		BWN_PHY_SET(mac, 0x0802, 0x0100);
4779 		BWN_PHY_SET(mac, 0x042b, 0x2000);
4780 
4781 		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4782 
4783 		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4784 		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4785 		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4786 	}
4787 
4788 	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4789 		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4790 
4791 	if (phy->analog == 1) {
4792 		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4793 		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4794 		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4795 		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4796 		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4797 	} else
4798 		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4799 	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4800 	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4801 
4802 	if (phy->analog == 1)
4803 		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4804 	else
4805 		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4806 
4807 	if (phy->analog == 0)
4808 		BWN_WRITE_2(mac, 0x03e4, 0x3000);
4809 
4810 	old_channel = phy->chan;
4811 	bwn_phy_g_switch_chan(mac, 7, 0);
4812 
4813 	if (phy->rf_ver != 0x2050) {
4814 		BWN_RF_WRITE(mac, 0x0075, 0x0080);
4815 		BWN_RF_WRITE(mac, 0x0079, 0x0081);
4816 	}
4817 
4818 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
4819 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
4820 
4821 	if (phy->rf_ver == 0x2050) {
4822 		BWN_RF_WRITE(mac, 0x0050, 0x0020);
4823 		BWN_RF_WRITE(mac, 0x005a, 0x0070);
4824 	}
4825 
4826 	BWN_RF_WRITE(mac, 0x005b, 0x007b);
4827 	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4828 	BWN_RF_SET(mac, 0x007a, 0x0007);
4829 
4830 	bwn_phy_g_switch_chan(mac, old_channel, 0);
4831 	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4832 	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4833 	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4834 
4835 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4836 	    pg->pg_txctl);
4837 
4838 	if (phy->rf_ver == 0x2050)
4839 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
4840 
4841 	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4842 }
4843 
4844 static void
4845 bwn_loopback_calcgain(struct bwn_mac *mac)
4846 {
4847 	struct bwn_phy *phy = &mac->mac_phy;
4848 	struct bwn_phy_g *pg = &phy->phy_g;
4849 	struct bwn_softc *sc = mac->mac_sc;
4850 	uint16_t backup_phy[16] = { 0 };
4851 	uint16_t backup_radio[3];
4852 	uint16_t backup_bband;
4853 	uint16_t i, j, loop_i_max;
4854 	uint16_t trsw_rx;
4855 	uint16_t loop1_outer_done, loop1_inner_done;
4856 
4857 	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4858 	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4859 	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4860 	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4861 	if (phy->rev != 1) {
4862 		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4863 		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4864 	}
4865 	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4866 	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4867 	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4868 	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4869 	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4870 	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4871 	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4872 	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4873 	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4874 	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4875 	backup_bband = pg->pg_bbatt.att;
4876 	backup_radio[0] = BWN_RF_READ(mac, 0x52);
4877 	backup_radio[1] = BWN_RF_READ(mac, 0x43);
4878 	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4879 
4880 	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4881 	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4882 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4883 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4884 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4885 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4886 	if (phy->rev != 1) {
4887 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4888 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4889 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4890 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4891 	}
4892 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4893 	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4894 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4895 	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4896 
4897 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4898 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4899 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4900 
4901 	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4902 	if (phy->rev != 1) {
4903 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4904 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4905 	}
4906 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4907 
4908 	if (phy->rf_rev == 8)
4909 		BWN_RF_WRITE(mac, 0x43, 0x000f);
4910 	else {
4911 		BWN_RF_WRITE(mac, 0x52, 0);
4912 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4913 	}
4914 	bwn_phy_g_set_bbatt(mac, 11);
4915 
4916 	if (phy->rev >= 3)
4917 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4918 	else
4919 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4920 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4921 
4922 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4923 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4924 
4925 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4926 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4927 
4928 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4929 		if (phy->rev >= 7) {
4930 			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4931 			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4932 		}
4933 	}
4934 	BWN_RF_MASK(mac, 0x7a, 0x00f7);
4935 
4936 	j = 0;
4937 	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4938 	for (i = 0; i < loop_i_max; i++) {
4939 		for (j = 0; j < 16; j++) {
4940 			BWN_RF_WRITE(mac, 0x43, i);
4941 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4942 			    (j << 8));
4943 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4944 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4945 			DELAY(20);
4946 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4947 				goto done0;
4948 		}
4949 	}
4950 done0:
4951 	loop1_outer_done = i;
4952 	loop1_inner_done = j;
4953 	if (j >= 8) {
4954 		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4955 		trsw_rx = 0x1b;
4956 		for (j = j - 8; j < 16; j++) {
4957 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4958 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4959 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4960 			DELAY(20);
4961 			trsw_rx -= 3;
4962 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4963 				goto done1;
4964 		}
4965 	} else
4966 		trsw_rx = 0x18;
4967 done1:
4968 
4969 	if (phy->rev != 1) {
4970 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4971 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4972 	}
4973 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4974 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4975 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4976 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4977 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4978 	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4979 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4980 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4981 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4982 
4983 	bwn_phy_g_set_bbatt(mac, backup_bband);
4984 
4985 	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4986 	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4987 	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4988 
4989 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4990 	DELAY(10);
4991 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4992 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4993 	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4994 	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4995 
4996 	pg->pg_max_lb_gain =
4997 	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4998 	pg->pg_trsw_rx_gain = trsw_rx * 2;
4999 }
5000 
5001 static uint16_t
5002 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5003 {
5004 	struct bwn_phy *phy = &mac->mac_phy;
5005 	uint32_t tmp1 = 0, tmp2 = 0;
5006 	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5007 	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5008 	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5009 	static const uint8_t rcc_table[] = {
5010 		0x02, 0x03, 0x01, 0x0f,
5011 		0x06, 0x07, 0x05, 0x0f,
5012 		0x0a, 0x0b, 0x09, 0x0f,
5013 		0x0e, 0x0f, 0x0d, 0x0f,
5014 	};
5015 
5016 	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5017 	    rfoverval = rfover = cck3 = 0;
5018 	radio0 = BWN_RF_READ(mac, 0x43);
5019 	radio1 = BWN_RF_READ(mac, 0x51);
5020 	radio2 = BWN_RF_READ(mac, 0x52);
5021 	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5022 	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5023 	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5024 	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5025 
5026 	if (phy->type == BWN_PHYTYPE_B) {
5027 		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5028 		reg0 = BWN_READ_2(mac, 0x3ec);
5029 
5030 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5031 		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5032 	} else if (phy->gmode || phy->rev >= 2) {
5033 		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5034 		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5035 		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5036 		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5037 		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5038 		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5039 
5040 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5041 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5042 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5043 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5044 		if (BWN_HAS_LOOPBACK(phy)) {
5045 			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5046 			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5047 			if (phy->rev >= 3)
5048 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5049 			else
5050 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5051 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5052 		}
5053 
5054 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5055 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5056 			BWN_LPD(0, 1, 1)));
5057 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5058 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5059 	}
5060 	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5061 
5062 	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5063 	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5064 	reg1 = BWN_READ_2(mac, 0x3e6);
5065 	reg2 = BWN_READ_2(mac, 0x3f4);
5066 
5067 	if (phy->analog == 0)
5068 		BWN_WRITE_2(mac, 0x03e6, 0x0122);
5069 	else {
5070 		if (phy->analog >= 2)
5071 			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5072 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5073 		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5074 	}
5075 
5076 	reg = BWN_RF_READ(mac, 0x60);
5077 	index = (reg & 0x001e) >> 1;
5078 	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5079 
5080 	if (phy->type == BWN_PHYTYPE_B)
5081 		BWN_RF_WRITE(mac, 0x78, 0x26);
5082 	if (phy->gmode || phy->rev >= 2) {
5083 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5084 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5085 			BWN_LPD(0, 1, 1)));
5086 	}
5087 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5088 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5089 	if (phy->gmode || phy->rev >= 2) {
5090 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5091 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5092 			BWN_LPD(0, 0, 1)));
5093 	}
5094 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5095 	BWN_RF_SET(mac, 0x51, 0x0004);
5096 	if (phy->rf_rev == 8)
5097 		BWN_RF_WRITE(mac, 0x43, 0x1f);
5098 	else {
5099 		BWN_RF_WRITE(mac, 0x52, 0);
5100 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5101 	}
5102 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5103 
5104 	for (i = 0; i < 16; i++) {
5105 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5106 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5107 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5108 		if (phy->gmode || phy->rev >= 2) {
5109 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5110 			    bwn_rf_2050_rfoverval(mac,
5111 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5112 		}
5113 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5114 		DELAY(10);
5115 		if (phy->gmode || phy->rev >= 2) {
5116 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5117 			    bwn_rf_2050_rfoverval(mac,
5118 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5119 		}
5120 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5121 		DELAY(10);
5122 		if (phy->gmode || phy->rev >= 2) {
5123 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5124 			    bwn_rf_2050_rfoverval(mac,
5125 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5126 		}
5127 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5128 		DELAY(20);
5129 		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5130 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5131 		if (phy->gmode || phy->rev >= 2) {
5132 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5133 			    bwn_rf_2050_rfoverval(mac,
5134 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5135 		}
5136 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5137 	}
5138 	DELAY(10);
5139 
5140 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5141 	tmp1++;
5142 	tmp1 >>= 9;
5143 
5144 	for (i = 0; i < 16; i++) {
5145 		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5146 		BWN_RF_WRITE(mac, 0x78, radio78);
5147 		DELAY(10);
5148 		for (j = 0; j < 16; j++) {
5149 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5150 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5151 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5152 			if (phy->gmode || phy->rev >= 2) {
5153 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5154 				    bwn_rf_2050_rfoverval(mac,
5155 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5156 			}
5157 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5158 			DELAY(10);
5159 			if (phy->gmode || phy->rev >= 2) {
5160 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5161 				    bwn_rf_2050_rfoverval(mac,
5162 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5163 			}
5164 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5165 			DELAY(10);
5166 			if (phy->gmode || phy->rev >= 2) {
5167 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5168 				    bwn_rf_2050_rfoverval(mac,
5169 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5170 			}
5171 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5172 			DELAY(10);
5173 			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5174 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5175 			if (phy->gmode || phy->rev >= 2) {
5176 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5177 				    bwn_rf_2050_rfoverval(mac,
5178 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5179 			}
5180 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5181 		}
5182 		tmp2++;
5183 		tmp2 >>= 8;
5184 		if (tmp1 < tmp2)
5185 			break;
5186 	}
5187 
5188 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5189 	BWN_RF_WRITE(mac, 0x51, radio1);
5190 	BWN_RF_WRITE(mac, 0x52, radio2);
5191 	BWN_RF_WRITE(mac, 0x43, radio0);
5192 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5193 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5194 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5195 	BWN_WRITE_2(mac, 0x3e6, reg1);
5196 	if (phy->analog != 0)
5197 		BWN_WRITE_2(mac, 0x3f4, reg2);
5198 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5199 	bwn_spu_workaround(mac, phy->chan);
5200 	if (phy->type == BWN_PHYTYPE_B) {
5201 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5202 		BWN_WRITE_2(mac, 0x3ec, reg0);
5203 	} else if (phy->gmode) {
5204 		BWN_WRITE_2(mac, BWN_PHY_RADIO,
5205 			    BWN_READ_2(mac, BWN_PHY_RADIO)
5206 			    & 0x7fff);
5207 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5208 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5209 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5210 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5211 			      analogoverval);
5212 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5213 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5214 		if (BWN_HAS_LOOPBACK(phy)) {
5215 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5216 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5217 		}
5218 	}
5219 
5220 	return ((i > 15) ? radio78 : rcc);
5221 }
5222 
5223 static void
5224 bwn_phy_init_b6(struct bwn_mac *mac)
5225 {
5226 	struct bwn_phy *phy = &mac->mac_phy;
5227 	struct bwn_phy_g *pg = &phy->phy_g;
5228 	struct bwn_softc *sc = mac->mac_sc;
5229 	uint16_t offset, val;
5230 	uint8_t old_channel;
5231 
5232 	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5233 	    ("%s:%d: fail", __func__, __LINE__));
5234 
5235 	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5236 	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5237 	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5238 		BWN_RF_WRITE(mac, 0x51, 0x37);
5239 		BWN_RF_WRITE(mac, 0x52, 0x70);
5240 		BWN_RF_WRITE(mac, 0x53, 0xb3);
5241 		BWN_RF_WRITE(mac, 0x54, 0x9b);
5242 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5243 		BWN_RF_WRITE(mac, 0x5b, 0x88);
5244 		BWN_RF_WRITE(mac, 0x5d, 0x88);
5245 		BWN_RF_WRITE(mac, 0x5e, 0x88);
5246 		BWN_RF_WRITE(mac, 0x7d, 0x88);
5247 		bwn_hf_write(mac,
5248 		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5249 	}
5250 	if (phy->rf_rev == 8) {
5251 		BWN_RF_WRITE(mac, 0x51, 0);
5252 		BWN_RF_WRITE(mac, 0x52, 0x40);
5253 		BWN_RF_WRITE(mac, 0x53, 0xb7);
5254 		BWN_RF_WRITE(mac, 0x54, 0x98);
5255 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5256 		BWN_RF_WRITE(mac, 0x5b, 0x6b);
5257 		BWN_RF_WRITE(mac, 0x5c, 0x0f);
5258 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5259 			BWN_RF_WRITE(mac, 0x5d, 0xfa);
5260 			BWN_RF_WRITE(mac, 0x5e, 0xd8);
5261 		} else {
5262 			BWN_RF_WRITE(mac, 0x5d, 0xf5);
5263 			BWN_RF_WRITE(mac, 0x5e, 0xb8);
5264 		}
5265 		BWN_RF_WRITE(mac, 0x0073, 0x0003);
5266 		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5267 		BWN_RF_WRITE(mac, 0x007c, 0x0001);
5268 		BWN_RF_WRITE(mac, 0x007e, 0x0008);
5269 	}
5270 	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5271 		BWN_PHY_WRITE(mac, offset, val);
5272 		val -= 0x0202;
5273 	}
5274 	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5275 		BWN_PHY_WRITE(mac, offset, val);
5276 		val -= 0x0202;
5277 	}
5278 	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5279 		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5280 		val += 0x0202;
5281 	}
5282 	if (phy->type == BWN_PHYTYPE_G) {
5283 		BWN_RF_SET(mac, 0x007a, 0x0020);
5284 		BWN_RF_SET(mac, 0x0051, 0x0004);
5285 		BWN_PHY_SET(mac, 0x0802, 0x0100);
5286 		BWN_PHY_SET(mac, 0x042b, 0x2000);
5287 		BWN_PHY_WRITE(mac, 0x5b, 0);
5288 		BWN_PHY_WRITE(mac, 0x5c, 0);
5289 	}
5290 
5291 	old_channel = phy->chan;
5292 	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5293 
5294 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
5295 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
5296 	DELAY(40);
5297 	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5298 		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5299 		BWN_RF_WRITE(mac, 0x50, 0x20);
5300 	}
5301 	if (phy->rf_rev <= 2) {
5302 		BWN_RF_WRITE(mac, 0x7c, 0x20);
5303 		BWN_RF_WRITE(mac, 0x5a, 0x70);
5304 		BWN_RF_WRITE(mac, 0x5b, 0x7b);
5305 		BWN_RF_WRITE(mac, 0x5c, 0xb0);
5306 	}
5307 	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5308 
5309 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5310 
5311 	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5312 	if (phy->rf_rev >= 6)
5313 		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5314 	else
5315 		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5316 	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5317 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5318 	    pg->pg_txctl);
5319 	if (phy->rf_rev <= 5)
5320 		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5321 	if (phy->rf_rev <= 2)
5322 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5323 
5324 	if (phy->analog == 4) {
5325 		BWN_WRITE_2(mac, 0x3e4, 9);
5326 		BWN_PHY_MASK(mac, 0x61, 0x0fff);
5327 	} else
5328 		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5329 	if (phy->type == BWN_PHYTYPE_B)
5330 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5331 	else if (phy->type == BWN_PHYTYPE_G)
5332 		BWN_WRITE_2(mac, 0x03e6, 0x0);
5333 }
5334 
5335 static void
5336 bwn_phy_init_a(struct bwn_mac *mac)
5337 {
5338 	struct bwn_phy *phy = &mac->mac_phy;
5339 	struct bwn_softc *sc = mac->mac_sc;
5340 
5341 	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5342 	    ("%s:%d: fail", __func__, __LINE__));
5343 
5344 	if (phy->rev >= 6) {
5345 		if (phy->type == BWN_PHYTYPE_A)
5346 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5347 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5348 			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5349 		else
5350 			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5351 	}
5352 
5353 	bwn_wa_init(mac);
5354 
5355 	if (phy->type == BWN_PHYTYPE_G &&
5356 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5357 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5358 }
5359 
5360 static void
5361 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5362 {
5363 	int i;
5364 
5365 	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5366 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5367 }
5368 
5369 static void
5370 bwn_wa_agc(struct bwn_mac *mac)
5371 {
5372 	struct bwn_phy *phy = &mac->mac_phy;
5373 
5374 	if (phy->rev == 1) {
5375 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5376 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5377 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5378 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5379 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5380 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5381 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5382 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5383 		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5384 	} else {
5385 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5386 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5387 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5388 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5389 	}
5390 
5391 	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5392 	    0x5700);
5393 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5394 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5395 	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5396 	BWN_RF_SET(mac, 0x7a, 0x0008);
5397 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5398 	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5399 	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5400 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5401 	if (phy->rev == 1)
5402 		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5403 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5404 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5405 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5406 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5407 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5408 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5409 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5410 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5411 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5412 	if (phy->rev == 1) {
5413 		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5414 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5415 	} else {
5416 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5417 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5418 		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5419 		if (phy->rev >= 6) {
5420 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5421 			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5422 			    (uint16_t)~0xf000, 0x3000);
5423 		}
5424 	}
5425 	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5426 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5427 	if (phy->rev == 1) {
5428 		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5429 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5430 		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5431 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5432 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5433 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5434 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5435 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5436 	} else {
5437 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5438 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5439 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5440 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5441 	}
5442 	if (phy->rev >= 6) {
5443 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5444 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5445 	}
5446 	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5447 }
5448 
5449 static void
5450 bwn_wa_grev1(struct bwn_mac *mac)
5451 {
5452 	struct bwn_phy *phy = &mac->mac_phy;
5453 	int i;
5454 	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5455 	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5456 	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5457 
5458 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5459 
5460 	/* init CRSTHRES and ANTDWELL */
5461 	if (phy->rev == 1) {
5462 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5463 	} else if (phy->rev == 2) {
5464 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5465 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5466 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5467 	} else {
5468 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5469 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5470 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5471 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5472 	}
5473 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5474 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5475 	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5476 
5477 	/* XXX support PHY-A??? */
5478 	for (i = 0; i < N(bwn_tab_finefreqg); i++)
5479 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5480 		    bwn_tab_finefreqg[i]);
5481 
5482 	/* XXX support PHY-A??? */
5483 	if (phy->rev == 1)
5484 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5485 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5486 			    bwn_tab_noise_g1[i]);
5487 	else
5488 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5489 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5490 			    bwn_tab_noise_g2[i]);
5491 
5492 
5493 	for (i = 0; i < N(bwn_tab_rotor); i++)
5494 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5495 		    bwn_tab_rotor[i]);
5496 
5497 	/* XXX support PHY-A??? */
5498 	if (phy->rev >= 6) {
5499 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5500 		    BWN_PHY_ENCORE_EN)
5501 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5502 		else
5503 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5504 	} else
5505 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5506 
5507 	for (i = 0; i < N(bwn_tab_retard); i++)
5508 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5509 		    bwn_tab_retard[i]);
5510 
5511 	if (phy->rev == 1) {
5512 		for (i = 0; i < 16; i++)
5513 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5514 			    i, 0x0020);
5515 	} else {
5516 		for (i = 0; i < 32; i++)
5517 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5518 	}
5519 
5520 	bwn_wa_agc(mac);
5521 }
5522 
5523 static void
5524 bwn_wa_grev26789(struct bwn_mac *mac)
5525 {
5526 	struct bwn_phy *phy = &mac->mac_phy;
5527 	int i;
5528 	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5529 	uint16_t ofdmrev;
5530 
5531 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5532 
5533 	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5534 
5535 	/* init CRSTHRES and ANTDWELL */
5536 	if (phy->rev == 1)
5537 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5538 	else if (phy->rev == 2) {
5539 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5540 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5541 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5542 	} else {
5543 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5544 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5545 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5546 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5547 	}
5548 
5549 	for (i = 0; i < 64; i++)
5550 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5551 
5552 	/* XXX support PHY-A??? */
5553 	if (phy->rev == 1)
5554 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5555 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5556 			    bwn_tab_noise_g1[i]);
5557 	else
5558 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5559 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5560 			    bwn_tab_noise_g2[i]);
5561 
5562 	/* XXX support PHY-A??? */
5563 	if (phy->rev >= 6) {
5564 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5565 		    BWN_PHY_ENCORE_EN)
5566 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5567 		else
5568 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5569 	} else
5570 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5571 
5572 	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5573 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5574 		    bwn_tab_sigmasqr2[i]);
5575 
5576 	if (phy->rev == 1) {
5577 		for (i = 0; i < 16; i++)
5578 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5579 			    0x0020);
5580 	} else {
5581 		for (i = 0; i < 32; i++)
5582 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5583 	}
5584 
5585 	bwn_wa_agc(mac);
5586 
5587 	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5588 	if (ofdmrev > 2) {
5589 		if (phy->type == BWN_PHYTYPE_A)
5590 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5591 		else
5592 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5593 	} else {
5594 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5595 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5596 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5597 	}
5598 
5599 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5600 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5601 }
5602 
5603 static void
5604 bwn_wa_init(struct bwn_mac *mac)
5605 {
5606 	struct bwn_phy *phy = &mac->mac_phy;
5607 	struct bwn_softc *sc = mac->mac_sc;
5608 
5609 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5610 
5611 	switch (phy->rev) {
5612 	case 1:
5613 		bwn_wa_grev1(mac);
5614 		break;
5615 	case 2:
5616 	case 6:
5617 	case 7:
5618 	case 8:
5619 	case 9:
5620 		bwn_wa_grev26789(mac);
5621 		break;
5622 	default:
5623 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5624 	}
5625 
5626 	if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5627 	    siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5628 	    siba_get_pci_revid(sc->sc_dev) != 0x17) {
5629 		if (phy->rev < 2) {
5630 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5631 			    0x0002);
5632 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5633 			    0x0001);
5634 		} else {
5635 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5636 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5637 			if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5638 			     BWN_BFL_EXTLNA) &&
5639 			    (phy->rev >= 7)) {
5640 				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5641 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5642 				    0x0020, 0x0001);
5643 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5644 				    0x0021, 0x0001);
5645 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5646 				    0x0022, 0x0001);
5647 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5648 				    0x0023, 0x0000);
5649 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5650 				    0x0000, 0x0000);
5651 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5652 				    0x0003, 0x0002);
5653 			}
5654 		}
5655 	}
5656 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5657 		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5658 		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5659 	}
5660 
5661 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5662 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5663 }
5664 
5665 static void
5666 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5667     uint16_t value)
5668 {
5669 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5670 	uint16_t addr;
5671 
5672 	addr = table + offset;
5673 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5674 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5675 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5676 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5677 	}
5678 	pg->pg_ofdmtab_addr = addr;
5679 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5680 }
5681 
5682 static void
5683 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5684     uint32_t value)
5685 {
5686 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5687 	uint16_t addr;
5688 
5689 	addr = table + offset;
5690 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5691 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5692 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5693 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5694 	}
5695 	pg->pg_ofdmtab_addr = addr;
5696 
5697 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5698 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5699 }
5700 
5701 static void
5702 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5703     uint16_t value)
5704 {
5705 
5706 	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5707 	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5708 }
5709 
5710 static void
5711 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5712 {
5713 	struct bwn_phy *phy = &mac->mac_phy;
5714 	struct bwn_softc *sc = mac->mac_sc;
5715 	unsigned int i, max_loop;
5716 	uint16_t value;
5717 	uint32_t buffer[5] = {
5718 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5719 	};
5720 
5721 	if (ofdm) {
5722 		max_loop = 0x1e;
5723 		buffer[0] = 0x000201cc;
5724 	} else {
5725 		max_loop = 0xfa;
5726 		buffer[0] = 0x000b846e;
5727 	}
5728 
5729 	for (i = 0; i < 5; i++)
5730 		bwn_ram_write(mac, i * 4, buffer[i]);
5731 
5732 	BWN_WRITE_2(mac, 0x0568, 0x0000);
5733 	BWN_WRITE_2(mac, 0x07c0,
5734 	    (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5735 	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5736 	BWN_WRITE_2(mac, 0x050c, value);
5737 	if (phy->type == BWN_PHYTYPE_LP)
5738 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
5739 	BWN_WRITE_2(mac, 0x0508, 0x0000);
5740 	BWN_WRITE_2(mac, 0x050a, 0x0000);
5741 	BWN_WRITE_2(mac, 0x054c, 0x0000);
5742 	BWN_WRITE_2(mac, 0x056a, 0x0014);
5743 	BWN_WRITE_2(mac, 0x0568, 0x0826);
5744 	BWN_WRITE_2(mac, 0x0500, 0x0000);
5745 	if (phy->type == BWN_PHYTYPE_LP)
5746 		BWN_WRITE_2(mac, 0x0502, 0x0050);
5747 	else
5748 		BWN_WRITE_2(mac, 0x0502, 0x0030);
5749 
5750 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5751 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
5752 	for (i = 0x00; i < max_loop; i++) {
5753 		value = BWN_READ_2(mac, 0x050e);
5754 		if (value & 0x0080)
5755 			break;
5756 		DELAY(10);
5757 	}
5758 	for (i = 0x00; i < 0x0a; i++) {
5759 		value = BWN_READ_2(mac, 0x050e);
5760 		if (value & 0x0400)
5761 			break;
5762 		DELAY(10);
5763 	}
5764 	for (i = 0x00; i < 0x19; i++) {
5765 		value = BWN_READ_2(mac, 0x0690);
5766 		if (!(value & 0x0100))
5767 			break;
5768 		DELAY(10);
5769 	}
5770 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5771 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
5772 }
5773 
5774 static void
5775 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5776 {
5777 	uint32_t macctl;
5778 
5779 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5780 
5781 	macctl = BWN_READ_4(mac, BWN_MACCTL);
5782 	if (macctl & BWN_MACCTL_BIGENDIAN)
5783 		kprintf("TODO: need swap\n");
5784 
5785 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5786 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5787 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5788 }
5789 
5790 static void
5791 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5792 {
5793 	uint16_t value;
5794 
5795 	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5796 	    ("%s:%d: fail", __func__, __LINE__));
5797 
5798 	value = (uint8_t) (ctl->q);
5799 	value |= ((uint8_t) (ctl->i)) << 8;
5800 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5801 }
5802 
5803 static uint16_t
5804 bwn_lo_calcfeed(struct bwn_mac *mac,
5805     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5806 {
5807 	struct bwn_phy *phy = &mac->mac_phy;
5808 	struct bwn_softc *sc = mac->mac_sc;
5809 	uint16_t rfover;
5810 	uint16_t feedthrough;
5811 
5812 	if (phy->gmode) {
5813 		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5814 		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5815 
5816 		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5817 		    ("%s:%d: fail", __func__, __LINE__));
5818 		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5819 		    ("%s:%d: fail", __func__, __LINE__));
5820 
5821 		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5822 
5823 		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5824 		if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5825 		    phy->rev > 6)
5826 			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5827 
5828 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5829 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5830 		DELAY(10);
5831 		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5832 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5833 		DELAY(10);
5834 		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5835 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5836 		DELAY(10);
5837 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5838 	} else {
5839 		pga |= BWN_PHY_PGACTL_UNKNOWN;
5840 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5841 		DELAY(10);
5842 		pga |= BWN_PHY_PGACTL_LOWBANDW;
5843 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5844 		DELAY(10);
5845 		pga |= BWN_PHY_PGACTL_LPF;
5846 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5847 	}
5848 	DELAY(21);
5849 	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5850 
5851 	return (feedthrough);
5852 }
5853 
5854 static uint16_t
5855 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5856     uint16_t *value, uint16_t *pad_mix_gain)
5857 {
5858 	struct bwn_phy *phy = &mac->mac_phy;
5859 	uint16_t reg, v, padmix;
5860 
5861 	if (phy->type == BWN_PHYTYPE_B) {
5862 		v = 0x30;
5863 		if (phy->rf_rev <= 5) {
5864 			reg = 0x43;
5865 			padmix = 0;
5866 		} else {
5867 			reg = 0x52;
5868 			padmix = 5;
5869 		}
5870 	} else {
5871 		if (phy->rev >= 2 && phy->rf_rev == 8) {
5872 			reg = 0x43;
5873 			v = 0x10;
5874 			padmix = 2;
5875 		} else {
5876 			reg = 0x52;
5877 			v = 0x30;
5878 			padmix = 5;
5879 		}
5880 	}
5881 	if (value)
5882 		*value = v;
5883 	if (pad_mix_gain)
5884 		*pad_mix_gain = padmix;
5885 
5886 	return (reg);
5887 }
5888 
5889 static void
5890 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5891 {
5892 	struct bwn_phy *phy = &mac->mac_phy;
5893 	struct bwn_phy_g *pg = &phy->phy_g;
5894 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5895 	uint16_t reg, mask;
5896 	uint16_t trsw_rx, pga;
5897 	uint16_t rf_pctl_reg;
5898 
5899 	static const uint8_t tx_bias_values[] = {
5900 		0x09, 0x08, 0x0a, 0x01, 0x00,
5901 		0x02, 0x05, 0x04, 0x06,
5902 	};
5903 	static const uint8_t tx_magn_values[] = {
5904 		0x70, 0x40,
5905 	};
5906 
5907 	if (!BWN_HAS_LOOPBACK(phy)) {
5908 		rf_pctl_reg = 6;
5909 		trsw_rx = 2;
5910 		pga = 0;
5911 	} else {
5912 		int lb_gain;
5913 
5914 		trsw_rx = 0;
5915 		lb_gain = pg->pg_max_lb_gain / 2;
5916 		if (lb_gain > 10) {
5917 			rf_pctl_reg = 0;
5918 			pga = abs(10 - lb_gain) / 6;
5919 			pga = MIN(MAX(pga, 0), 15);
5920 		} else {
5921 			int cmp_val;
5922 			int tmp;
5923 
5924 			pga = 0;
5925 			cmp_val = 0x24;
5926 			if ((phy->rev >= 2) &&
5927 			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5928 				cmp_val = 0x3c;
5929 			tmp = lb_gain;
5930 			if ((10 - lb_gain) < cmp_val)
5931 				tmp = (10 - lb_gain);
5932 			if (tmp < 0)
5933 				tmp += 6;
5934 			else
5935 				tmp += 3;
5936 			cmp_val /= 4;
5937 			tmp /= 4;
5938 			if (tmp >= cmp_val)
5939 				rf_pctl_reg = cmp_val;
5940 			else
5941 				rf_pctl_reg = tmp;
5942 		}
5943 	}
5944 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5945 	bwn_phy_g_set_bbatt(mac, 2);
5946 
5947 	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5948 	mask = ~mask;
5949 	BWN_RF_MASK(mac, reg, mask);
5950 
5951 	if (BWN_HAS_TXMAG(phy)) {
5952 		int i, j;
5953 		int feedthrough;
5954 		int min_feedth = 0xffff;
5955 		uint8_t tx_magn, tx_bias;
5956 
5957 		for (i = 0; i < N(tx_magn_values); i++) {
5958 			tx_magn = tx_magn_values[i];
5959 			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5960 			for (j = 0; j < N(tx_bias_values); j++) {
5961 				tx_bias = tx_bias_values[j];
5962 				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5963 				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5964 				    trsw_rx);
5965 				if (feedthrough < min_feedth) {
5966 					lo->tx_bias = tx_bias;
5967 					lo->tx_magn = tx_magn;
5968 					min_feedth = feedthrough;
5969 				}
5970 				if (lo->tx_bias == 0)
5971 					break;
5972 			}
5973 			BWN_RF_WRITE(mac, 0x52,
5974 					  (BWN_RF_READ(mac, 0x52)
5975 					   & 0xff00) | lo->tx_bias | lo->
5976 					  tx_magn);
5977 		}
5978 	} else {
5979 		lo->tx_magn = 0;
5980 		lo->tx_bias = 0;
5981 		BWN_RF_MASK(mac, 0x52, 0xfff0);
5982 	}
5983 
5984 	BWN_GETTIME(lo->txctl_measured_time);
5985 }
5986 
5987 static void
5988 bwn_lo_get_powervector(struct bwn_mac *mac)
5989 {
5990 	struct bwn_phy *phy = &mac->mac_phy;
5991 	struct bwn_phy_g *pg = &phy->phy_g;
5992 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5993 	int i;
5994 	uint64_t tmp;
5995 	uint64_t power_vector = 0;
5996 
5997 	for (i = 0; i < 8; i += 2) {
5998 		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5999 		power_vector |= (tmp << (i * 8));
6000 		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6001 	}
6002 	if (power_vector)
6003 		lo->power_vector = power_vector;
6004 
6005 	BWN_GETTIME(lo->pwr_vec_read_time);
6006 }
6007 
6008 static void
6009 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6010     int use_trsw_rx)
6011 {
6012 	struct bwn_phy *phy = &mac->mac_phy;
6013 	struct bwn_phy_g *pg = &phy->phy_g;
6014 	uint16_t tmp;
6015 
6016 	if (max_rx_gain < 0)
6017 		max_rx_gain = 0;
6018 
6019 	if (BWN_HAS_LOOPBACK(phy)) {
6020 		int trsw_rx = 0;
6021 		int trsw_rx_gain;
6022 
6023 		if (use_trsw_rx) {
6024 			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6025 			if (max_rx_gain >= trsw_rx_gain) {
6026 				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6027 				trsw_rx = 0x20;
6028 			}
6029 		} else
6030 			trsw_rx_gain = max_rx_gain;
6031 		if (trsw_rx_gain < 9) {
6032 			pg->pg_lna_lod_gain = 0;
6033 		} else {
6034 			pg->pg_lna_lod_gain = 1;
6035 			trsw_rx_gain -= 8;
6036 		}
6037 		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6038 		pg->pg_pga_gain = trsw_rx_gain / 3;
6039 		if (pg->pg_pga_gain >= 5) {
6040 			pg->pg_pga_gain -= 5;
6041 			pg->pg_lna_gain = 2;
6042 		} else
6043 			pg->pg_lna_gain = 0;
6044 	} else {
6045 		pg->pg_lna_gain = 0;
6046 		pg->pg_trsw_rx_gain = 0x20;
6047 		if (max_rx_gain >= 0x14) {
6048 			pg->pg_lna_lod_gain = 1;
6049 			pg->pg_pga_gain = 2;
6050 		} else if (max_rx_gain >= 0x12) {
6051 			pg->pg_lna_lod_gain = 1;
6052 			pg->pg_pga_gain = 1;
6053 		} else if (max_rx_gain >= 0xf) {
6054 			pg->pg_lna_lod_gain = 1;
6055 			pg->pg_pga_gain = 0;
6056 		} else {
6057 			pg->pg_lna_lod_gain = 0;
6058 			pg->pg_pga_gain = 0;
6059 		}
6060 	}
6061 
6062 	tmp = BWN_RF_READ(mac, 0x7a);
6063 	if (pg->pg_lna_lod_gain == 0)
6064 		tmp &= ~0x0008;
6065 	else
6066 		tmp |= 0x0008;
6067 	BWN_RF_WRITE(mac, 0x7a, tmp);
6068 }
6069 
6070 static void
6071 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6072 {
6073 	struct bwn_phy *phy = &mac->mac_phy;
6074 	struct bwn_phy_g *pg = &phy->phy_g;
6075 	struct bwn_softc *sc = mac->mac_sc;
6076 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6077 	struct timespec ts;
6078 	uint16_t tmp;
6079 
6080 	if (bwn_has_hwpctl(mac)) {
6081 		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6082 		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6083 		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6084 		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6085 		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6086 
6087 		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6088 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6089 		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6090 		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6091 	}
6092 	if (phy->type == BWN_PHYTYPE_B &&
6093 	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6094 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6095 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6096 	}
6097 	if (phy->rev >= 2) {
6098 		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6099 		sav->phy_analogoverval =
6100 		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6101 		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6102 		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6103 		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6104 		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6105 		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6106 
6107 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6108 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6109 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6110 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6111 		if (phy->type == BWN_PHYTYPE_G) {
6112 			if ((phy->rev >= 7) &&
6113 			    (siba_sprom_get_bf_lo(sc->sc_dev) &
6114 			     BWN_BFL_EXTLNA)) {
6115 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6116 			} else {
6117 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6118 			}
6119 		} else {
6120 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6121 		}
6122 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6123 	}
6124 	sav->reg0 = BWN_READ_2(mac, 0x3f4);
6125 	sav->reg1 = BWN_READ_2(mac, 0x3e2);
6126 	sav->rf0 = BWN_RF_READ(mac, 0x43);
6127 	sav->rf1 = BWN_RF_READ(mac, 0x7a);
6128 	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6129 	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6130 	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6131 	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6132 
6133 	if (!BWN_HAS_TXMAG(phy)) {
6134 		sav->rf2 = BWN_RF_READ(mac, 0x52);
6135 		sav->rf2 &= 0x00f0;
6136 	}
6137 	if (phy->type == BWN_PHYTYPE_B) {
6138 		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6139 		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6140 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6141 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6142 	} else {
6143 		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6144 			    | 0x8000);
6145 	}
6146 	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6147 		    & 0xf000);
6148 
6149 	tmp =
6150 	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6151 	BWN_PHY_WRITE(mac, tmp, 0x007f);
6152 
6153 	tmp = sav->phy_syncctl;
6154 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6155 	tmp = sav->rf1;
6156 	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6157 
6158 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6159 	if (phy->type == BWN_PHYTYPE_G ||
6160 	    (phy->type == BWN_PHYTYPE_B &&
6161 	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6162 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6163 	} else
6164 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6165 	if (phy->rev >= 2)
6166 		bwn_dummy_transmission(mac, 0, 1);
6167 	bwn_phy_g_switch_chan(mac, 6, 0);
6168 	BWN_RF_READ(mac, 0x51);
6169 	if (phy->type == BWN_PHYTYPE_G)
6170 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6171 
6172 	nanouptime(&ts);
6173 	if (time_before(lo->txctl_measured_time,
6174 	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6175 		bwn_lo_measure_txctl_values(mac);
6176 
6177 	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6178 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6179 	else {
6180 		if (phy->type == BWN_PHYTYPE_B)
6181 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6182 		else
6183 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6184 	}
6185 }
6186 
6187 static void
6188 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6189 {
6190 	struct bwn_phy *phy = &mac->mac_phy;
6191 	struct bwn_phy_g *pg = &phy->phy_g;
6192 	uint16_t tmp;
6193 
6194 	if (phy->rev >= 2) {
6195 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6196 		tmp = (pg->pg_pga_gain << 8);
6197 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6198 		DELAY(5);
6199 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6200 		DELAY(2);
6201 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6202 	} else {
6203 		tmp = (pg->pg_pga_gain | 0xefa0);
6204 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6205 	}
6206 	if (phy->type == BWN_PHYTYPE_G) {
6207 		if (phy->rev >= 3)
6208 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6209 		else
6210 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6211 		if (phy->rev >= 2)
6212 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6213 		else
6214 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6215 	}
6216 	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6217 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6218 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6219 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6220 	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6221 	BWN_RF_WRITE(mac, 0x43, sav->rf0);
6222 	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6223 	if (!BWN_HAS_TXMAG(phy)) {
6224 		tmp = sav->rf2;
6225 		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6226 	}
6227 	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6228 	if (phy->type == BWN_PHYTYPE_B &&
6229 	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6230 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6231 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6232 	}
6233 	if (phy->rev >= 2) {
6234 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6235 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6236 			      sav->phy_analogoverval);
6237 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6238 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6239 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6240 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6241 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6242 	}
6243 	if (bwn_has_hwpctl(mac)) {
6244 		tmp = (sav->phy_lomask & 0xbfff);
6245 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6246 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6247 		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6248 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6249 		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6250 	}
6251 	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6252 }
6253 
6254 static int
6255 bwn_lo_probe_loctl(struct bwn_mac *mac,
6256     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6257 {
6258 	struct bwn_phy *phy = &mac->mac_phy;
6259 	struct bwn_phy_g *pg = &phy->phy_g;
6260 	struct bwn_loctl orig, test;
6261 	struct bwn_loctl prev = { -100, -100 };
6262 	static const struct bwn_loctl modifiers[] = {
6263 		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6264 		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6265 	};
6266 	int begin, end, lower = 0, i;
6267 	uint16_t feedth;
6268 
6269 	if (d->curstate == 0) {
6270 		begin = 1;
6271 		end = 8;
6272 	} else if (d->curstate % 2 == 0) {
6273 		begin = d->curstate - 1;
6274 		end = d->curstate + 1;
6275 	} else {
6276 		begin = d->curstate - 2;
6277 		end = d->curstate + 2;
6278 	}
6279 	if (begin < 1)
6280 		begin += 8;
6281 	if (end > 8)
6282 		end -= 8;
6283 
6284 	memcpy(&orig, probe, sizeof(struct bwn_loctl));
6285 	i = begin;
6286 	d->curstate = i;
6287 	while (1) {
6288 		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6289 		memcpy(&test, &orig, sizeof(struct bwn_loctl));
6290 		test.i += modifiers[i - 1].i * d->multipler;
6291 		test.q += modifiers[i - 1].q * d->multipler;
6292 		if ((test.i != prev.i || test.q != prev.q) &&
6293 		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6294 			bwn_lo_write(mac, &test);
6295 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6296 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6297 			if (feedth < d->feedth) {
6298 				memcpy(probe, &test,
6299 				    sizeof(struct bwn_loctl));
6300 				lower = 1;
6301 				d->feedth = feedth;
6302 				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6303 					break;
6304 			}
6305 		}
6306 		memcpy(&prev, &test, sizeof(prev));
6307 		if (i == end)
6308 			break;
6309 		if (i == 8)
6310 			i = 1;
6311 		else
6312 			i++;
6313 		d->curstate = i;
6314 	}
6315 
6316 	return (lower);
6317 }
6318 
6319 static void
6320 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6321 {
6322 	struct bwn_phy *phy = &mac->mac_phy;
6323 	struct bwn_phy_g *pg = &phy->phy_g;
6324 	struct bwn_lo_g_sm d;
6325 	struct bwn_loctl probe;
6326 	int lower, repeat, cnt = 0;
6327 	uint16_t feedth;
6328 
6329 	d.nmeasure = 0;
6330 	d.multipler = 1;
6331 	if (BWN_HAS_LOOPBACK(phy))
6332 		d.multipler = 3;
6333 
6334 	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6335 	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6336 
6337 	do {
6338 		bwn_lo_write(mac, &d.loctl);
6339 		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6340 		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6341 		if (feedth < 0x258) {
6342 			if (feedth >= 0x12c)
6343 				*rxgain += 6;
6344 			else
6345 				*rxgain += 3;
6346 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6347 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6348 		}
6349 		d.feedth = feedth;
6350 		d.curstate = 0;
6351 		do {
6352 			KASSERT(d.curstate >= 0 && d.curstate <= 8,
6353 			    ("%s:%d: fail", __func__, __LINE__));
6354 			memcpy(&probe, &d.loctl,
6355 			       sizeof(struct bwn_loctl));
6356 			lower = bwn_lo_probe_loctl(mac, &probe, &d);
6357 			if (!lower)
6358 				break;
6359 			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6360 				break;
6361 			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6362 			d.nmeasure++;
6363 		} while (d.nmeasure < 24);
6364 		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6365 
6366 		if (BWN_HAS_LOOPBACK(phy)) {
6367 			if (d.feedth > 0x1194)
6368 				*rxgain -= 6;
6369 			else if (d.feedth < 0x5dc)
6370 				*rxgain += 3;
6371 			if (cnt == 0) {
6372 				if (d.feedth <= 0x5dc) {
6373 					d.multipler = 1;
6374 					cnt++;
6375 				} else
6376 					d.multipler = 2;
6377 			} else if (cnt == 2)
6378 				d.multipler = 1;
6379 		}
6380 		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6381 	} while (++cnt < repeat);
6382 }
6383 
6384 static struct bwn_lo_calib *
6385 bwn_lo_calibset(struct bwn_mac *mac,
6386     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6387 {
6388 	struct bwn_phy *phy = &mac->mac_phy;
6389 	struct bwn_phy_g *pg = &phy->phy_g;
6390 	struct bwn_loctl loctl = { 0, 0 };
6391 	struct bwn_lo_calib *cal;
6392 	struct bwn_lo_g_value sval = { 0 };
6393 	int rxgain;
6394 	uint16_t pad, reg, value;
6395 
6396 	sval.old_channel = phy->chan;
6397 	bwn_mac_suspend(mac);
6398 	bwn_lo_save(mac, &sval);
6399 
6400 	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6401 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6402 	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6403 
6404 	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6405 	if (rfatt->padmix)
6406 		rxgain -= pad;
6407 	if (BWN_HAS_LOOPBACK(phy))
6408 		rxgain += pg->pg_max_lb_gain;
6409 	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6410 	bwn_phy_g_set_bbatt(mac, bbatt->att);
6411 	bwn_lo_probe_sm(mac, &loctl, &rxgain);
6412 
6413 	bwn_lo_restore(mac, &sval);
6414 	bwn_mac_enable(mac);
6415 
6416 	cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO);
6417 	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6418 	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6419 	memcpy(&cal->ctl, &loctl, sizeof(loctl));
6420 
6421 	BWN_GETTIME(cal->calib_time);
6422 
6423 	return (cal);
6424 }
6425 
6426 static struct bwn_lo_calib *
6427 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6428     const struct bwn_rfatt *rfatt)
6429 {
6430 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6431 	struct bwn_lo_calib *c;
6432 
6433 	TAILQ_FOREACH(c, &lo->calib_list, list) {
6434 		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6435 			continue;
6436 		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6437 			continue;
6438 		return (c);
6439 	}
6440 
6441 	c = bwn_lo_calibset(mac, bbatt, rfatt);
6442 	if (c == NULL)	/* XXX ivadasz: can't happen */
6443 		return (NULL);
6444 	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6445 
6446 	return (c);
6447 }
6448 
6449 static void
6450 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6451 {
6452 	struct bwn_phy *phy = &mac->mac_phy;
6453 	struct bwn_phy_g *pg = &phy->phy_g;
6454 	struct bwn_softc *sc = mac->mac_sc;
6455 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6456 	const struct bwn_rfatt *rfatt;
6457 	const struct bwn_bbatt *bbatt;
6458 	uint64_t pvector;
6459 	int i;
6460 	int rf_offset, bb_offset;
6461 	uint8_t changed = 0;
6462 
6463 	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6464 	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6465 	    ("%s:%d: fail", __func__, __LINE__));
6466 
6467 	pvector = lo->power_vector;
6468 	if (!update && !pvector)
6469 		return;
6470 
6471 	bwn_mac_suspend(mac);
6472 
6473 	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6474 		struct bwn_lo_calib *cal;
6475 		int idx;
6476 		uint16_t val;
6477 
6478 		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6479 			continue;
6480 		bb_offset = i / lo->rfatt.len;
6481 		rf_offset = i % lo->rfatt.len;
6482 		bbatt = &(lo->bbatt.array[bb_offset]);
6483 		rfatt = &(lo->rfatt.array[rf_offset]);
6484 
6485 		cal = bwn_lo_calibset(mac, bbatt, rfatt);
6486 		if (cal == NULL) {	/* XXX ivadasz: can't happen */
6487 			device_printf(sc->sc_dev, "LO: Could not "
6488 			    "calibrate DC table entry\n");
6489 			continue;
6490 		}
6491 		val = (uint8_t)(cal->ctl.q);
6492 		val |= ((uint8_t)(cal->ctl.i)) << 4;
6493 		kfree(cal, M_DEVBUF);
6494 
6495 		idx = i / 2;
6496 		if (i % 2)
6497 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6498 			    | ((val & 0x00ff) << 8);
6499 		else
6500 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6501 			    | (val & 0x00ff);
6502 		changed = 1;
6503 	}
6504 	if (changed) {
6505 		for (i = 0; i < BWN_DC_LT_SIZE; i++)
6506 			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6507 	}
6508 	bwn_mac_enable(mac);
6509 }
6510 
6511 static void
6512 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6513 {
6514 
6515 	if (!rf->padmix)
6516 		return;
6517 	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6518 		rf->att = 4;
6519 }
6520 
6521 static void
6522 bwn_lo_g_adjust(struct bwn_mac *mac)
6523 {
6524 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6525 	struct bwn_lo_calib *cal;
6526 	struct bwn_rfatt rf;
6527 
6528 	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6529 	bwn_lo_fixup_rfatt(&rf);
6530 
6531 	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6532 	if (cal == NULL)	/* XXX ivadasz: can't happen */
6533 		return;
6534 	bwn_lo_write(mac, &cal->ctl);
6535 }
6536 
6537 static void
6538 bwn_lo_g_init(struct bwn_mac *mac)
6539 {
6540 
6541 	if (!bwn_has_hwpctl(mac))
6542 		return;
6543 
6544 	bwn_lo_get_powervector(mac);
6545 	bwn_phy_g_dc_lookup_init(mac, 1);
6546 }
6547 
6548 static void
6549 bwn_mac_suspend(struct bwn_mac *mac)
6550 {
6551 	struct bwn_softc *sc = mac->mac_sc;
6552 	int i;
6553 	uint32_t tmp;
6554 
6555 	KASSERT(mac->mac_suspended >= 0,
6556 	    ("%s:%d: fail", __func__, __LINE__));
6557 
6558 	if (mac->mac_suspended == 0) {
6559 		bwn_psctl(mac, BWN_PS_AWAKE);
6560 		BWN_WRITE_4(mac, BWN_MACCTL,
6561 			    BWN_READ_4(mac, BWN_MACCTL)
6562 			    & ~BWN_MACCTL_ON);
6563 		BWN_READ_4(mac, BWN_MACCTL);
6564 		for (i = 35; i; i--) {
6565 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6566 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6567 				goto out;
6568 			DELAY(10);
6569 		}
6570 		for (i = 40; i; i--) {
6571 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6572 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6573 				goto out;
6574 			DELAY(1000);
6575 		}
6576 		device_printf(sc->sc_dev, "MAC suspend failed\n");
6577 	}
6578 out:
6579 	mac->mac_suspended++;
6580 }
6581 
6582 static void
6583 bwn_mac_enable(struct bwn_mac *mac)
6584 {
6585 	struct bwn_softc *sc = mac->mac_sc;
6586 	uint16_t state;
6587 
6588 	state = bwn_shm_read_2(mac, BWN_SHARED,
6589 	    BWN_SHARED_UCODESTAT);
6590 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6591 	    state != BWN_SHARED_UCODESTAT_SLEEP)
6592 		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6593 
6594 	mac->mac_suspended--;
6595 	KASSERT(mac->mac_suspended >= 0,
6596 	    ("%s:%d: fail", __func__, __LINE__));
6597 	if (mac->mac_suspended == 0) {
6598 		BWN_WRITE_4(mac, BWN_MACCTL,
6599 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6600 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6601 		BWN_READ_4(mac, BWN_MACCTL);
6602 		BWN_READ_4(mac, BWN_INTR_REASON);
6603 		bwn_psctl(mac, 0);
6604 	}
6605 }
6606 
6607 static void
6608 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6609 {
6610 	struct bwn_softc *sc = mac->mac_sc;
6611 	int i;
6612 	uint16_t ucstat;
6613 
6614 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6615 	    ("%s:%d: fail", __func__, __LINE__));
6616 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6617 	    ("%s:%d: fail", __func__, __LINE__));
6618 
6619 	/* XXX forcibly awake and hwps-off */
6620 
6621 	BWN_WRITE_4(mac, BWN_MACCTL,
6622 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6623 	    ~BWN_MACCTL_HWPS);
6624 	BWN_READ_4(mac, BWN_MACCTL);
6625 	if (siba_get_revid(sc->sc_dev) >= 5) {
6626 		for (i = 0; i < 100; i++) {
6627 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6628 			    BWN_SHARED_UCODESTAT);
6629 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6630 				break;
6631 			DELAY(10);
6632 		}
6633 	}
6634 }
6635 
6636 static int16_t
6637 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6638 {
6639 
6640 	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6641 	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6642 }
6643 
6644 static void
6645 bwn_nrssi_threshold(struct bwn_mac *mac)
6646 {
6647 	struct bwn_phy *phy = &mac->mac_phy;
6648 	struct bwn_phy_g *pg = &phy->phy_g;
6649 	struct bwn_softc *sc = mac->mac_sc;
6650 	int32_t a, b;
6651 	int16_t tmp16;
6652 	uint16_t tmpu16;
6653 
6654 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6655 
6656 	if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6657 		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6658 			a = 0x13;
6659 			b = 0x12;
6660 		} else {
6661 			a = 0xe;
6662 			b = 0x11;
6663 		}
6664 
6665 		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6666 		a += (pg->pg_nrssi[0] << 6);
6667 		a += (a < 32) ? 31 : 32;
6668 		a = a >> 6;
6669 		a = MIN(MAX(a, -31), 31);
6670 
6671 		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6672 		b += (pg->pg_nrssi[0] << 6);
6673 		if (b < 32)
6674 			b += 31;
6675 		else
6676 			b += 32;
6677 		b = b >> 6;
6678 		b = MIN(MAX(b, -31), 31);
6679 
6680 		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6681 		tmpu16 |= ((uint32_t)b & 0x0000003f);
6682 		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6683 		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6684 		return;
6685 	}
6686 
6687 	tmp16 = bwn_nrssi_read(mac, 0x20);
6688 	if (tmp16 >= 0x20)
6689 		tmp16 -= 0x40;
6690 	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6691 }
6692 
6693 static void
6694 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6695 {
6696 #define	SAVE_RF_MAX		3
6697 #define	SAVE_PHY_COMM_MAX	4
6698 #define	SAVE_PHY3_MAX		8
6699 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6700 		{ 0x7a, 0x52, 0x43 };
6701 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6702 		{ 0x15, 0x5a, 0x59, 0x58 };
6703 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6704 		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6705 		0x0801, 0x0060, 0x0014, 0x0478
6706 	};
6707 	struct bwn_phy *phy = &mac->mac_phy;
6708 	struct bwn_phy_g *pg = &phy->phy_g;
6709 	int32_t i, tmp32, phy3_idx = 0;
6710 	uint16_t delta, tmp;
6711 	uint16_t save_rf[SAVE_RF_MAX];
6712 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6713 	uint16_t save_phy3[SAVE_PHY3_MAX];
6714 	uint16_t ant_div, phy0, chan_ex;
6715 	int16_t nrssi0, nrssi1;
6716 
6717 	KASSERT(phy->type == BWN_PHYTYPE_G,
6718 	    ("%s:%d: fail", __func__, __LINE__));
6719 
6720 	if (phy->rf_rev >= 9)
6721 		return;
6722 	if (phy->rf_rev == 8)
6723 		bwn_nrssi_offset(mac);
6724 
6725 	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6726 	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6727 
6728 	/*
6729 	 * Save RF/PHY registers for later restoration
6730 	 */
6731 	ant_div = BWN_READ_2(mac, 0x03e2);
6732 	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6733 	for (i = 0; i < SAVE_RF_MAX; ++i)
6734 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6735 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6736 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6737 
6738 	phy0 = BWN_READ_2(mac, BWN_PHY0);
6739 	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6740 	if (phy->rev >= 3) {
6741 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
6742 			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6743 		BWN_PHY_WRITE(mac, 0x002e, 0);
6744 		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6745 		switch (phy->rev) {
6746 		case 4:
6747 		case 6:
6748 		case 7:
6749 			BWN_PHY_SET(mac, 0x0478, 0x0100);
6750 			BWN_PHY_SET(mac, 0x0801, 0x0040);
6751 			break;
6752 		case 3:
6753 		case 5:
6754 			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6755 			break;
6756 		}
6757 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6758 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6759 	}
6760 	/*
6761 	 * Calculate nrssi0
6762 	 */
6763 	BWN_RF_SET(mac, 0x007a, 0x0070);
6764 	bwn_set_all_gains(mac, 0, 8, 0);
6765 	BWN_RF_MASK(mac, 0x007a, 0x00f7);
6766 	if (phy->rev >= 2) {
6767 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6768 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6769 	}
6770 	BWN_RF_SET(mac, 0x007a, 0x0080);
6771 	DELAY(20);
6772 
6773 	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6774 	if (nrssi0 >= 0x0020)
6775 		nrssi0 -= 0x0040;
6776 
6777 	/*
6778 	 * Calculate nrssi1
6779 	 */
6780 	BWN_RF_MASK(mac, 0x007a, 0x007f);
6781 	if (phy->rev >= 2)
6782 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6783 
6784 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6785 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6786 	BWN_RF_SET(mac, 0x007a, 0x000f);
6787 	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6788 	if (phy->rev >= 2) {
6789 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6790 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6791 	}
6792 
6793 	bwn_set_all_gains(mac, 3, 0, 1);
6794 	if (phy->rf_rev == 8) {
6795 		BWN_RF_WRITE(mac, 0x0043, 0x001f);
6796 	} else {
6797 		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6798 		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6799 		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6800 		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6801 	}
6802 	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6803 	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6804 	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6805 	DELAY(20);
6806 	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6807 
6808 	/*
6809 	 * Install calculated narrow RSSI values
6810 	 */
6811 	if (nrssi1 >= 0x0020)
6812 		nrssi1 -= 0x0040;
6813 	if (nrssi0 == nrssi1)
6814 		pg->pg_nrssi_slope = 0x00010000;
6815 	else
6816 		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6817 	if (nrssi0 >= -4) {
6818 		pg->pg_nrssi[0] = nrssi1;
6819 		pg->pg_nrssi[1] = nrssi0;
6820 	}
6821 
6822 	/*
6823 	 * Restore saved RF/PHY registers
6824 	 */
6825 	if (phy->rev >= 3) {
6826 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6827 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6828 			    save_phy3[phy3_idx]);
6829 		}
6830 	}
6831 	if (phy->rev >= 2) {
6832 		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6833 		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6834 	}
6835 
6836 	for (i = 0; i < SAVE_RF_MAX; ++i)
6837 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6838 
6839 	BWN_WRITE_2(mac, 0x03e2, ant_div);
6840 	BWN_WRITE_2(mac, 0x03e6, phy0);
6841 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6842 
6843 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6844 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6845 
6846 	bwn_spu_workaround(mac, phy->chan);
6847 	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6848 	bwn_set_original_gains(mac);
6849 	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6850 	if (phy->rev >= 3) {
6851 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6852 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6853 			    save_phy3[phy3_idx]);
6854 		}
6855 	}
6856 
6857 	delta = 0x1f - pg->pg_nrssi[0];
6858 	for (i = 0; i < 64; i++) {
6859 		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6860 		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6861 		pg->pg_nrssi_lt[i] = tmp32;
6862 	}
6863 
6864 	bwn_nrssi_threshold(mac);
6865 #undef SAVE_RF_MAX
6866 #undef SAVE_PHY_COMM_MAX
6867 #undef SAVE_PHY3_MAX
6868 }
6869 
6870 static void
6871 bwn_nrssi_offset(struct bwn_mac *mac)
6872 {
6873 #define	SAVE_RF_MAX		2
6874 #define	SAVE_PHY_COMM_MAX	10
6875 #define	SAVE_PHY6_MAX		8
6876 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6877 		{ 0x7a, 0x43 };
6878 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6879 		0x0001, 0x0811, 0x0812, 0x0814,
6880 		0x0815, 0x005a, 0x0059, 0x0058,
6881 		0x000a, 0x0003
6882 	};
6883 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6884 		0x002e, 0x002f, 0x080f, 0x0810,
6885 		0x0801, 0x0060, 0x0014, 0x0478
6886 	};
6887 	struct bwn_phy *phy = &mac->mac_phy;
6888 	int i, phy6_idx = 0;
6889 	uint16_t save_rf[SAVE_RF_MAX];
6890 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6891 	uint16_t save_phy6[SAVE_PHY6_MAX];
6892 	int16_t nrssi;
6893 	uint16_t saved = 0xffff;
6894 
6895 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6896 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6897 	for (i = 0; i < SAVE_RF_MAX; ++i)
6898 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6899 
6900 	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6901 	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6902 	BWN_PHY_SET(mac, 0x0811, 0x000c);
6903 	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6904 	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6905 	if (phy->rev >= 6) {
6906 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
6907 			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6908 
6909 		BWN_PHY_WRITE(mac, 0x002e, 0);
6910 		BWN_PHY_WRITE(mac, 0x002f, 0);
6911 		BWN_PHY_WRITE(mac, 0x080f, 0);
6912 		BWN_PHY_WRITE(mac, 0x0810, 0);
6913 		BWN_PHY_SET(mac, 0x0478, 0x0100);
6914 		BWN_PHY_SET(mac, 0x0801, 0x0040);
6915 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6916 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6917 	}
6918 	BWN_RF_SET(mac, 0x007a, 0x0070);
6919 	BWN_RF_SET(mac, 0x007a, 0x0080);
6920 	DELAY(30);
6921 
6922 	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6923 	if (nrssi >= 0x20)
6924 		nrssi -= 0x40;
6925 	if (nrssi == 31) {
6926 		for (i = 7; i >= 4; i--) {
6927 			BWN_RF_WRITE(mac, 0x007b, i);
6928 			DELAY(20);
6929 			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6930 			    0x003f);
6931 			if (nrssi >= 0x20)
6932 				nrssi -= 0x40;
6933 			if (nrssi < 31 && saved == 0xffff)
6934 				saved = i;
6935 		}
6936 		if (saved == 0xffff)
6937 			saved = 4;
6938 	} else {
6939 		BWN_RF_MASK(mac, 0x007a, 0x007f);
6940 		if (phy->rev != 1) {
6941 			BWN_PHY_SET(mac, 0x0814, 0x0001);
6942 			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6943 		}
6944 		BWN_PHY_SET(mac, 0x0811, 0x000c);
6945 		BWN_PHY_SET(mac, 0x0812, 0x000c);
6946 		BWN_PHY_SET(mac, 0x0811, 0x0030);
6947 		BWN_PHY_SET(mac, 0x0812, 0x0030);
6948 		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6949 		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6950 		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6951 		if (phy->rev == 0)
6952 			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6953 		else
6954 			BWN_PHY_SET(mac, 0x000a, 0x2000);
6955 		if (phy->rev != 1) {
6956 			BWN_PHY_SET(mac, 0x0814, 0x0004);
6957 			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6958 		}
6959 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6960 		BWN_RF_SET(mac, 0x007a, 0x000f);
6961 		bwn_set_all_gains(mac, 3, 0, 1);
6962 		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6963 		DELAY(30);
6964 		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6965 		if (nrssi >= 0x20)
6966 			nrssi -= 0x40;
6967 		if (nrssi == -32) {
6968 			for (i = 0; i < 4; i++) {
6969 				BWN_RF_WRITE(mac, 0x007b, i);
6970 				DELAY(20);
6971 				nrssi = (int16_t)((BWN_PHY_READ(mac,
6972 				    0x047f) >> 8) & 0x003f);
6973 				if (nrssi >= 0x20)
6974 					nrssi -= 0x40;
6975 				if (nrssi > -31 && saved == 0xffff)
6976 					saved = i;
6977 			}
6978 			if (saved == 0xffff)
6979 				saved = 3;
6980 		} else
6981 			saved = 0;
6982 	}
6983 	BWN_RF_WRITE(mac, 0x007b, saved);
6984 
6985 	/*
6986 	 * Restore saved RF/PHY registers
6987 	 */
6988 	if (phy->rev >= 6) {
6989 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6990 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6991 			    save_phy6[phy6_idx]);
6992 		}
6993 	}
6994 	if (phy->rev != 1) {
6995 		for (i = 3; i < 5; i++)
6996 			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6997 			    save_phy_comm[i]);
6998 	}
6999 	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7000 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7001 
7002 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7003 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7004 
7005 	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7006 	BWN_PHY_SET(mac, 0x0429, 0x8000);
7007 	bwn_set_original_gains(mac);
7008 	if (phy->rev >= 6) {
7009 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7010 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7011 			    save_phy6[phy6_idx]);
7012 		}
7013 	}
7014 
7015 	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7016 	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7017 	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7018 }
7019 
7020 static void
7021 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7022     int16_t third)
7023 {
7024 	struct bwn_phy *phy = &mac->mac_phy;
7025 	uint16_t i;
7026 	uint16_t start = 0x08, end = 0x18;
7027 	uint16_t tmp;
7028 	uint16_t table;
7029 
7030 	if (phy->rev <= 1) {
7031 		start = 0x10;
7032 		end = 0x20;
7033 	}
7034 
7035 	table = BWN_OFDMTAB_GAINX;
7036 	if (phy->rev <= 1)
7037 		table = BWN_OFDMTAB_GAINX_R1;
7038 	for (i = 0; i < 4; i++)
7039 		bwn_ofdmtab_write_2(mac, table, i, first);
7040 
7041 	for (i = start; i < end; i++)
7042 		bwn_ofdmtab_write_2(mac, table, i, second);
7043 
7044 	if (third != -1) {
7045 		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7046 		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7047 		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7048 		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7049 	}
7050 	bwn_dummy_transmission(mac, 0, 1);
7051 }
7052 
7053 static void
7054 bwn_set_original_gains(struct bwn_mac *mac)
7055 {
7056 	struct bwn_phy *phy = &mac->mac_phy;
7057 	uint16_t i, tmp;
7058 	uint16_t table;
7059 	uint16_t start = 0x0008, end = 0x0018;
7060 
7061 	if (phy->rev <= 1) {
7062 		start = 0x0010;
7063 		end = 0x0020;
7064 	}
7065 
7066 	table = BWN_OFDMTAB_GAINX;
7067 	if (phy->rev <= 1)
7068 		table = BWN_OFDMTAB_GAINX_R1;
7069 	for (i = 0; i < 4; i++) {
7070 		tmp = (i & 0xfffc);
7071 		tmp |= (i & 0x0001) << 1;
7072 		tmp |= (i & 0x0002) >> 1;
7073 
7074 		bwn_ofdmtab_write_2(mac, table, i, tmp);
7075 	}
7076 
7077 	for (i = start; i < end; i++)
7078 		bwn_ofdmtab_write_2(mac, table, i, i - start);
7079 
7080 	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7081 	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7082 	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7083 	bwn_dummy_transmission(mac, 0, 1);
7084 }
7085 
7086 static void
7087 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7088 {
7089 	struct bwn_phy *phy = &mac->mac_phy;
7090 	struct bwn_phy_g *pg = &phy->phy_g;
7091 	struct bwn_rfatt old_rfatt, rfatt;
7092 	struct bwn_bbatt old_bbatt, bbatt;
7093 	struct bwn_softc *sc = mac->mac_sc;
7094 	uint8_t old_txctl = 0;
7095 
7096 	KASSERT(phy->type == BWN_PHYTYPE_G,
7097 	    ("%s:%d: fail", __func__, __LINE__));
7098 
7099 	if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7100 	    (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7101 		return;
7102 
7103 	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7104 
7105 	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7106 
7107 	if (!phy->gmode)
7108 		return;
7109 	bwn_hwpctl_early_init(mac);
7110 	if (pg->pg_curtssi == 0) {
7111 		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7112 			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7113 		} else {
7114 			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7115 			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7116 			old_txctl = pg->pg_txctl;
7117 
7118 			bbatt.att = 11;
7119 			if (phy->rf_rev == 8) {
7120 				rfatt.att = 15;
7121 				rfatt.padmix = 1;
7122 			} else {
7123 				rfatt.att = 9;
7124 				rfatt.padmix = 0;
7125 			}
7126 			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7127 		}
7128 		bwn_dummy_transmission(mac, 0, 1);
7129 		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7130 		if (phy->rf_ver == 0x2050 && phy->analog == 0)
7131 			BWN_RF_MASK(mac, 0x0076, 0xff7b);
7132 		else
7133 			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7134 			    &old_rfatt, old_txctl);
7135 	}
7136 	bwn_hwpctl_init_gphy(mac);
7137 
7138 	/* clear TSSI */
7139 	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7140 	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7141 	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7142 	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7143 }
7144 
7145 static void
7146 bwn_hwpctl_early_init(struct bwn_mac *mac)
7147 {
7148 	struct bwn_phy *phy = &mac->mac_phy;
7149 
7150 	if (!bwn_has_hwpctl(mac)) {
7151 		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7152 		return;
7153 	}
7154 
7155 	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7156 	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7157 	BWN_PHY_SET(mac, 0x047c, 0x0002);
7158 	BWN_PHY_SET(mac, 0x047a, 0xf000);
7159 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7160 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7161 		BWN_PHY_SET(mac, 0x005d, 0x8000);
7162 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7163 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7164 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7165 	} else {
7166 		BWN_PHY_SET(mac, 0x0036, 0x0200);
7167 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7168 		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7169 		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7170 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7171 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7172 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7173 	}
7174 }
7175 
7176 static void
7177 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7178 {
7179 	struct bwn_phy *phy = &mac->mac_phy;
7180 	struct bwn_phy_g *pg = &phy->phy_g;
7181 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7182 	int i;
7183 	uint16_t nr_written = 0, tmp, value;
7184 	uint8_t rf, bb;
7185 
7186 	if (!bwn_has_hwpctl(mac)) {
7187 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7188 		return;
7189 	}
7190 
7191 	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7192 	    (pg->pg_idletssi - pg->pg_curtssi));
7193 	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7194 	    (pg->pg_idletssi - pg->pg_curtssi));
7195 
7196 	for (i = 0; i < 32; i++)
7197 		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7198 	for (i = 32; i < 64; i++)
7199 		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7200 	for (i = 0; i < 64; i += 2) {
7201 		value = (uint16_t) pg->pg_tssi2dbm[i];
7202 		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7203 		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7204 	}
7205 
7206 	for (rf = 0; rf < lo->rfatt.len; rf++) {
7207 		for (bb = 0; bb < lo->bbatt.len; bb++) {
7208 			if (nr_written >= 0x40)
7209 				return;
7210 			tmp = lo->bbatt.array[bb].att;
7211 			tmp <<= 8;
7212 			if (phy->rf_rev == 8)
7213 				tmp |= 0x50;
7214 			else
7215 				tmp |= 0x40;
7216 			tmp |= lo->rfatt.array[rf].att;
7217 			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7218 			nr_written++;
7219 		}
7220 	}
7221 
7222 	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7223 	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7224 
7225 	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7226 	BWN_PHY_SET(mac, 0x0478, 0x0800);
7227 	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7228 	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7229 
7230 	bwn_phy_g_dc_lookup_init(mac, 1);
7231 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7232 }
7233 
7234 static void
7235 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7236 {
7237 	struct bwn_softc *sc = mac->mac_sc;
7238 
7239 	if (spu != 0)
7240 		bwn_spu_workaround(mac, channel);
7241 
7242 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7243 
7244 	if (channel == 14) {
7245 		if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7246 			bwn_hf_write(mac,
7247 			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7248 		else
7249 			bwn_hf_write(mac,
7250 			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7251 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7252 		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7253 		return;
7254 	}
7255 
7256 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7257 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7258 }
7259 
7260 static uint16_t
7261 bwn_phy_g_chan2freq(uint8_t channel)
7262 {
7263 	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7264 
7265 	KASSERT(channel >= 1 && channel <= 14,
7266 	    ("%s:%d: fail", __func__, __LINE__));
7267 
7268 	return (bwn_phy_g_rf_channels[channel - 1]);
7269 }
7270 
7271 static void
7272 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7273     const struct bwn_rfatt *rfatt, uint8_t txctl)
7274 {
7275 	struct bwn_phy *phy = &mac->mac_phy;
7276 	struct bwn_phy_g *pg = &phy->phy_g;
7277 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7278 	uint16_t bb, rf;
7279 	uint16_t tx_bias, tx_magn;
7280 
7281 	bb = bbatt->att;
7282 	rf = rfatt->att;
7283 	tx_bias = lo->tx_bias;
7284 	tx_magn = lo->tx_magn;
7285 	if (tx_bias == 0xff)
7286 		tx_bias = 0;
7287 
7288 	pg->pg_txctl = txctl;
7289 	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7290 	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7291 	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7292 	bwn_phy_g_set_bbatt(mac, bb);
7293 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7294 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7295 		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7296 	else {
7297 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7298 		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7299 	}
7300 	if (BWN_HAS_TXMAG(phy))
7301 		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7302 	else
7303 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7304 	bwn_lo_g_adjust(mac);
7305 }
7306 
7307 static void
7308 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7309     uint16_t bbatt)
7310 {
7311 	struct bwn_phy *phy = &mac->mac_phy;
7312 
7313 	if (phy->analog == 0) {
7314 		BWN_WRITE_2(mac, BWN_PHY0,
7315 		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7316 		return;
7317 	}
7318 	if (phy->analog > 1) {
7319 		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7320 		return;
7321 	}
7322 	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7323 }
7324 
7325 static uint16_t
7326 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7327 {
7328 	struct bwn_phy *phy = &mac->mac_phy;
7329 	struct bwn_phy_g *pg = &phy->phy_g;
7330 	struct bwn_softc *sc = mac->mac_sc;
7331 	int max_lb_gain;
7332 	uint16_t extlna;
7333 	uint16_t i;
7334 
7335 	if (phy->gmode == 0)
7336 		return (0);
7337 
7338 	if (BWN_HAS_LOOPBACK(phy)) {
7339 		max_lb_gain = pg->pg_max_lb_gain;
7340 		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7341 		if (max_lb_gain >= 0x46) {
7342 			extlna = 0x3000;
7343 			max_lb_gain -= 0x46;
7344 		} else if (max_lb_gain >= 0x3a) {
7345 			extlna = 0x1000;
7346 			max_lb_gain -= 0x3a;
7347 		} else if (max_lb_gain >= 0x2e) {
7348 			extlna = 0x2000;
7349 			max_lb_gain -= 0x2e;
7350 		} else {
7351 			extlna = 0;
7352 			max_lb_gain -= 0x10;
7353 		}
7354 
7355 		for (i = 0; i < 16; i++) {
7356 			max_lb_gain -= (i * 6);
7357 			if (max_lb_gain < 6)
7358 				break;
7359 		}
7360 
7361 		if ((phy->rev < 7) ||
7362 		    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7363 			if (reg == BWN_PHY_RFOVER) {
7364 				return (0x1b3);
7365 			} else if (reg == BWN_PHY_RFOVERVAL) {
7366 				extlna |= (i << 8);
7367 				switch (lpd) {
7368 				case BWN_LPD(0, 1, 1):
7369 					return (0x0f92);
7370 				case BWN_LPD(0, 0, 1):
7371 				case BWN_LPD(1, 0, 1):
7372 					return (0x0092 | extlna);
7373 				case BWN_LPD(1, 0, 0):
7374 					return (0x0093 | extlna);
7375 				}
7376 				KASSERT(0 == 1,
7377 				    ("%s:%d: fail", __func__, __LINE__));
7378 			}
7379 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7380 		} else {
7381 			if (reg == BWN_PHY_RFOVER)
7382 				return (0x9b3);
7383 			if (reg == BWN_PHY_RFOVERVAL) {
7384 				if (extlna)
7385 					extlna |= 0x8000;
7386 				extlna |= (i << 8);
7387 				switch (lpd) {
7388 				case BWN_LPD(0, 1, 1):
7389 					return (0x8f92);
7390 				case BWN_LPD(0, 0, 1):
7391 					return (0x8092 | extlna);
7392 				case BWN_LPD(1, 0, 1):
7393 					return (0x2092 | extlna);
7394 				case BWN_LPD(1, 0, 0):
7395 					return (0x2093 | extlna);
7396 				}
7397 				KASSERT(0 == 1,
7398 				    ("%s:%d: fail", __func__, __LINE__));
7399 			}
7400 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7401 		}
7402 		return (0);
7403 	}
7404 
7405 	if ((phy->rev < 7) ||
7406 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7407 		if (reg == BWN_PHY_RFOVER) {
7408 			return (0x1b3);
7409 		} else if (reg == BWN_PHY_RFOVERVAL) {
7410 			switch (lpd) {
7411 			case BWN_LPD(0, 1, 1):
7412 				return (0x0fb2);
7413 			case BWN_LPD(0, 0, 1):
7414 				return (0x00b2);
7415 			case BWN_LPD(1, 0, 1):
7416 				return (0x30b2);
7417 			case BWN_LPD(1, 0, 0):
7418 				return (0x30b3);
7419 			}
7420 			KASSERT(0 == 1,
7421 			    ("%s:%d: fail", __func__, __LINE__));
7422 		}
7423 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7424 	} else {
7425 		if (reg == BWN_PHY_RFOVER) {
7426 			return (0x9b3);
7427 		} else if (reg == BWN_PHY_RFOVERVAL) {
7428 			switch (lpd) {
7429 			case BWN_LPD(0, 1, 1):
7430 				return (0x8fb2);
7431 			case BWN_LPD(0, 0, 1):
7432 				return (0x80b2);
7433 			case BWN_LPD(1, 0, 1):
7434 				return (0x20b2);
7435 			case BWN_LPD(1, 0, 0):
7436 				return (0x20b3);
7437 			}
7438 			KASSERT(0 == 1,
7439 			    ("%s:%d: fail", __func__, __LINE__));
7440 		}
7441 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7442 	}
7443 	return (0);
7444 }
7445 
7446 static void
7447 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7448 {
7449 
7450 	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7451 		return;
7452 	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7453 	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7454 	DELAY(1000);
7455 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7456 }
7457 
7458 static int
7459 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7460 {
7461 	struct bwn_softc *sc = mac->mac_sc;
7462 	struct bwn_fw *fw = &mac->mac_fw;
7463 	const uint8_t rev = siba_get_revid(sc->sc_dev);
7464 	const char *filename;
7465 	uint32_t high;
7466 	int error;
7467 
7468 	/* microcode */
7469 	if (rev >= 5 && rev <= 10)
7470 		filename = "ucode5";
7471 	else if (rev >= 11 && rev <= 12)
7472 		filename = "ucode11";
7473 	else if (rev == 13)
7474 		filename = "ucode13";
7475 	else if (rev == 14)
7476 		filename = "ucode14";
7477 	else if (rev >= 15)
7478 		filename = "ucode15";
7479 	else {
7480 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7481 		bwn_release_firmware(mac);
7482 		return (EOPNOTSUPP);
7483 	}
7484 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
7485 	if (error) {
7486 		bwn_release_firmware(mac);
7487 		return (error);
7488 	}
7489 
7490 	/* PCM */
7491 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7492 	if (rev >= 5 && rev <= 10) {
7493 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7494 		if (error == ENOENT)
7495 			fw->no_pcmfile = 1;
7496 		else if (error) {
7497 			bwn_release_firmware(mac);
7498 			return (error);
7499 		}
7500 	} else if (rev < 11) {
7501 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7502 		return (EOPNOTSUPP);
7503 	}
7504 
7505 	/* initvals */
7506 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7507 	switch (mac->mac_phy.type) {
7508 	case BWN_PHYTYPE_A:
7509 		if (rev < 5 || rev > 10)
7510 			goto fail1;
7511 		if (high & BWN_TGSHIGH_HAVE_2GHZ)
7512 			filename = "a0g1initvals5";
7513 		else
7514 			filename = "a0g0initvals5";
7515 		break;
7516 	case BWN_PHYTYPE_G:
7517 		if (rev >= 5 && rev <= 10)
7518 			filename = "b0g0initvals5";
7519 		else if (rev >= 13)
7520 			filename = "b0g0initvals13";
7521 		else
7522 			goto fail1;
7523 		break;
7524 	case BWN_PHYTYPE_LP:
7525 		if (rev == 13)
7526 			filename = "lp0initvals13";
7527 		else if (rev == 14)
7528 			filename = "lp0initvals14";
7529 		else if (rev >= 15)
7530 			filename = "lp0initvals15";
7531 		else
7532 			goto fail1;
7533 		break;
7534 	case BWN_PHYTYPE_N:
7535 		if (rev >= 11 && rev <= 12)
7536 			filename = "n0initvals11";
7537 		else
7538 			goto fail1;
7539 		break;
7540 	default:
7541 		goto fail1;
7542 	}
7543 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
7544 	if (error) {
7545 		bwn_release_firmware(mac);
7546 		return (error);
7547 	}
7548 
7549 	/* bandswitch initvals */
7550 	switch (mac->mac_phy.type) {
7551 	case BWN_PHYTYPE_A:
7552 		if (rev >= 5 && rev <= 10) {
7553 			if (high & BWN_TGSHIGH_HAVE_2GHZ)
7554 				filename = "a0g1bsinitvals5";
7555 			else
7556 				filename = "a0g0bsinitvals5";
7557 		} else if (rev >= 11)
7558 			filename = NULL;
7559 		else
7560 			goto fail1;
7561 		break;
7562 	case BWN_PHYTYPE_G:
7563 		if (rev >= 5 && rev <= 10)
7564 			filename = "b0g0bsinitvals5";
7565 		else if (rev >= 11)
7566 			filename = NULL;
7567 		else
7568 			goto fail1;
7569 		break;
7570 	case BWN_PHYTYPE_LP:
7571 		if (rev == 13)
7572 			filename = "lp0bsinitvals13";
7573 		else if (rev == 14)
7574 			filename = "lp0bsinitvals14";
7575 		else if (rev >= 15)
7576 			filename = "lp0bsinitvals15";
7577 		else
7578 			goto fail1;
7579 		break;
7580 	case BWN_PHYTYPE_N:
7581 		if (rev >= 11 && rev <= 12)
7582 			filename = "n0bsinitvals11";
7583 		else
7584 			goto fail1;
7585 		break;
7586 	default:
7587 		goto fail1;
7588 	}
7589 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7590 	if (error) {
7591 		bwn_release_firmware(mac);
7592 		return (error);
7593 	}
7594 	return (0);
7595 fail1:
7596 	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7597 	bwn_release_firmware(mac);
7598 	return (EOPNOTSUPP);
7599 }
7600 
7601 static int
7602 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7603     const char *name, struct bwn_fwfile *bfw)
7604 {
7605 	const struct bwn_fwhdr *hdr;
7606 	struct bwn_softc *sc = mac->mac_sc;
7607 	const struct firmware *fw;
7608 	char namebuf[64];
7609 
7610 	if (name == NULL) {
7611 		bwn_do_release_fw(bfw);
7612 		return (0);
7613 	}
7614 	if (bfw->filename != NULL) {
7615 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7616 			return (0);
7617 		bwn_do_release_fw(bfw);
7618 	}
7619 
7620 	ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7621 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7622 	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7623 	wlan_assert_serialized();
7624 	wlan_serialize_exit();
7625 	fw = firmware_get(namebuf);
7626 	wlan_serialize_enter();
7627 	if (fw == NULL) {
7628 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7629 		    namebuf);
7630 		return (ENOENT);
7631 	}
7632 	if (fw->datasize < sizeof(struct bwn_fwhdr))
7633 		goto fail;
7634 	hdr = (const struct bwn_fwhdr *)(fw->data);
7635 	switch (hdr->type) {
7636 	case BWN_FWTYPE_UCODE:
7637 	case BWN_FWTYPE_PCM:
7638 		if (be32toh(hdr->size) !=
7639 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
7640 			goto fail;
7641 		/* FALLTHROUGH */
7642 	case BWN_FWTYPE_IV:
7643 		if (hdr->ver != 1)
7644 			goto fail;
7645 		break;
7646 	default:
7647 		goto fail;
7648 	}
7649 	bfw->filename = name;
7650 	bfw->fw = fw;
7651 	bfw->type = type;
7652 	return (0);
7653 fail:
7654 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7655 	if (fw != NULL)
7656 		firmware_put(fw, FIRMWARE_UNLOAD);
7657 	return (EPROTO);
7658 }
7659 
7660 static void
7661 bwn_release_firmware(struct bwn_mac *mac)
7662 {
7663 
7664 	bwn_do_release_fw(&mac->mac_fw.ucode);
7665 	bwn_do_release_fw(&mac->mac_fw.pcm);
7666 	bwn_do_release_fw(&mac->mac_fw.initvals);
7667 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
7668 }
7669 
7670 static void
7671 bwn_do_release_fw(struct bwn_fwfile *bfw)
7672 {
7673 
7674 	if (bfw->fw != NULL)
7675 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7676 	bfw->fw = NULL;
7677 	bfw->filename = NULL;
7678 }
7679 
7680 static int
7681 bwn_fw_loaducode(struct bwn_mac *mac)
7682 {
7683 #define	GETFWOFFSET(fwp, offset)	\
7684 	((const uint32_t *)((const char *)fwp.fw->data + offset))
7685 #define	GETFWSIZE(fwp, offset)	\
7686 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
7687 	struct bwn_softc *sc = mac->mac_sc;
7688 	const uint32_t *data;
7689 	unsigned int i;
7690 	uint32_t ctl;
7691 	uint16_t date, fwcaps, time;
7692 	int error = 0;
7693 
7694 	ctl = BWN_READ_4(mac, BWN_MACCTL);
7695 	ctl |= BWN_MACCTL_MCODE_JMP0;
7696 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7697 	    __LINE__));
7698 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7699 	for (i = 0; i < 64; i++)
7700 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7701 	for (i = 0; i < 4096; i += 2)
7702 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7703 
7704 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7705 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7706 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7707 	     i++) {
7708 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7709 		DELAY(10);
7710 	}
7711 
7712 	if (mac->mac_fw.pcm.fw) {
7713 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7714 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7715 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7716 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7717 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7718 		    sizeof(struct bwn_fwhdr)); i++) {
7719 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7720 			DELAY(10);
7721 		}
7722 	}
7723 
7724 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7725 	BWN_WRITE_4(mac, BWN_MACCTL,
7726 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7727 	    BWN_MACCTL_MCODE_RUN);
7728 
7729 	for (i = 0; i < 21; i++) {
7730 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7731 			break;
7732 		if (i >= 20) {
7733 			device_printf(sc->sc_dev, "ucode timeout\n");
7734 			error = ENXIO;
7735 			goto error;
7736 		}
7737 		DELAY(50000);
7738 	}
7739 	BWN_READ_4(mac, BWN_INTR_REASON);
7740 
7741 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7742 	if (mac->mac_fw.rev <= 0x128) {
7743 		device_printf(sc->sc_dev, "the firmware is too old\n");
7744 		error = EOPNOTSUPP;
7745 		goto error;
7746 	}
7747 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7748 	    BWN_SHARED_UCODE_PATCH);
7749 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7750 	mac->mac_fw.opensource = (date == 0xffff);
7751 	if (bwn_wme != 0)
7752 		mac->mac_flags |= BWN_MAC_FLAG_WME;
7753 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7754 
7755 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7756 	if (mac->mac_fw.opensource == 0) {
7757 		device_printf(sc->sc_dev,
7758 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
7759 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7760 		if (mac->mac_fw.no_pcmfile)
7761 			device_printf(sc->sc_dev,
7762 			    "no HW crypto acceleration due to pcm5\n");
7763 	} else {
7764 		mac->mac_fw.patch = time;
7765 		fwcaps = bwn_fwcaps_read(mac);
7766 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7767 			device_printf(sc->sc_dev,
7768 			    "disabling HW crypto acceleration\n");
7769 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7770 		}
7771 		if (!(fwcaps & BWN_FWCAPS_WME)) {
7772 			device_printf(sc->sc_dev, "disabling WME support\n");
7773 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7774 		}
7775 	}
7776 
7777 	if (BWN_ISOLDFMT(mac))
7778 		device_printf(sc->sc_dev, "using old firmware image\n");
7779 
7780 	return (0);
7781 
7782 error:
7783 	BWN_WRITE_4(mac, BWN_MACCTL,
7784 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7785 	    BWN_MACCTL_MCODE_JMP0);
7786 
7787 	return (error);
7788 #undef GETFWSIZE
7789 #undef GETFWOFFSET
7790 }
7791 
7792 /* OpenFirmware only */
7793 static uint16_t
7794 bwn_fwcaps_read(struct bwn_mac *mac)
7795 {
7796 
7797 	KASSERT(mac->mac_fw.opensource == 1,
7798 	    ("%s:%d: fail", __func__, __LINE__));
7799 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7800 }
7801 
7802 static int
7803 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7804     size_t count, size_t array_size)
7805 {
7806 #define	GET_NEXTIV16(iv)						\
7807 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7808 	    sizeof(uint16_t) + sizeof(uint16_t)))
7809 #define	GET_NEXTIV32(iv)						\
7810 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7811 	    sizeof(uint16_t) + sizeof(uint32_t)))
7812 	struct bwn_softc *sc = mac->mac_sc;
7813 	const struct bwn_fwinitvals *iv;
7814 	uint16_t offset;
7815 	size_t i;
7816 	uint8_t bit32;
7817 
7818 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7819 	    ("%s:%d: fail", __func__, __LINE__));
7820 	iv = ivals;
7821 	for (i = 0; i < count; i++) {
7822 		if (array_size < sizeof(iv->offset_size))
7823 			goto fail;
7824 		array_size -= sizeof(iv->offset_size);
7825 		offset = be16toh(iv->offset_size);
7826 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7827 		offset &= BWN_FWINITVALS_OFFSET_MASK;
7828 		if (offset >= 0x1000)
7829 			goto fail;
7830 		if (bit32) {
7831 			if (array_size < sizeof(iv->data.d32))
7832 				goto fail;
7833 			array_size -= sizeof(iv->data.d32);
7834 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7835 			iv = GET_NEXTIV32(iv);
7836 		} else {
7837 
7838 			if (array_size < sizeof(iv->data.d16))
7839 				goto fail;
7840 			array_size -= sizeof(iv->data.d16);
7841 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7842 
7843 			iv = GET_NEXTIV16(iv);
7844 		}
7845 	}
7846 	if (array_size != 0)
7847 		goto fail;
7848 	return (0);
7849 fail:
7850 	device_printf(sc->sc_dev, "initvals: invalid format\n");
7851 	return (EPROTO);
7852 #undef GET_NEXTIV16
7853 #undef GET_NEXTIV32
7854 }
7855 
7856 static int
7857 bwn_switch_channel(struct bwn_mac *mac, int chan)
7858 {
7859 	struct bwn_phy *phy = &(mac->mac_phy);
7860 	struct bwn_softc *sc = mac->mac_sc;
7861 	struct ifnet *ifp = sc->sc_ifp;
7862 	struct ieee80211com *ic = ifp->if_l2com;
7863 	uint16_t channelcookie, savedcookie;
7864 	int error;
7865 
7866 	if (chan == 0xffff)
7867 		chan = phy->get_default_chan(mac);
7868 
7869 	channelcookie = chan;
7870 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7871 		channelcookie |= 0x100;
7872 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7873 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7874 	error = phy->switch_channel(mac, chan);
7875 	if (error)
7876 		goto fail;
7877 
7878 	mac->mac_phy.chan = chan;
7879 	DELAY(8000);
7880 	return (0);
7881 fail:
7882 	device_printf(sc->sc_dev, "failed to switch channel\n");
7883 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7884 	return (error);
7885 }
7886 
7887 static uint16_t
7888 bwn_ant2phy(int antenna)
7889 {
7890 
7891 	switch (antenna) {
7892 	case BWN_ANT0:
7893 		return (BWN_TX_PHY_ANT0);
7894 	case BWN_ANT1:
7895 		return (BWN_TX_PHY_ANT1);
7896 	case BWN_ANT2:
7897 		return (BWN_TX_PHY_ANT2);
7898 	case BWN_ANT3:
7899 		return (BWN_TX_PHY_ANT3);
7900 	case BWN_ANTAUTO:
7901 		return (BWN_TX_PHY_ANT01AUTO);
7902 	}
7903 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7904 	return (0);
7905 }
7906 
7907 static void
7908 bwn_wme_load(struct bwn_mac *mac)
7909 {
7910 	struct bwn_softc *sc = mac->mac_sc;
7911 	int i;
7912 
7913 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7914 	    ("%s:%d: fail", __func__, __LINE__));
7915 
7916 	bwn_mac_suspend(mac);
7917 	for (i = 0; i < N(sc->sc_wmeParams); i++)
7918 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7919 		    bwn_wme_shm_offsets[i]);
7920 	bwn_mac_enable(mac);
7921 }
7922 
7923 static void
7924 bwn_wme_loadparams(struct bwn_mac *mac,
7925     const struct wmeParams *p, uint16_t shm_offset)
7926 {
7927 #define	SM(_v, _f)      (((_v) << _f##_S) & _f)
7928 	struct bwn_softc *sc = mac->mac_sc;
7929 	uint16_t params[BWN_NR_WMEPARAMS];
7930 	int slot, tmp;
7931 	unsigned int i;
7932 
7933 	slot = BWN_READ_2(mac, BWN_RNG) &
7934 	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7935 
7936 	memset(&params, 0, sizeof(params));
7937 
7938 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7939 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7940 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7941 
7942 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7943 	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7944 	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7945 	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7946 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7947 	params[BWN_WMEPARAM_BSLOTS] = slot;
7948 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7949 
7950 	for (i = 0; i < N(params); i++) {
7951 		if (i == BWN_WMEPARAM_STATUS) {
7952 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
7953 			    shm_offset + (i * 2));
7954 			tmp |= 0x100;
7955 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7956 			    tmp);
7957 		} else {
7958 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7959 			    params[i]);
7960 		}
7961 	}
7962 }
7963 
7964 static void
7965 bwn_mac_write_bssid(struct bwn_mac *mac)
7966 {
7967 	struct bwn_softc *sc = mac->mac_sc;
7968 	uint32_t tmp;
7969 	int i;
7970 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7971 
7972 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7973 	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
7974 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7975 	    IEEE80211_ADDR_LEN);
7976 
7977 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7978 		tmp = (uint32_t) (mac_bssid[i + 0]);
7979 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7980 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7981 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7982 		bwn_ram_write(mac, 0x20 + i, tmp);
7983 	}
7984 }
7985 
7986 static void
7987 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7988     const uint8_t *macaddr)
7989 {
7990 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7991 	uint16_t data;
7992 
7993 	if (mac == NULL)
7994 		macaddr = zero;
7995 
7996 	offset |= 0x0020;
7997 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7998 
7999 	data = macaddr[0];
8000 	data |= macaddr[1] << 8;
8001 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8002 	data = macaddr[2];
8003 	data |= macaddr[3] << 8;
8004 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8005 	data = macaddr[4];
8006 	data |= macaddr[5] << 8;
8007 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8008 }
8009 
8010 static void
8011 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8012     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8013 {
8014 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8015 	uint8_t per_sta_keys_start = 8;
8016 
8017 	if (BWN_SEC_NEWAPI(mac))
8018 		per_sta_keys_start = 4;
8019 
8020 	KASSERT(index < mac->mac_max_nr_keys,
8021 	    ("%s:%d: fail", __func__, __LINE__));
8022 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
8023 	    ("%s:%d: fail", __func__, __LINE__));
8024 
8025 	if (index >= per_sta_keys_start)
8026 		bwn_key_macwrite(mac, index, NULL);
8027 	if (key)
8028 		memcpy(buf, key, key_len);
8029 	bwn_key_write(mac, index, algorithm, buf);
8030 	if (index >= per_sta_keys_start)
8031 		bwn_key_macwrite(mac, index, mac_addr);
8032 
8033 	mac->mac_key[index].algorithm = algorithm;
8034 }
8035 
8036 static void
8037 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8038 {
8039 	struct bwn_softc *sc = mac->mac_sc;
8040 	uint32_t addrtmp[2] = { 0, 0 };
8041 	uint8_t start = 8;
8042 
8043 	if (BWN_SEC_NEWAPI(mac))
8044 		start = 4;
8045 
8046 	KASSERT(index >= start,
8047 	    ("%s:%d: fail", __func__, __LINE__));
8048 	index -= start;
8049 
8050 	if (addr) {
8051 		addrtmp[0] = addr[0];
8052 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8053 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8054 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8055 		addrtmp[1] = addr[4];
8056 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8057 	}
8058 
8059 	if (siba_get_revid(sc->sc_dev) >= 5) {
8060 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8061 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8062 	} else {
8063 		if (index >= 8) {
8064 			bwn_shm_write_4(mac, BWN_SHARED,
8065 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8066 			bwn_shm_write_2(mac, BWN_SHARED,
8067 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8068 		}
8069 	}
8070 }
8071 
8072 static void
8073 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8074     const uint8_t *key)
8075 {
8076 	unsigned int i;
8077 	uint32_t offset;
8078 	uint16_t kidx, value;
8079 
8080 	kidx = BWN_SEC_KEY2FW(mac, index);
8081 	bwn_shm_write_2(mac, BWN_SHARED,
8082 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8083 
8084 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8085 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8086 		value = key[i];
8087 		value |= (uint16_t)(key[i + 1]) << 8;
8088 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8089 	}
8090 }
8091 
8092 static void
8093 bwn_phy_exit(struct bwn_mac *mac)
8094 {
8095 
8096 	mac->mac_phy.rf_onoff(mac, 0);
8097 	if (mac->mac_phy.exit != NULL)
8098 		mac->mac_phy.exit(mac);
8099 }
8100 
8101 static void
8102 bwn_dma_free(struct bwn_mac *mac)
8103 {
8104 	struct bwn_dma *dma;
8105 
8106 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8107 		return;
8108 	dma = &mac->mac_method.dma;
8109 
8110 	bwn_dma_ringfree(&dma->rx);
8111 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8112 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8113 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8114 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8115 	bwn_dma_ringfree(&dma->mcast);
8116 }
8117 
8118 static void
8119 bwn_core_stop(struct bwn_mac *mac)
8120 {
8121 	struct bwn_softc *sc = mac->mac_sc;
8122 
8123 	wlan_assert_serialized();
8124 
8125 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8126 		return;
8127 
8128 	callout_stop(&sc->sc_rfswitch_ch);
8129 	callout_stop(&sc->sc_task_ch);
8130 	callout_stop(&sc->sc_watchdog_ch);
8131 	sc->sc_watchdog_timer = 0;
8132 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8133 	BWN_READ_4(mac, BWN_INTR_MASK);
8134 	bwn_mac_suspend(mac);
8135 
8136 	mac->mac_status = BWN_MAC_STATUS_INITED;
8137 }
8138 
8139 static int
8140 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8141 {
8142 	struct bwn_mac *up_dev = NULL;
8143 	struct bwn_mac *down_dev;
8144 	struct bwn_mac *mac;
8145 	int err, status;
8146 	uint8_t gmode;
8147 
8148 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8149 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8150 		    mac->mac_phy.supports_2ghz) {
8151 			up_dev = mac;
8152 			gmode = 1;
8153 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8154 		    mac->mac_phy.supports_5ghz) {
8155 			up_dev = mac;
8156 			gmode = 0;
8157 		} else {
8158 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8159 			return (EINVAL);
8160 		}
8161 		if (up_dev != NULL)
8162 			break;
8163 	}
8164 	if (up_dev == NULL) {
8165 		device_printf(sc->sc_dev, "Could not find a device\n");
8166 		return (ENODEV);
8167 	}
8168 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8169 		return (0);
8170 
8171 	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8172 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8173 
8174 	down_dev = sc->sc_curmac;
8175 	status = down_dev->mac_status;
8176 	if (status >= BWN_MAC_STATUS_STARTED)
8177 		bwn_core_stop(down_dev);
8178 	if (status >= BWN_MAC_STATUS_INITED)
8179 		bwn_core_exit(down_dev);
8180 
8181 	if (down_dev != up_dev)
8182 		bwn_phy_reset(down_dev);
8183 
8184 	up_dev->mac_phy.gmode = gmode;
8185 	if (status >= BWN_MAC_STATUS_INITED) {
8186 		err = bwn_core_init(up_dev);
8187 		if (err) {
8188 			device_printf(sc->sc_dev,
8189 			    "fatal: failed to initialize for %s-GHz\n",
8190 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8191 			goto fail;
8192 		}
8193 	}
8194 	if (status >= BWN_MAC_STATUS_STARTED)
8195 		bwn_core_start(up_dev);
8196 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8197 	sc->sc_curmac = up_dev;
8198 
8199 	return (0);
8200 fail:
8201 	sc->sc_curmac = NULL;
8202 	return (err);
8203 }
8204 
8205 static void
8206 bwn_rf_turnon(struct bwn_mac *mac)
8207 {
8208 
8209 	bwn_mac_suspend(mac);
8210 	mac->mac_phy.rf_onoff(mac, 1);
8211 	mac->mac_phy.rf_on = 1;
8212 	bwn_mac_enable(mac);
8213 }
8214 
8215 static void
8216 bwn_rf_turnoff(struct bwn_mac *mac)
8217 {
8218 
8219 	bwn_mac_suspend(mac);
8220 	mac->mac_phy.rf_onoff(mac, 0);
8221 	mac->mac_phy.rf_on = 0;
8222 	bwn_mac_enable(mac);
8223 }
8224 
8225 static void
8226 bwn_phy_reset(struct bwn_mac *mac)
8227 {
8228 	struct bwn_softc *sc = mac->mac_sc;
8229 
8230 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8231 	    ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8232 	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8233 	DELAY(1000);
8234 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8235 	    (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8236 	    BWN_TGSLOW_PHYRESET);
8237 	DELAY(1000);
8238 }
8239 
8240 static int
8241 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8242 {
8243 	struct bwn_vap *bvp = BWN_VAP(vap);
8244 	struct ieee80211com *ic= vap->iv_ic;
8245 	struct ifnet *ifp = ic->ic_ifp;
8246 	enum ieee80211_state ostate = vap->iv_state;
8247 	struct bwn_softc *sc = ifp->if_softc;
8248 	struct bwn_mac *mac = sc->sc_curmac;
8249 	int error;
8250 
8251 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8252 	    ieee80211_state_name[vap->iv_state],
8253 	    ieee80211_state_name[nstate]);
8254 
8255 	error = bvp->bv_newstate(vap, nstate, arg);
8256 	if (error != 0)
8257 		return (error);
8258 
8259 	bwn_led_newstate(mac, nstate);
8260 
8261 	/*
8262 	 * Clear the BSSID when we stop a STA
8263 	 */
8264 	if (vap->iv_opmode == IEEE80211_M_STA) {
8265 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8266 			/*
8267 			 * Clear out the BSSID.  If we reassociate to
8268 			 * the same AP, this will reinialize things
8269 			 * correctly...
8270 			 */
8271 			if (ic->ic_opmode == IEEE80211_M_STA &&
8272 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8273 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8274 				bwn_set_macaddr(mac);
8275 			}
8276 		}
8277 	}
8278 
8279 	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8280 	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
8281 		/* XXX nothing to do? */
8282 	} else if (nstate == IEEE80211_S_RUN) {
8283 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8284 		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8285 		bwn_set_opmode(mac);
8286 		bwn_set_pretbtt(mac);
8287 		bwn_spu_setdelay(mac, 0);
8288 		bwn_set_macaddr(mac);
8289 	}
8290 
8291 	return (error);
8292 }
8293 
8294 static void
8295 bwn_set_pretbtt(struct bwn_mac *mac)
8296 {
8297 	struct bwn_softc *sc = mac->mac_sc;
8298 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8299 	uint16_t pretbtt;
8300 
8301 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8302 		pretbtt = 2;
8303 	else
8304 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8305 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8306 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8307 }
8308 
8309 static void
8310 bwn_intr(void *arg)
8311 {
8312 	struct bwn_mac *mac = arg;
8313 	struct bwn_softc *sc = mac->mac_sc;
8314 	uint32_t reason;
8315 
8316 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8317 	    (sc->sc_flags & BWN_FLAG_INVALID))
8318 		return;
8319 
8320 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
8321 	if (reason == 0xffffffff)	/* shared IRQ */
8322 		return;
8323 	reason &= mac->mac_intr_mask;
8324 	if (reason == 0)
8325 		return;
8326 
8327 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00;
8328 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8329 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8330 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8331 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8332 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8333 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8334 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8335 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8336 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8337 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8338 
8339 	/* Disable interrupts. */
8340 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8341 
8342 	mac->mac_reason_intr = reason;
8343 
8344 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8345 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8346 
8347 	taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
8348 	return;
8349 }
8350 
8351 static void
8352 bwn_intrtask(void *arg, int npending)
8353 {
8354 	struct bwn_mac *mac = arg;
8355 	struct bwn_softc *sc = mac->mac_sc;
8356 	struct ifnet *ifp = sc->sc_ifp;
8357 	uint32_t merged = 0;
8358 	int i, tx = 0, rx = 0;
8359 
8360 	wlan_serialize_enter();
8361 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8362 	    (sc->sc_flags & BWN_FLAG_INVALID)) {
8363 		wlan_serialize_exit();
8364 		return;
8365 	}
8366 
8367 	for (i = 0; i < N(mac->mac_reason); i++)
8368 		merged |= mac->mac_reason[i];
8369 
8370 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8371 		device_printf(sc->sc_dev, "MAC trans error\n");
8372 
8373 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8374 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8375 		mac->mac_phy.txerrors--;
8376 		if (mac->mac_phy.txerrors == 0) {
8377 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8378 			bwn_restart(mac, "PHY TX errors");
8379 		}
8380 	}
8381 
8382 	if (merged & BWN_DMAINTR_FATALMASK) {
8383 		device_printf(sc->sc_dev,
8384 		    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8385 		    mac->mac_reason[0], mac->mac_reason[1],
8386 		    mac->mac_reason[2], mac->mac_reason[3],
8387 		    mac->mac_reason[4], mac->mac_reason[5]);
8388 		bwn_restart(mac, "DMA error");
8389 		wlan_serialize_exit();
8390 		return;
8391 	}
8392 
8393 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8394 		bwn_intr_ucode_debug(mac);
8395 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8396 		bwn_intr_tbtt_indication(mac);
8397 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8398 		bwn_intr_atim_end(mac);
8399 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
8400 		bwn_intr_beacon(mac);
8401 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
8402 		bwn_intr_pmq(mac);
8403 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8404 		bwn_intr_noise(mac);
8405 
8406 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8407 		if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) {
8408 			device_printf(sc->sc_dev, "RX descriptor overflow\n");
8409 			bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx);
8410 		}
8411 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8412 			bwn_dma_rx(mac->mac_method.dma.rx);
8413 			rx = 1;
8414 		}
8415 	} else
8416 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8417 
8418 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8419 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8420 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8421 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8422 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8423 
8424 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8425 		bwn_intr_txeof(mac);
8426 		tx = 1;
8427 	}
8428 
8429 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8430 
8431 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8432 		int evt = BWN_LED_EVENT_NONE;
8433 
8434 		if (tx && rx) {
8435 			if (sc->sc_rx_rate > sc->sc_tx_rate)
8436 				evt = BWN_LED_EVENT_RX;
8437 			else
8438 				evt = BWN_LED_EVENT_TX;
8439 		} else if (tx) {
8440 			evt = BWN_LED_EVENT_TX;
8441 		} else if (rx) {
8442 			evt = BWN_LED_EVENT_RX;
8443 		} else if (rx == 0) {
8444 			evt = BWN_LED_EVENT_POLL;
8445 		}
8446 
8447 		if (evt != BWN_LED_EVENT_NONE)
8448 			bwn_led_event(mac, evt);
8449        }
8450 
8451 	if (!ifq_is_oactive(&ifp->if_snd)) {
8452 		if (!ifq_is_empty(&ifp->if_snd))
8453 			bwn_start_locked(ifp);
8454 	}
8455 
8456 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8457 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8458 
8459 	wlan_serialize_exit();
8460 }
8461 
8462 static void
8463 bwn_restart(struct bwn_mac *mac, const char *msg)
8464 {
8465 	struct bwn_softc *sc = mac->mac_sc;
8466 	struct ifnet *ifp = sc->sc_ifp;
8467 	struct ieee80211com *ic = ifp->if_l2com;
8468 
8469 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
8470 		return;
8471 
8472 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8473 	ieee80211_runtask(ic, &mac->mac_hwreset);
8474 }
8475 
8476 static void
8477 bwn_intr_ucode_debug(struct bwn_mac *mac)
8478 {
8479 	struct bwn_softc *sc = mac->mac_sc;
8480 	uint16_t reason;
8481 
8482 	if (mac->mac_fw.opensource == 0)
8483 		return;
8484 
8485 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8486 	switch (reason) {
8487 	case BWN_DEBUGINTR_PANIC:
8488 		bwn_handle_fwpanic(mac);
8489 		break;
8490 	case BWN_DEBUGINTR_DUMP_SHM:
8491 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8492 		break;
8493 	case BWN_DEBUGINTR_DUMP_REGS:
8494 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8495 		break;
8496 	case BWN_DEBUGINTR_MARKER:
8497 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8498 		break;
8499 	default:
8500 		device_printf(sc->sc_dev,
8501 		    "ucode debug unknown reason: %#x\n", reason);
8502 	}
8503 
8504 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8505 	    BWN_DEBUGINTR_ACK);
8506 }
8507 
8508 static void
8509 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8510 {
8511 	struct bwn_softc *sc = mac->mac_sc;
8512 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8513 
8514 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8515 		bwn_psctl(mac, 0);
8516 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8517 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8518 }
8519 
8520 static void
8521 bwn_intr_atim_end(struct bwn_mac *mac)
8522 {
8523 
8524 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8525 		BWN_WRITE_4(mac, BWN_MACCMD,
8526 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8527 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8528 	}
8529 }
8530 
8531 static void
8532 bwn_intr_beacon(struct bwn_mac *mac)
8533 {
8534 	struct bwn_softc *sc = mac->mac_sc;
8535 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8536 	uint32_t cmd, beacon0, beacon1;
8537 
8538 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8539 	    ic->ic_opmode == IEEE80211_M_MBSS)
8540 		return;
8541 
8542 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8543 
8544 	cmd = BWN_READ_4(mac, BWN_MACCMD);
8545 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8546 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8547 
8548 	if (beacon0 && beacon1) {
8549 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8550 		mac->mac_intr_mask |= BWN_INTR_BEACON;
8551 		return;
8552 	}
8553 
8554 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8555 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8556 		bwn_load_beacon0(mac);
8557 		bwn_load_beacon1(mac);
8558 		cmd = BWN_READ_4(mac, BWN_MACCMD);
8559 		cmd |= BWN_MACCMD_BEACON0_VALID;
8560 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8561 	} else {
8562 		if (!beacon0) {
8563 			bwn_load_beacon0(mac);
8564 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8565 			cmd |= BWN_MACCMD_BEACON0_VALID;
8566 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8567 		} else if (!beacon1) {
8568 			bwn_load_beacon1(mac);
8569 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8570 			cmd |= BWN_MACCMD_BEACON1_VALID;
8571 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8572 		}
8573 	}
8574 }
8575 
8576 static void
8577 bwn_intr_pmq(struct bwn_mac *mac)
8578 {
8579 	uint32_t tmp;
8580 
8581 	while (1) {
8582 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8583 		if (!(tmp & 0x00000008))
8584 			break;
8585 	}
8586 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8587 }
8588 
8589 static void
8590 bwn_intr_noise(struct bwn_mac *mac)
8591 {
8592 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8593 	uint16_t tmp;
8594 	uint8_t noise[4];
8595 	uint8_t i, j;
8596 	int32_t average;
8597 
8598 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
8599 		return;
8600 
8601 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8602 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8603 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8604 	    noise[3] == 0x7f)
8605 		goto new;
8606 
8607 	KASSERT(mac->mac_noise.noi_nsamples < 8,
8608 	    ("%s:%d: fail", __func__, __LINE__));
8609 	i = mac->mac_noise.noi_nsamples;
8610 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8611 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8612 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8613 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8614 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8615 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8616 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8617 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8618 	mac->mac_noise.noi_nsamples++;
8619 	if (mac->mac_noise.noi_nsamples == 8) {
8620 		average = 0;
8621 		for (i = 0; i < 8; i++) {
8622 			for (j = 0; j < 4; j++)
8623 				average += mac->mac_noise.noi_samples[i][j];
8624 		}
8625 		average = (((average / 32) * 125) + 64) / 128;
8626 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8627 		if (tmp >= 8)
8628 			average += 2;
8629 		else
8630 			average -= 25;
8631 		average -= (tmp == 8) ? 72 : 48;
8632 
8633 		mac->mac_stats.link_noise = average;
8634 		mac->mac_noise.noi_running = 0;
8635 		return;
8636 	}
8637 new:
8638 	bwn_noise_gensample(mac);
8639 }
8640 
8641 static int
8642 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8643 {
8644 	struct bwn_mac *mac = prq->prq_mac;
8645 	struct bwn_softc *sc = mac->mac_sc;
8646 	unsigned int i;
8647 
8648 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8649 		return (0);
8650 
8651 	for (i = 0; i < 5000; i++) {
8652 		if (bwn_pio_rxeof(prq) == 0)
8653 			break;
8654 	}
8655 	if (i >= 5000)
8656 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8657 	return ((i > 0) ? 1 : 0);
8658 }
8659 
8660 static void
8661 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr)
8662 {
8663 	int curslot, prevslot;
8664 
8665 	curslot = dr->get_curslot(dr);
8666 	if (curslot == 0)
8667 		prevslot = dr->dr_numslots - 1;
8668 	else
8669 		prevslot = curslot - 1;
8670 	dr->set_curslot(dr, prevslot);
8671 }
8672 
8673 static void
8674 bwn_dma_rx(struct bwn_dma_ring *dr)
8675 {
8676 	int slot, curslot;
8677 
8678 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8679 	curslot = dr->get_curslot(dr);
8680 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8681 	    ("%s:%d: fail", __func__, __LINE__));
8682 
8683 	slot = dr->dr_curslot;
8684 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8685 		bwn_dma_rxeof(dr, &slot);
8686 
8687 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8688 	    BUS_DMASYNC_PREWRITE);
8689 
8690 	dr->set_curslot(dr, slot);
8691 	dr->dr_curslot = slot;
8692 }
8693 
8694 static void
8695 bwn_intr_txeof(struct bwn_mac *mac)
8696 {
8697 	struct bwn_txstatus stat;
8698 	uint32_t stat0, stat1;
8699 	uint16_t tmp;
8700 
8701 	while (1) {
8702 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8703 		if (!(stat0 & 0x00000001))
8704 			break;
8705 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8706 
8707 		stat.cookie = (stat0 >> 16);
8708 		stat.seq = (stat1 & 0x0000ffff);
8709 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8710 		tmp = (stat0 & 0x0000ffff);
8711 		stat.framecnt = ((tmp & 0xf000) >> 12);
8712 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
8713 		stat.sreason = ((tmp & 0x001c) >> 2);
8714 		stat.pm = (tmp & 0x0080) ? 1 : 0;
8715 		stat.im = (tmp & 0x0040) ? 1 : 0;
8716 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8717 		stat.ack = (tmp & 0x0002) ? 1 : 0;
8718 
8719 		bwn_handle_txeof(mac, &stat);
8720 	}
8721 }
8722 
8723 static void
8724 bwn_hwreset(void *arg, int npending)
8725 {
8726 	struct bwn_mac *mac = arg;
8727 	struct bwn_softc *sc = mac->mac_sc;
8728 	int error = 0;
8729 	int prev_status;
8730 
8731 	wlan_serialize_enter();
8732 
8733 	prev_status = mac->mac_status;
8734 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8735 		bwn_core_stop(mac);
8736 	if (prev_status >= BWN_MAC_STATUS_INITED)
8737 		bwn_core_exit(mac);
8738 
8739 	if (prev_status >= BWN_MAC_STATUS_INITED) {
8740 		error = bwn_core_init(mac);
8741 		if (error)
8742 			goto out;
8743 	}
8744 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8745 		bwn_core_start(mac);
8746 out:
8747 	if (error) {
8748 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8749 		sc->sc_curmac = NULL;
8750 	}
8751 	wlan_serialize_exit();
8752 }
8753 
8754 static void
8755 bwn_handle_fwpanic(struct bwn_mac *mac)
8756 {
8757 	struct bwn_softc *sc = mac->mac_sc;
8758 	uint16_t reason;
8759 
8760 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8761 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8762 
8763 	if (reason == BWN_FWPANIC_RESTART)
8764 		bwn_restart(mac, "ucode panic");
8765 }
8766 
8767 static void
8768 bwn_load_beacon0(struct bwn_mac *mac)
8769 {
8770 
8771 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8772 }
8773 
8774 static void
8775 bwn_load_beacon1(struct bwn_mac *mac)
8776 {
8777 
8778 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8779 }
8780 
8781 static uint32_t
8782 bwn_jssi_read(struct bwn_mac *mac)
8783 {
8784 	uint32_t val = 0;
8785 
8786 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8787 	val <<= 16;
8788 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8789 
8790 	return (val);
8791 }
8792 
8793 static void
8794 bwn_noise_gensample(struct bwn_mac *mac)
8795 {
8796 	uint32_t jssi = 0x7f7f7f7f;
8797 
8798 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8799 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8800 	BWN_WRITE_4(mac, BWN_MACCMD,
8801 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8802 }
8803 
8804 static int
8805 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8806 {
8807 	return (dr->dr_numslots - dr->dr_usedslot);
8808 }
8809 
8810 static int
8811 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8812 {
8813 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8814 	    ("%s:%d: fail", __func__, __LINE__));
8815 	if (slot == dr->dr_numslots - 1)
8816 		return (0);
8817 	return (slot + 1);
8818 }
8819 
8820 static void
8821 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8822 {
8823 	struct bwn_mac *mac = dr->dr_mac;
8824 	struct bwn_softc *sc = mac->mac_sc;
8825 	struct bwn_dma *dma = &mac->mac_method.dma;
8826 	struct bwn_dmadesc_generic *desc;
8827 	struct bwn_dmadesc_meta *meta;
8828 	struct bwn_rxhdr4 *rxhdr;
8829 	struct ifnet *ifp = sc->sc_ifp;
8830 	struct mbuf *m;
8831 	uint32_t macstat;
8832 	int32_t tmp;
8833 	int cnt = 0;
8834 	uint16_t len;
8835 
8836 	dr->getdesc(dr, *slot, &desc, &meta);
8837 
8838 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8839 	m = meta->mt_m;
8840 
8841 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8842 		ifp->if_ierrors++;
8843 		return;
8844 	}
8845 
8846 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
8847 	len = le16toh(rxhdr->frame_len);
8848 	if (len <= 0) {
8849 		ifp->if_ierrors++;
8850 		return;
8851 	}
8852 	if (bwn_dma_check_redzone(dr, m)) {
8853 		device_printf(sc->sc_dev, "redzone error.\n");
8854 		bwn_dma_set_redzone(dr, m);
8855 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8856 		    BUS_DMASYNC_PREWRITE);
8857 		return;
8858 	}
8859 	if (len > dr->dr_rx_bufsize) {
8860 		tmp = len;
8861 		while (1) {
8862 			dr->getdesc(dr, *slot, &desc, &meta);
8863 			bwn_dma_set_redzone(dr, meta->mt_m);
8864 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8865 			    BUS_DMASYNC_PREWRITE);
8866 			*slot = bwn_dma_nextslot(dr, *slot);
8867 			cnt++;
8868 			tmp -= dr->dr_rx_bufsize;
8869 			if (tmp <= 0)
8870 				break;
8871 		}
8872 		device_printf(sc->sc_dev, "too small buffer "
8873 		       "(len %u buffer %u dropped %d)\n",
8874 		       len, dr->dr_rx_bufsize, cnt);
8875 		return;
8876 	}
8877 	macstat = le32toh(rxhdr->mac_status);
8878 	if (macstat & BWN_RX_MAC_FCSERR) {
8879 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8880 			device_printf(sc->sc_dev, "RX drop\n");
8881 			return;
8882 		}
8883 	}
8884 
8885 	m->m_pkthdr.rcvif = ifp;
8886 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8887 	m_adj(m, dr->dr_frameoffset);
8888 
8889 	bwn_rxeof(dr->dr_mac, m, rxhdr);
8890 }
8891 
8892 static void
8893 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8894 {
8895 	struct bwn_dma_ring *dr;
8896 	struct bwn_dmadesc_generic *desc;
8897 	struct bwn_dmadesc_meta *meta;
8898 	struct bwn_pio_txqueue *tq;
8899 	struct bwn_pio_txpkt *tp = NULL;
8900 	struct bwn_softc *sc = mac->mac_sc;
8901 	struct bwn_stats *stats = &mac->mac_stats;
8902 	struct ieee80211_node *ni;
8903 	struct ieee80211vap *vap;
8904 	int retrycnt = 0, slot;
8905 
8906 	if (status->im)
8907 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8908 	if (status->ampdu)
8909 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8910 	if (status->rtscnt) {
8911 		if (status->rtscnt == 0xf)
8912 			stats->rtsfail++;
8913 		else
8914 			stats->rts++;
8915 	}
8916 
8917 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8918 		if (status->ack) {
8919 			dr = bwn_dma_parse_cookie(mac, status,
8920 			    status->cookie, &slot);
8921 			if (dr == NULL) {
8922 				device_printf(sc->sc_dev,
8923 				    "failed to parse cookie\n");
8924 				return;
8925 			}
8926 			while (1) {
8927 				dr->getdesc(dr, slot, &desc, &meta);
8928 				if (meta->mt_islast) {
8929 					ni = meta->mt_ni;
8930 					vap = ni->ni_vap;
8931 					ieee80211_ratectl_tx_complete(vap, ni,
8932 					    status->ack ?
8933 					      IEEE80211_RATECTL_TX_SUCCESS :
8934 					      IEEE80211_RATECTL_TX_FAILURE,
8935 					    &retrycnt, 0);
8936 					break;
8937 				}
8938 				slot = bwn_dma_nextslot(dr, slot);
8939 			}
8940 		}
8941 		bwn_dma_handle_txeof(mac, status);
8942 	} else {
8943 		if (status->ack) {
8944 			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8945 			if (tq == NULL) {
8946 				device_printf(sc->sc_dev,
8947 				    "failed to parse cookie\n");
8948 				return;
8949 			}
8950 			ni = tp->tp_ni;
8951 			vap = ni->ni_vap;
8952 			ieee80211_ratectl_tx_complete(vap, ni,
8953 			    status->ack ?
8954 			      IEEE80211_RATECTL_TX_SUCCESS :
8955 			      IEEE80211_RATECTL_TX_FAILURE,
8956 			    &retrycnt, 0);
8957 		}
8958 		bwn_pio_handle_txeof(mac, status);
8959 	}
8960 
8961 	bwn_phy_txpower_check(mac, 0);
8962 }
8963 
8964 static uint8_t
8965 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8966 {
8967 	struct bwn_mac *mac = prq->prq_mac;
8968 	struct bwn_softc *sc = mac->mac_sc;
8969 	struct bwn_rxhdr4 rxhdr;
8970 	struct ifnet *ifp = sc->sc_ifp;
8971 	struct mbuf *m;
8972 	uint32_t ctl32, macstat, v32;
8973 	unsigned int i, padding;
8974 	uint16_t ctl16, len, totlen, v16;
8975 	unsigned char *mp;
8976 	char *data;
8977 
8978 	memset(&rxhdr, 0, sizeof(rxhdr));
8979 
8980 	if (prq->prq_rev >= 8) {
8981 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8982 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8983 			return (0);
8984 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8985 		    BWN_PIO8_RXCTL_FRAMEREADY);
8986 		for (i = 0; i < 10; i++) {
8987 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8988 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8989 				goto ready;
8990 			DELAY(10);
8991 		}
8992 	} else {
8993 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8994 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8995 			return (0);
8996 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8997 		    BWN_PIO_RXCTL_FRAMEREADY);
8998 		for (i = 0; i < 10; i++) {
8999 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9000 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9001 				goto ready;
9002 			DELAY(10);
9003 		}
9004 	}
9005 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9006 	return (1);
9007 ready:
9008 	if (prq->prq_rev >= 8)
9009 		siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9010 		    prq->prq_base + BWN_PIO8_RXDATA);
9011 	else
9012 		siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9013 		    prq->prq_base + BWN_PIO_RXDATA);
9014 	len = le16toh(rxhdr.frame_len);
9015 	if (len > 0x700) {
9016 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9017 		goto error;
9018 	}
9019 	if (len == 0) {
9020 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9021 		goto error;
9022 	}
9023 
9024 	macstat = le32toh(rxhdr.mac_status);
9025 	if (macstat & BWN_RX_MAC_FCSERR) {
9026 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9027 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
9028 			goto error;
9029 		}
9030 	}
9031 
9032 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9033 	totlen = len + padding;
9034 	KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9035 	m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR);
9036 	if (m == NULL) {
9037 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
9038 		goto error;
9039 	}
9040 	mp = mtod(m, unsigned char *);
9041 	if (prq->prq_rev >= 8) {
9042 		siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9043 		    prq->prq_base + BWN_PIO8_RXDATA);
9044 		if (totlen & 3) {
9045 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9046 			data = &(mp[totlen - 1]);
9047 			switch (totlen & 3) {
9048 			case 3:
9049 				*data = (v32 >> 16);
9050 				data--;
9051 			case 2:
9052 				*data = (v32 >> 8);
9053 				data--;
9054 			case 1:
9055 				*data = v32;
9056 			}
9057 		}
9058 	} else {
9059 		siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9060 		    prq->prq_base + BWN_PIO_RXDATA);
9061 		if (totlen & 1) {
9062 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9063 			mp[totlen - 1] = v16;
9064 		}
9065 	}
9066 
9067 	m->m_pkthdr.rcvif = ifp;
9068 	m->m_len = m->m_pkthdr.len = totlen;
9069 
9070 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
9071 
9072 	return (1);
9073 error:
9074 	if (prq->prq_rev >= 8)
9075 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9076 		    BWN_PIO8_RXCTL_DATAREADY);
9077 	else
9078 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9079 	return (1);
9080 }
9081 
9082 static int
9083 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9084     struct bwn_dmadesc_meta *meta, int init)
9085 {
9086 	struct bwn_mac *mac = dr->dr_mac;
9087 	struct bwn_dma *dma = &mac->mac_method.dma;
9088 	struct bwn_rxhdr4 *hdr;
9089 	bus_dmamap_t map;
9090 	bus_addr_t paddr;
9091 	struct mbuf *m;
9092 	int error;
9093 
9094 	m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR);
9095 	if (m == NULL) {
9096 		error = ENOBUFS;
9097 
9098 		/*
9099 		 * If the NIC is up and running, we need to:
9100 		 * - Clear RX buffer's header.
9101 		 * - Restore RX descriptor settings.
9102 		 */
9103 		if (init)
9104 			return (error);
9105 		else
9106 			goto back;
9107 	}
9108 	m->m_len = m->m_pkthdr.len = MCLBYTES;
9109 
9110 	bwn_dma_set_redzone(dr, m);
9111 
9112 	/*
9113 	 * Try to load RX buf into temporary DMA map
9114 	 */
9115 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9116 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9117 	if (error) {
9118 		m_freem(m);
9119 
9120 		/*
9121 		 * See the comment above
9122 		 */
9123 		if (init)
9124 			return (error);
9125 		else
9126 			goto back;
9127 	}
9128 
9129 	if (!init)
9130 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9131 	meta->mt_m = m;
9132 	meta->mt_paddr = paddr;
9133 
9134 	/*
9135 	 * Swap RX buf's DMA map with the loaded temporary one
9136 	 */
9137 	map = meta->mt_dmap;
9138 	meta->mt_dmap = dr->dr_spare_dmap;
9139 	dr->dr_spare_dmap = map;
9140 
9141 back:
9142 	/*
9143 	 * Clear RX buf header
9144 	 */
9145 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9146 	bzero(hdr, sizeof(*hdr));
9147 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9148 	    BUS_DMASYNC_PREWRITE);
9149 
9150 	/*
9151 	 * Setup RX buf descriptor
9152 	 */
9153 	dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9154 	    sizeof(*hdr), 0, 0, 0);
9155 	return (error);
9156 }
9157 
9158 static void
9159 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9160 		 bus_size_t mapsz __unused, int error)
9161 {
9162 
9163 	if (!error) {
9164 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9165 		*((bus_addr_t *)arg) = seg->ds_addr;
9166 	}
9167 }
9168 
9169 static int
9170 bwn_hwrate2ieeerate(int rate)
9171 {
9172 
9173 	switch (rate) {
9174 	case BWN_CCK_RATE_1MB:
9175 		return (2);
9176 	case BWN_CCK_RATE_2MB:
9177 		return (4);
9178 	case BWN_CCK_RATE_5MB:
9179 		return (11);
9180 	case BWN_CCK_RATE_11MB:
9181 		return (22);
9182 	case BWN_OFDM_RATE_6MB:
9183 		return (12);
9184 	case BWN_OFDM_RATE_9MB:
9185 		return (18);
9186 	case BWN_OFDM_RATE_12MB:
9187 		return (24);
9188 	case BWN_OFDM_RATE_18MB:
9189 		return (36);
9190 	case BWN_OFDM_RATE_24MB:
9191 		return (48);
9192 	case BWN_OFDM_RATE_36MB:
9193 		return (72);
9194 	case BWN_OFDM_RATE_48MB:
9195 		return (96);
9196 	case BWN_OFDM_RATE_54MB:
9197 		return (108);
9198 	default:
9199 		kprintf("Ooops\n");
9200 		return (0);
9201 	}
9202 }
9203 
9204 static void
9205 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9206 {
9207 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9208 	struct bwn_plcp6 *plcp;
9209 	struct bwn_softc *sc = mac->mac_sc;
9210 	struct ieee80211_frame_min *wh;
9211 	struct ieee80211_node *ni;
9212 	struct ifnet *ifp = sc->sc_ifp;
9213 	struct ieee80211com *ic = ifp->if_l2com;
9214 	uint32_t macstat;
9215 	int padding, rate, rssi = 0, noise = 0, type;
9216 	uint16_t phytype, phystat0, phystat3, chanstat;
9217 	unsigned char *mp = mtod(m, unsigned char *);
9218 	static int rx_mac_dec_rpt = 0;
9219 
9220 	phystat0 = le16toh(rxhdr->phy_status0);
9221 	phystat3 = le16toh(rxhdr->phy_status3);
9222 	macstat = le32toh(rxhdr->mac_status);
9223 	chanstat = le16toh(rxhdr->channel);
9224 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9225 
9226 	if (macstat & BWN_RX_MAC_FCSERR)
9227 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9228 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9229 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9230 	if (macstat & BWN_RX_MAC_DECERR)
9231 		goto drop;
9232 
9233 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9234 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9235 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9236 		    m->m_pkthdr.len);
9237 		goto drop;
9238 	}
9239 	plcp = (struct bwn_plcp6 *)(mp + padding);
9240 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
9241 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9242 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9243 		    m->m_pkthdr.len);
9244 		goto drop;
9245 	}
9246 	wh = mtod(m, struct ieee80211_frame_min *);
9247 
9248 	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9249 		device_printf(sc->sc_dev,
9250 		    "RX decryption attempted (old %d keyidx %#x)\n",
9251 		    BWN_ISOLDFMT(mac),
9252 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9253 
9254 	/* XXX calculating RSSI & noise & antenna */
9255 
9256 	if (phystat0 & BWN_RX_PHYST0_OFDM)
9257 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
9258 		    phytype == BWN_PHYTYPE_A);
9259 	else
9260 		rate = bwn_plcp_get_cckrate(mac, plcp);
9261 	if (rate == -1) {
9262 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9263 			goto drop;
9264 	}
9265 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9266 
9267 	/* RX radio tap */
9268 	if (ieee80211_radiotap_active(ic))
9269 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9270 	m_adj(m, -IEEE80211_CRC_LEN);
9271 
9272 	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
9273 	noise = mac->mac_stats.link_noise;
9274 
9275 	ifp->if_ipackets++;
9276 
9277 	ni = ieee80211_find_rxnode(ic, wh);
9278 	if (ni != NULL) {
9279 		type = ieee80211_input(ni, m, rssi, noise);
9280 		ieee80211_free_node(ni);
9281 	} else
9282 		type = ieee80211_input_all(ic, m, rssi, noise);
9283 
9284 	return;
9285 drop:
9286 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9287 }
9288 
9289 static void
9290 bwn_dma_handle_txeof(struct bwn_mac *mac,
9291     const struct bwn_txstatus *status)
9292 {
9293 	struct bwn_dma *dma = &mac->mac_method.dma;
9294 	struct bwn_dma_ring *dr;
9295 	struct bwn_dmadesc_generic *desc;
9296 	struct bwn_dmadesc_meta *meta;
9297 	struct bwn_softc *sc = mac->mac_sc;
9298 	struct ieee80211_node *ni;
9299 	struct ifnet *ifp = sc->sc_ifp;
9300 	struct mbuf *m;
9301 	int slot;
9302 
9303 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9304 	if (dr == NULL) {
9305 		device_printf(sc->sc_dev, "failed to parse cookie\n");
9306 		return;
9307 	}
9308 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9309 
9310 	while (1) {
9311 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
9312 		    ("%s:%d: fail", __func__, __LINE__));
9313 		dr->getdesc(dr, slot, &desc, &meta);
9314 
9315 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
9316 			bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap,
9317 			    BUS_DMASYNC_POSTWRITE);
9318 		} else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
9319 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9320 		}
9321 
9322 		if (meta->mt_islast) {
9323 			KASSERT(meta->mt_m != NULL,
9324 			    ("%s:%d: fail", __func__, __LINE__));
9325 
9326 			ni = meta->mt_ni;
9327 			m = meta->mt_m;
9328 			if (ni != NULL) {
9329 				/*
9330 				 * Do any tx complete callback. Note this must
9331 				 * be done before releasing the node reference.
9332 				 */
9333 				if (m->m_flags & M_TXCB)
9334 					ieee80211_process_callback(ni, m, 0);
9335 				ieee80211_free_node(ni);
9336 				meta->mt_ni = NULL;
9337 			}
9338 			m_freem(m);
9339 			meta->mt_m = NULL;
9340 		} else {
9341 			KASSERT(meta->mt_m == NULL,
9342 			    ("%s:%d: fail", __func__, __LINE__));
9343 		}
9344 
9345 		dr->dr_usedslot--;
9346 		if (meta->mt_islast) {
9347 			ifp->if_opackets++;
9348 			break;
9349 		}
9350 		slot = bwn_dma_nextslot(dr, slot);
9351 	}
9352 	sc->sc_watchdog_timer = 0;
9353 	if (dr->dr_stop) {
9354 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9355 		    ("%s:%d: fail", __func__, __LINE__));
9356 		ifq_clr_oactive(&ifp->if_snd);
9357 		dr->dr_stop = 0;
9358 	}
9359 }
9360 
9361 static void
9362 bwn_pio_handle_txeof(struct bwn_mac *mac,
9363     const struct bwn_txstatus *status)
9364 {
9365 	struct bwn_pio_txqueue *tq;
9366 	struct bwn_pio_txpkt *tp = NULL;
9367 	struct bwn_softc *sc = mac->mac_sc;
9368 	struct ifnet *ifp = sc->sc_ifp;
9369 
9370 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9371 	if (tq == NULL)
9372 		return;
9373 
9374 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9375 	tq->tq_free++;
9376 
9377 	if (tp->tp_ni != NULL) {
9378 		/*
9379 		 * Do any tx complete callback.  Note this must
9380 		 * be done before releasing the node reference.
9381 		 */
9382 		if (tp->tp_m->m_flags & M_TXCB)
9383 			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9384 		ieee80211_free_node(tp->tp_ni);
9385 		tp->tp_ni = NULL;
9386 	}
9387 	m_freem(tp->tp_m);
9388 	tp->tp_m = NULL;
9389 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9390 
9391 	ifp->if_opackets++;
9392 
9393 	sc->sc_watchdog_timer = 0;
9394 	if (tq->tq_stop) {
9395 		ifq_clr_oactive(&ifp->if_snd);
9396 		tq->tq_stop = 0;
9397 	}
9398 }
9399 
9400 static void
9401 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9402 {
9403 	struct bwn_softc *sc = mac->mac_sc;
9404 	struct bwn_phy *phy = &mac->mac_phy;
9405 	struct ifnet *ifp = sc->sc_ifp;
9406 	struct ieee80211com *ic = ifp->if_l2com;
9407 	unsigned long now;
9408 	int result;
9409 
9410 	BWN_GETTIME(now);
9411 
9412 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9413 		return;
9414 	phy->nexttime = now + 2 * 1000;
9415 
9416 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9417 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9418 		return;
9419 
9420 	if (phy->recalc_txpwr != NULL) {
9421 		result = phy->recalc_txpwr(mac,
9422 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9423 		if (result == BWN_TXPWR_RES_DONE)
9424 			return;
9425 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9426 		    ("%s: fail", __func__));
9427 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9428 
9429 		ieee80211_runtask(ic, &mac->mac_txpower);
9430 	}
9431 }
9432 
9433 static uint16_t
9434 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9435 {
9436 
9437 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9438 }
9439 
9440 static uint32_t
9441 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9442 {
9443 
9444 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9445 }
9446 
9447 static void
9448 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9449 {
9450 
9451 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9452 }
9453 
9454 static void
9455 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9456 {
9457 
9458 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9459 }
9460 
9461 static int
9462 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9463 {
9464 
9465 	switch (rate) {
9466 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9467 	case 12:
9468 		return (BWN_OFDM_RATE_6MB);
9469 	case 18:
9470 		return (BWN_OFDM_RATE_9MB);
9471 	case 24:
9472 		return (BWN_OFDM_RATE_12MB);
9473 	case 36:
9474 		return (BWN_OFDM_RATE_18MB);
9475 	case 48:
9476 		return (BWN_OFDM_RATE_24MB);
9477 	case 72:
9478 		return (BWN_OFDM_RATE_36MB);
9479 	case 96:
9480 		return (BWN_OFDM_RATE_48MB);
9481 	case 108:
9482 		return (BWN_OFDM_RATE_54MB);
9483 	/* CCK rates (NB: not IEEE std, device-specific) */
9484 	case 2:
9485 		return (BWN_CCK_RATE_1MB);
9486 	case 4:
9487 		return (BWN_CCK_RATE_2MB);
9488 	case 11:
9489 		return (BWN_CCK_RATE_5MB);
9490 	case 22:
9491 		return (BWN_CCK_RATE_11MB);
9492 	}
9493 
9494 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9495 	return (BWN_CCK_RATE_1MB);
9496 }
9497 
9498 static int
9499 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9500     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9501 {
9502 	const struct bwn_phy *phy = &mac->mac_phy;
9503 	struct bwn_softc *sc = mac->mac_sc;
9504 	struct ieee80211_frame *wh;
9505 	struct ieee80211_frame *protwh;
9506 	struct ieee80211_frame_cts *cts;
9507 	struct ieee80211_frame_rts *rts;
9508 	const struct ieee80211_txparam *tp;
9509 	struct ieee80211vap *vap = ni->ni_vap;
9510 	struct ifnet *ifp = sc->sc_ifp;
9511 	struct ieee80211com *ic = ifp->if_l2com;
9512 	struct mbuf *mprot;
9513 	unsigned int len;
9514 	uint32_t macctl = 0;
9515 	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9516 	uint16_t phyctl = 0;
9517 	uint8_t rate, rate_fb;
9518 
9519 	wh = mtod(m, struct ieee80211_frame *);
9520 	memset(txhdr, 0, sizeof(*txhdr));
9521 
9522 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9523 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9524 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9525 
9526 	/*
9527 	 * Find TX rate
9528 	 */
9529 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9530 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9531 		rate = rate_fb = tp->mgmtrate;
9532 	else if (ismcast)
9533 		rate = rate_fb = tp->mcastrate;
9534 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9535 		rate = rate_fb = tp->ucastrate;
9536 	else {
9537 		rix = ieee80211_ratectl_rate(ni, NULL, 0);
9538 		rate = ni->ni_txrate;
9539 
9540 		if (rix > 0)
9541 			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9542 			    IEEE80211_RATE_VAL;
9543 		else
9544 			rate_fb = rate;
9545 	}
9546 
9547 	sc->sc_tx_rate = rate;
9548 
9549 	rate = bwn_ieeerate2hwrate(sc, rate);
9550 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9551 
9552 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9553 	    bwn_plcp_getcck(rate);
9554 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9555 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9556 
9557 	if ((rate_fb == rate) ||
9558 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9559 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
9560 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9561 	else
9562 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9563 		    m->m_pkthdr.len, rate, isshort);
9564 
9565 	/* XXX TX encryption */
9566 	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9567 	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9568 	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9569 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9570 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9571 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9572 
9573 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9574 	    BWN_TX_EFT_FB_CCK;
9575 	txhdr->chan = phy->chan;
9576 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9577 	    BWN_TX_PHY_ENC_CCK;
9578 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9579 	     rate == BWN_CCK_RATE_11MB))
9580 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
9581 
9582 	/* XXX TX antenna selection */
9583 
9584 	switch (bwn_antenna_sanitize(mac, 0)) {
9585 	case 0:
9586 		phyctl |= BWN_TX_PHY_ANT01AUTO;
9587 		break;
9588 	case 1:
9589 		phyctl |= BWN_TX_PHY_ANT0;
9590 		break;
9591 	case 2:
9592 		phyctl |= BWN_TX_PHY_ANT1;
9593 		break;
9594 	case 3:
9595 		phyctl |= BWN_TX_PHY_ANT2;
9596 		break;
9597 	case 4:
9598 		phyctl |= BWN_TX_PHY_ANT3;
9599 		break;
9600 	default:
9601 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9602 	}
9603 
9604 	if (!ismcast)
9605 		macctl |= BWN_TX_MAC_ACK;
9606 
9607 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9608 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9609 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9610 		macctl |= BWN_TX_MAC_LONGFRAME;
9611 
9612 	if (ic->ic_flags & IEEE80211_F_USEPROT) {
9613 		/* XXX RTS rate is always 1MB??? */
9614 		rts_rate = BWN_CCK_RATE_1MB;
9615 		rts_rate_fb = bwn_get_fbrate(rts_rate);
9616 
9617 		protdur = ieee80211_compute_duration(ic->ic_rt,
9618 		    m->m_pkthdr.len, rate, isshort) +
9619 		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9620 
9621 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9622 			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9623 			    (txhdr->body.old.rts_frame) :
9624 			    (txhdr->body.new.rts_frame));
9625 			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9626 			    protdur);
9627 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9628 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9629 			    mprot->m_pkthdr.len);
9630 			m_freem(mprot);
9631 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9632 			len = sizeof(struct ieee80211_frame_cts);
9633 		} else {
9634 			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9635 			    (txhdr->body.old.rts_frame) :
9636 			    (txhdr->body.new.rts_frame));
9637 			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9638 			    isshort);
9639 			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9640 			    wh->i_addr2, protdur);
9641 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9642 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9643 			    mprot->m_pkthdr.len);
9644 			m_freem(mprot);
9645 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
9646 			len = sizeof(struct ieee80211_frame_rts);
9647 		}
9648 		len += IEEE80211_CRC_LEN;
9649 		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9650 		    &txhdr->body.old.rts_plcp :
9651 		    &txhdr->body.new.rts_plcp), len, rts_rate);
9652 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9653 		    rts_rate_fb);
9654 
9655 		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9656 		    (&txhdr->body.old.rts_frame) :
9657 		    (&txhdr->body.new.rts_frame));
9658 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9659 
9660 		if (BWN_ISOFDMRATE(rts_rate)) {
9661 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9662 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9663 		} else {
9664 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9665 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9666 		}
9667 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9668 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9669 	}
9670 
9671 	if (BWN_ISOLDFMT(mac))
9672 		txhdr->body.old.cookie = htole16(cookie);
9673 	else
9674 		txhdr->body.new.cookie = htole16(cookie);
9675 
9676 	txhdr->macctl = htole32(macctl);
9677 	txhdr->phyctl = htole16(phyctl);
9678 
9679 	/*
9680 	 * TX radio tap
9681 	 */
9682 	if (ieee80211_radiotap_active_vap(vap)) {
9683 		sc->sc_tx_th.wt_flags = 0;
9684 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9685 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9686 		if (isshort &&
9687 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9688 		     rate == BWN_CCK_RATE_11MB))
9689 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9690 		sc->sc_tx_th.wt_rate = rate;
9691 
9692 		ieee80211_radiotap_tx(vap, m);
9693 	}
9694 
9695 	return (0);
9696 }
9697 
9698 static void
9699 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9700     const uint8_t rate)
9701 {
9702 	uint32_t d, plen;
9703 	uint8_t *raw = plcp->o.raw;
9704 
9705 	if (BWN_ISOFDMRATE(rate)) {
9706 		d = bwn_plcp_getofdm(rate);
9707 		KASSERT(!(octets & 0xf000),
9708 		    ("%s:%d: fail", __func__, __LINE__));
9709 		d |= (octets << 5);
9710 		plcp->o.data = htole32(d);
9711 	} else {
9712 		plen = octets * 16 / rate;
9713 		if ((octets * 16 % rate) > 0) {
9714 			plen++;
9715 			if ((rate == BWN_CCK_RATE_11MB)
9716 			    && ((octets * 8 % 11) < 4)) {
9717 				raw[1] = 0x84;
9718 			} else
9719 				raw[1] = 0x04;
9720 		} else
9721 			raw[1] = 0x04;
9722 		plcp->o.data |= htole32(plen << 16);
9723 		raw[0] = bwn_plcp_getcck(rate);
9724 	}
9725 }
9726 
9727 static uint8_t
9728 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9729 {
9730 	struct bwn_softc *sc = mac->mac_sc;
9731 	uint8_t mask;
9732 
9733 	if (n == 0)
9734 		return (0);
9735 	if (mac->mac_phy.gmode)
9736 		mask = siba_sprom_get_ant_bg(sc->sc_dev);
9737 	else
9738 		mask = siba_sprom_get_ant_a(sc->sc_dev);
9739 	if (!(mask & (1 << (n - 1))))
9740 		return (0);
9741 	return (n);
9742 }
9743 
9744 static uint8_t
9745 bwn_get_fbrate(uint8_t bitrate)
9746 {
9747 	switch (bitrate) {
9748 	case BWN_CCK_RATE_1MB:
9749 		return (BWN_CCK_RATE_1MB);
9750 	case BWN_CCK_RATE_2MB:
9751 		return (BWN_CCK_RATE_1MB);
9752 	case BWN_CCK_RATE_5MB:
9753 		return (BWN_CCK_RATE_2MB);
9754 	case BWN_CCK_RATE_11MB:
9755 		return (BWN_CCK_RATE_5MB);
9756 	case BWN_OFDM_RATE_6MB:
9757 		return (BWN_CCK_RATE_5MB);
9758 	case BWN_OFDM_RATE_9MB:
9759 		return (BWN_OFDM_RATE_6MB);
9760 	case BWN_OFDM_RATE_12MB:
9761 		return (BWN_OFDM_RATE_9MB);
9762 	case BWN_OFDM_RATE_18MB:
9763 		return (BWN_OFDM_RATE_12MB);
9764 	case BWN_OFDM_RATE_24MB:
9765 		return (BWN_OFDM_RATE_18MB);
9766 	case BWN_OFDM_RATE_36MB:
9767 		return (BWN_OFDM_RATE_24MB);
9768 	case BWN_OFDM_RATE_48MB:
9769 		return (BWN_OFDM_RATE_36MB);
9770 	case BWN_OFDM_RATE_54MB:
9771 		return (BWN_OFDM_RATE_48MB);
9772 	}
9773 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9774 	return (0);
9775 }
9776 
9777 static uint32_t
9778 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9779     uint32_t ctl, const void *_data, int len)
9780 {
9781 	struct bwn_softc *sc = mac->mac_sc;
9782 	uint32_t value = 0;
9783 	const uint8_t *data = _data;
9784 
9785 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9786 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9787 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9788 
9789 	siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9790 	    tq->tq_base + BWN_PIO8_TXDATA);
9791 	if (len & 3) {
9792 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9793 		    BWN_PIO8_TXCTL_24_31);
9794 		data = &(data[len - 1]);
9795 		switch (len & 3) {
9796 		case 3:
9797 			ctl |= BWN_PIO8_TXCTL_16_23;
9798 			value |= (uint32_t)(*data) << 16;
9799 			data--;
9800 		case 2:
9801 			ctl |= BWN_PIO8_TXCTL_8_15;
9802 			value |= (uint32_t)(*data) << 8;
9803 			data--;
9804 		case 1:
9805 			value |= (uint32_t)(*data);
9806 		}
9807 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9808 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9809 	}
9810 
9811 	return (ctl);
9812 }
9813 
9814 static void
9815 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9816     uint16_t offset, uint32_t value)
9817 {
9818 
9819 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
9820 }
9821 
9822 static uint16_t
9823 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9824     uint16_t ctl, const void *_data, int len)
9825 {
9826 	struct bwn_softc *sc = mac->mac_sc;
9827 	const uint8_t *data = _data;
9828 
9829 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9830 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9831 
9832 	siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9833 	    tq->tq_base + BWN_PIO_TXDATA);
9834 	if (len & 1) {
9835 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9836 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9837 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9838 	}
9839 
9840 	return (ctl);
9841 }
9842 
9843 static uint16_t
9844 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9845     uint16_t ctl, struct mbuf *m0)
9846 {
9847 	int i, j = 0;
9848 	uint16_t data = 0;
9849 	const uint8_t *buf;
9850 	struct mbuf *m = m0;
9851 
9852 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9853 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9854 
9855 	for (; m != NULL; m = m->m_next) {
9856 		buf = mtod(m, const uint8_t *);
9857 		for (i = 0; i < m->m_len; i++) {
9858 			if (!((j++) % 2))
9859 				data |= buf[i];
9860 			else {
9861 				data |= (buf[i] << 8);
9862 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9863 				data = 0;
9864 			}
9865 		}
9866 	}
9867 	if (m0->m_pkthdr.len % 2) {
9868 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9869 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9870 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9871 	}
9872 
9873 	return (ctl);
9874 }
9875 
9876 static void
9877 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9878 {
9879 
9880 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
9881 		return;
9882 	BWN_WRITE_2(mac, 0x684, 510 + time);
9883 
9884 	/*
9885 	 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a
9886 	 *              a severe performance penalty (especially when sending).
9887 	 */
9888 #if 0
9889 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9890 #endif
9891 }
9892 
9893 static struct bwn_dma_ring *
9894 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9895 {
9896 
9897 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9898 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9899 
9900 	switch (prio) {
9901 	case 3:
9902 		return (mac->mac_method.dma.wme[WME_AC_VO]);
9903 	case 2:
9904 		return (mac->mac_method.dma.wme[WME_AC_VI]);
9905 	case 0:
9906 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9907 	case 1:
9908 		return (mac->mac_method.dma.wme[WME_AC_BK]);
9909 	}
9910 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9911 	return (NULL);
9912 }
9913 
9914 static int
9915 bwn_dma_getslot(struct bwn_dma_ring *dr)
9916 {
9917 	int slot;
9918 
9919 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9920 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9921 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9922 
9923 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9924 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9925 	dr->dr_curslot = slot;
9926 	dr->dr_usedslot++;
9927 
9928 	return (slot);
9929 }
9930 
9931 static int
9932 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9933 {
9934 	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9935 	unsigned int a, b, c, d;
9936 	unsigned int avg;
9937 	uint32_t tmp;
9938 
9939 	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9940 	a = tmp & 0xff;
9941 	b = (tmp >> 8) & 0xff;
9942 	c = (tmp >> 16) & 0xff;
9943 	d = (tmp >> 24) & 0xff;
9944 	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9945 	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9946 		return (ENOENT);
9947 	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9948 	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9949 	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9950 
9951 	if (ofdm) {
9952 		a = (a + 32) & 0x3f;
9953 		b = (b + 32) & 0x3f;
9954 		c = (c + 32) & 0x3f;
9955 		d = (d + 32) & 0x3f;
9956 	}
9957 
9958 	avg = (a + b + c + d + 2) / 4;
9959 	if (ofdm) {
9960 		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9961 		    & BWN_HF_4DB_CCK_POWERBOOST)
9962 			avg = (avg >= 13) ? (avg - 13) : 0;
9963 	}
9964 	return (avg);
9965 }
9966 
9967 static void
9968 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9969 {
9970 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9971 	int rfatt = *rfattp;
9972 	int bbatt = *bbattp;
9973 
9974 	while (1) {
9975 		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9976 			break;
9977 		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9978 			break;
9979 		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9980 			break;
9981 		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9982 			break;
9983 		if (bbatt > lo->bbatt.max) {
9984 			bbatt -= 4;
9985 			rfatt += 1;
9986 			continue;
9987 		}
9988 		if (bbatt < lo->bbatt.min) {
9989 			bbatt += 4;
9990 			rfatt -= 1;
9991 			continue;
9992 		}
9993 		if (rfatt > lo->rfatt.max) {
9994 			rfatt -= 1;
9995 			bbatt += 4;
9996 			continue;
9997 		}
9998 		if (rfatt < lo->rfatt.min) {
9999 			rfatt += 1;
10000 			bbatt -= 4;
10001 			continue;
10002 		}
10003 		break;
10004 	}
10005 
10006 	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10007 	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10008 }
10009 
10010 static void
10011 bwn_phy_lock(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, BWN_PS_AWAKE);
10021 }
10022 
10023 static void
10024 bwn_phy_unlock(struct bwn_mac *mac)
10025 {
10026 	struct bwn_softc *sc = mac->mac_sc;
10027 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10028 
10029 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10030 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10031 
10032 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10033 		bwn_psctl(mac, 0);
10034 }
10035 
10036 static void
10037 bwn_rf_lock(struct bwn_mac *mac)
10038 {
10039 
10040 	BWN_WRITE_4(mac, BWN_MACCTL,
10041 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10042 	BWN_READ_4(mac, BWN_MACCTL);
10043 	DELAY(10);
10044 }
10045 
10046 static void
10047 bwn_rf_unlock(struct bwn_mac *mac)
10048 {
10049 
10050 	BWN_READ_2(mac, BWN_PHYVER);
10051 	BWN_WRITE_4(mac, BWN_MACCTL,
10052 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10053 }
10054 
10055 static struct bwn_pio_txqueue *
10056 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10057     struct bwn_pio_txpkt **pack)
10058 {
10059 	struct bwn_pio *pio = &mac->mac_method.pio;
10060 	struct bwn_pio_txqueue *tq = NULL;
10061 	unsigned int index;
10062 
10063 	switch (cookie & 0xf000) {
10064 	case 0x1000:
10065 		tq = &pio->wme[WME_AC_BK];
10066 		break;
10067 	case 0x2000:
10068 		tq = &pio->wme[WME_AC_BE];
10069 		break;
10070 	case 0x3000:
10071 		tq = &pio->wme[WME_AC_VI];
10072 		break;
10073 	case 0x4000:
10074 		tq = &pio->wme[WME_AC_VO];
10075 		break;
10076 	case 0x5000:
10077 		tq = &pio->mcast;
10078 		break;
10079 	}
10080 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10081 	if (tq == NULL)
10082 		return (NULL);
10083 	index = (cookie & 0x0fff);
10084 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10085 	if (index >= N(tq->tq_pkts))
10086 		return (NULL);
10087 	*pack = &tq->tq_pkts[index];
10088 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10089 	return (tq);
10090 }
10091 
10092 static void
10093 bwn_txpwr(void *arg, int npending)
10094 {
10095 	struct bwn_mac *mac = arg;
10096 
10097 	wlan_serialize_enter();
10098 	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10099 	    mac->mac_phy.set_txpwr != NULL)
10100 		mac->mac_phy.set_txpwr(mac);
10101 	wlan_serialize_exit();
10102 }
10103 
10104 static void
10105 bwn_task_15s(struct bwn_mac *mac)
10106 {
10107 	uint16_t reg;
10108 
10109 	if (mac->mac_fw.opensource) {
10110 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10111 		if (reg) {
10112 			bwn_restart(mac, "fw watchdog");
10113 			return;
10114 		}
10115 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10116 	}
10117 	if (mac->mac_phy.task_15s)
10118 		mac->mac_phy.task_15s(mac);
10119 
10120 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10121 }
10122 
10123 static void
10124 bwn_task_30s(struct bwn_mac *mac)
10125 {
10126 
10127 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10128 		return;
10129 	mac->mac_noise.noi_running = 1;
10130 	mac->mac_noise.noi_nsamples = 0;
10131 
10132 	bwn_noise_gensample(mac);
10133 }
10134 
10135 static void
10136 bwn_task_60s(struct bwn_mac *mac)
10137 {
10138 
10139 	if (mac->mac_phy.task_60s)
10140 		mac->mac_phy.task_60s(mac);
10141 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10142 }
10143 
10144 static void
10145 bwn_tasks(void *arg)
10146 {
10147 	struct bwn_mac *mac = arg;
10148 	struct bwn_softc *sc = mac->mac_sc;
10149 
10150 	wlan_serialize_enter();
10151 
10152 	if (mac->mac_status != BWN_MAC_STATUS_STARTED) {
10153 		wlan_serialize_exit();
10154 		return;
10155 	}
10156 
10157 	if (mac->mac_task_state % 4 == 0)
10158 		bwn_task_60s(mac);
10159 	if (mac->mac_task_state % 2 == 0)
10160 		bwn_task_30s(mac);
10161 	bwn_task_15s(mac);
10162 
10163 	mac->mac_task_state++;
10164 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10165 	wlan_serialize_exit();
10166 }
10167 
10168 static int
10169 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10170 {
10171 	struct bwn_softc *sc = mac->mac_sc;
10172 
10173 	KASSERT(a == 0, ("not support APHY\n"));
10174 
10175 	switch (plcp->o.raw[0] & 0xf) {
10176 	case 0xb:
10177 		return (BWN_OFDM_RATE_6MB);
10178 	case 0xf:
10179 		return (BWN_OFDM_RATE_9MB);
10180 	case 0xa:
10181 		return (BWN_OFDM_RATE_12MB);
10182 	case 0xe:
10183 		return (BWN_OFDM_RATE_18MB);
10184 	case 0x9:
10185 		return (BWN_OFDM_RATE_24MB);
10186 	case 0xd:
10187 		return (BWN_OFDM_RATE_36MB);
10188 	case 0x8:
10189 		return (BWN_OFDM_RATE_48MB);
10190 	case 0xc:
10191 		return (BWN_OFDM_RATE_54MB);
10192 	}
10193 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10194 	    plcp->o.raw[0] & 0xf);
10195 	return (-1);
10196 }
10197 
10198 static int
10199 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10200 {
10201 	struct bwn_softc *sc = mac->mac_sc;
10202 
10203 	switch (plcp->o.raw[0]) {
10204 	case 0x0a:
10205 		return (BWN_CCK_RATE_1MB);
10206 	case 0x14:
10207 		return (BWN_CCK_RATE_2MB);
10208 	case 0x37:
10209 		return (BWN_CCK_RATE_5MB);
10210 	case 0x6e:
10211 		return (BWN_CCK_RATE_11MB);
10212 	}
10213 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10214 	return (-1);
10215 }
10216 
10217 static void
10218 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10219     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10220     int rssi, int noise)
10221 {
10222 	struct bwn_softc *sc = mac->mac_sc;
10223 	const struct ieee80211_frame_min *wh;
10224 	uint64_t tsf;
10225 	uint16_t low_mactime_now;
10226 
10227 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10228 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10229 
10230 	wh = mtod(m, const struct ieee80211_frame_min *);
10231 	if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10232 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10233 
10234 	bwn_tsf_read(mac, &tsf);
10235 	low_mactime_now = tsf;
10236 	tsf = tsf & ~0xffffULL;
10237 	tsf += le16toh(rxhdr->mac_time);
10238 	if (low_mactime_now < le16toh(rxhdr->mac_time))
10239 		tsf -= 0x10000;
10240 
10241 	sc->sc_rx_th.wr_tsf = tsf;
10242 	sc->sc_rx_th.wr_rate = rate;
10243 	sc->sc_rx_th.wr_antsignal = rssi;
10244 	sc->sc_rx_th.wr_antnoise = noise;
10245 }
10246 
10247 static void
10248 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10249 {
10250 	uint32_t low, high;
10251 
10252 	KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10253 	    ("%s:%d: fail", __func__, __LINE__));
10254 
10255 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10256 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10257 	*tsf = high;
10258 	*tsf <<= 32;
10259 	*tsf |= low;
10260 }
10261 
10262 static int
10263 bwn_dma_attach(struct bwn_mac *mac)
10264 {
10265 	struct bwn_dma *dma = &mac->mac_method.dma;
10266 	struct bwn_softc *sc = mac->mac_sc;
10267 	bus_addr_t lowaddr = 0;
10268 	int error;
10269 
10270 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10271 		return (0);
10272 
10273 	KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10274 
10275 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
10276 
10277 	dma->dmatype = bwn_dma_gettype(mac);
10278 	if (dma->dmatype == BWN_DMA_30BIT)
10279 		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10280 	else if (dma->dmatype == BWN_DMA_32BIT)
10281 		lowaddr = BUS_SPACE_MAXADDR_32BIT;
10282 	else
10283 		lowaddr = BUS_SPACE_MAXADDR;
10284 
10285 	/*
10286 	 * Create top level DMA tag
10287 	 */
10288 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
10289 			       BWN_ALIGN, 0,		/* alignment, bounds */
10290 			       lowaddr,			/* lowaddr */
10291 			       BUS_SPACE_MAXADDR,	/* highaddr */
10292 			       NULL, NULL,		/* filter, filterarg */
10293 			       MAXBSIZE,		/* maxsize */
10294 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
10295 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
10296 			       0,			/* flags */
10297 			       &dma->parent_dtag);
10298 	if (error) {
10299 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10300 		return (error);
10301 	}
10302 
10303 	/*
10304 	 * Create TX/RX mbuf DMA tag
10305 	 */
10306 	error = bus_dma_tag_create(dma->parent_dtag,
10307 				4,
10308 				0,
10309 				BUS_SPACE_MAXADDR,
10310 				BUS_SPACE_MAXADDR,
10311 				NULL, NULL,
10312 				MCLBYTES,
10313 				1,
10314 				BUS_SPACE_MAXSIZE_32BIT,
10315 				0,
10316 				&dma->rxbuf_dtag);
10317 	if (error) {
10318 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10319 		goto fail0;
10320 	}
10321 	error = bus_dma_tag_create(dma->parent_dtag,
10322 				4,
10323 				0,
10324 				BUS_SPACE_MAXADDR,
10325 				BUS_SPACE_MAXADDR,
10326 				NULL, NULL,
10327 				MCLBYTES,
10328 				1,
10329 				BUS_SPACE_MAXSIZE_32BIT,
10330 				0,
10331 				&dma->txbuf_dtag);
10332 	if (error) {
10333 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10334 		goto fail1;
10335 	}
10336 
10337 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10338 	if (dma->wme[WME_AC_BK] == NULL)
10339 		goto fail2;
10340 
10341 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10342 	if (dma->wme[WME_AC_BE] == NULL)
10343 		goto fail3;
10344 
10345 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10346 	if (dma->wme[WME_AC_VI] == NULL)
10347 		goto fail4;
10348 
10349 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10350 	if (dma->wme[WME_AC_VO] == NULL)
10351 		goto fail5;
10352 
10353 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10354 	if (dma->mcast == NULL)
10355 		goto fail6;
10356 	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10357 	if (dma->rx == NULL)
10358 		goto fail7;
10359 
10360 	return (error);
10361 
10362 fail7:	bwn_dma_ringfree(&dma->mcast);
10363 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10364 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10365 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10366 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10367 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
10368 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
10369 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
10370 	return (error);
10371 }
10372 
10373 static struct bwn_dma_ring *
10374 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10375     uint16_t cookie, int *slot)
10376 {
10377 	struct bwn_dma *dma = &mac->mac_method.dma;
10378 	struct bwn_dma_ring *dr;
10379 	struct bwn_softc *sc = mac->mac_sc;
10380 
10381 	switch (cookie & 0xf000) {
10382 	case 0x1000:
10383 		dr = dma->wme[WME_AC_BK];
10384 		break;
10385 	case 0x2000:
10386 		dr = dma->wme[WME_AC_BE];
10387 		break;
10388 	case 0x3000:
10389 		dr = dma->wme[WME_AC_VI];
10390 		break;
10391 	case 0x4000:
10392 		dr = dma->wme[WME_AC_VO];
10393 		break;
10394 	case 0x5000:
10395 		dr = dma->mcast;
10396 		break;
10397 	default:
10398 		dr = NULL;
10399 		KASSERT(0 == 1,
10400 		    ("invalid cookie value %d", cookie & 0xf000));
10401 	}
10402 	*slot = (cookie & 0x0fff);
10403 	if (*slot < 0 || *slot >= dr->dr_numslots) {
10404 		/*
10405 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10406 		 * that it occurs events which have same H/W sequence numbers.
10407 		 * When it's occurred just prints a WARNING msgs and ignores.
10408 		 */
10409 		KASSERT(status->seq == dma->lastseq,
10410 		    ("%s:%d: fail", __func__, __LINE__));
10411 		device_printf(sc->sc_dev,
10412 		    "out of slot ranges (0 < %d < %d)\n", *slot,
10413 		    dr->dr_numslots);
10414 		return (NULL);
10415 	}
10416 	dma->lastseq = status->seq;
10417 	return (dr);
10418 }
10419 
10420 static void
10421 bwn_dma_stop(struct bwn_mac *mac)
10422 {
10423 	struct bwn_dma *dma;
10424 
10425 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10426 		return;
10427 	dma = &mac->mac_method.dma;
10428 
10429 	bwn_dma_ringstop(&dma->rx);
10430 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10431 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10432 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10433 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10434 	bwn_dma_ringstop(&dma->mcast);
10435 }
10436 
10437 static void
10438 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10439 {
10440 
10441 	if (dr == NULL)
10442 		return;
10443 
10444 	bwn_dma_cleanup(*dr);
10445 }
10446 
10447 static void
10448 bwn_pio_stop(struct bwn_mac *mac)
10449 {
10450 	struct bwn_pio *pio;
10451 
10452 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10453 		return;
10454 	pio = &mac->mac_method.pio;
10455 
10456 	bwn_destroy_queue_tx(&pio->mcast);
10457 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10458 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10459 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10460 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10461 }
10462 
10463 static void
10464 bwn_led_attach(struct bwn_mac *mac)
10465 {
10466 	struct bwn_softc *sc = mac->mac_sc;
10467 	const uint8_t *led_act = NULL;
10468 	uint16_t val[BWN_LED_MAX];
10469 	int i;
10470 
10471 	sc->sc_led_idle = (2350 * hz) / 1000;
10472 	sc->sc_led_blink = 1;
10473 
10474 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10475 		if (siba_get_pci_subvendor(sc->sc_dev) ==
10476 		    bwn_vendor_led_act[i].vid) {
10477 			led_act = bwn_vendor_led_act[i].led_act;
10478 			break;
10479 		}
10480 	}
10481 	if (led_act == NULL)
10482 		led_act = bwn_default_led_act;
10483 
10484 	val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10485 	val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10486 	val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10487 	val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10488 
10489 	for (i = 0; i < BWN_LED_MAX; ++i) {
10490 		struct bwn_led *led = &sc->sc_leds[i];
10491 
10492 		if (val[i] == 0xff) {
10493 			led->led_act = led_act[i];
10494 		} else {
10495 			if (val[i] & BWN_LED_ACT_LOW)
10496 				led->led_flags |= BWN_LED_F_ACTLOW;
10497 			led->led_act = val[i] & BWN_LED_ACT_MASK;
10498 		}
10499 		led->led_mask = (1 << i);
10500 
10501 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10502 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
10503 		    led->led_act == BWN_LED_ACT_BLINK) {
10504 			led->led_flags |= BWN_LED_F_BLINK;
10505 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10506 				led->led_flags |= BWN_LED_F_POLLABLE;
10507 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10508 				led->led_flags |= BWN_LED_F_SLOW;
10509 
10510 			if (sc->sc_blink_led == NULL) {
10511 				sc->sc_blink_led = led;
10512 				if (led->led_flags & BWN_LED_F_SLOW)
10513 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
10514 			}
10515 		}
10516 
10517 		DPRINTF(sc, BWN_DEBUG_LED,
10518 		    "%dth led, act %d, lowact %d\n", i,
10519 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10520 	}
10521 	callout_init(&sc->sc_led_blink_ch);
10522 }
10523 
10524 static __inline uint16_t
10525 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10526 {
10527 
10528 	if (led->led_flags & BWN_LED_F_ACTLOW)
10529 		on = !on;
10530 	if (on)
10531 		val |= led->led_mask;
10532 	else
10533 		val &= ~led->led_mask;
10534 	return val;
10535 }
10536 
10537 static void
10538 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10539 {
10540 	struct bwn_softc *sc = mac->mac_sc;
10541 	struct ifnet *ifp = sc->sc_ifp;
10542 	struct ieee80211com *ic = ifp->if_l2com;
10543 	uint16_t val;
10544 	int i;
10545 
10546 	if (nstate == IEEE80211_S_INIT) {
10547 		callout_stop(&sc->sc_led_blink_ch);
10548 		sc->sc_led_blinking = 0;
10549 	}
10550 
10551 	if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0)
10552 		return;
10553 
10554 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10555 	for (i = 0; i < BWN_LED_MAX; ++i) {
10556 		struct bwn_led *led = &sc->sc_leds[i];
10557 		int on;
10558 
10559 		if (led->led_act == BWN_LED_ACT_UNKN ||
10560 		    led->led_act == BWN_LED_ACT_NULL)
10561 			continue;
10562 
10563 		if ((led->led_flags & BWN_LED_F_BLINK) &&
10564 		    nstate != IEEE80211_S_INIT)
10565 			continue;
10566 
10567 		switch (led->led_act) {
10568 		case BWN_LED_ACT_ON:    /* Always on */
10569 			on = 1;
10570 			break;
10571 		case BWN_LED_ACT_OFF:   /* Always off */
10572 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10573 			on = 0;
10574 			break;
10575 		default:
10576 			on = 1;
10577 			switch (nstate) {
10578 			case IEEE80211_S_INIT:
10579 				on = 0;
10580 				break;
10581 			case IEEE80211_S_RUN:
10582 				if (led->led_act == BWN_LED_ACT_11G &&
10583 				    ic->ic_curmode != IEEE80211_MODE_11G)
10584 					on = 0;
10585 				break;
10586 			default:
10587 				if (led->led_act == BWN_LED_ACT_ASSOC)
10588 					on = 0;
10589 				break;
10590 			}
10591 			break;
10592 		}
10593 
10594 		val = bwn_led_onoff(led, val, on);
10595 	}
10596 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10597 }
10598 
10599 static void
10600 bwn_led_event(struct bwn_mac *mac, int event)
10601 {
10602 	struct bwn_softc *sc = mac->mac_sc;
10603 	struct bwn_led *led = sc->sc_blink_led;
10604 	int rate;
10605 
10606 	if (event == BWN_LED_EVENT_POLL) {
10607 		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10608 			return;
10609 		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10610 			return;
10611 	}
10612 
10613 	sc->sc_led_ticks = ticks;
10614 	if (sc->sc_led_blinking)
10615 		return;
10616 
10617 	switch (event) {
10618 	case BWN_LED_EVENT_RX:
10619 		rate = sc->sc_rx_rate;
10620 		break;
10621 	case BWN_LED_EVENT_TX:
10622 		rate = sc->sc_tx_rate;
10623 		break;
10624 	case BWN_LED_EVENT_POLL:
10625 		rate = 0;
10626 		break;
10627 	default:
10628 		panic("unknown LED event %d\n", event);
10629 		break;
10630 	}
10631 	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10632 	    bwn_led_duration[rate].off_dur);
10633 }
10634 
10635 static void
10636 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10637 {
10638 	struct bwn_softc *sc = mac->mac_sc;
10639 	struct bwn_led *led = sc->sc_blink_led;
10640 	uint16_t val;
10641 
10642 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10643 	val = bwn_led_onoff(led, val, 1);
10644 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10645 
10646 	if (led->led_flags & BWN_LED_F_SLOW) {
10647 		BWN_LED_SLOWDOWN(on_dur);
10648 		BWN_LED_SLOWDOWN(off_dur);
10649 	}
10650 
10651 	sc->sc_led_blinking = 1;
10652 	sc->sc_led_blink_offdur = off_dur;
10653 
10654 	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10655 }
10656 
10657 static void
10658 bwn_led_blink_next(void *arg)
10659 {
10660 	struct bwn_mac *mac = arg;
10661 	struct bwn_softc *sc = mac->mac_sc;
10662 	uint16_t val;
10663 
10664 	wlan_serialize_enter();
10665 
10666 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10667 	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10668 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10669 
10670 	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10671 	    bwn_led_blink_end, mac);
10672 	wlan_serialize_exit();
10673 }
10674 
10675 static void
10676 bwn_led_blink_end(void *arg)
10677 {
10678 	struct bwn_mac *mac = arg;
10679 	struct bwn_softc *sc = mac->mac_sc;
10680 
10681 	sc->sc_led_blinking = 0;
10682 }
10683 
10684 static int
10685 bwn_suspend(device_t dev)
10686 {
10687 	struct bwn_softc *sc = device_get_softc(dev);
10688 
10689 	wlan_serialize_enter();
10690 	bwn_stop(sc, 1);
10691 	wlan_serialize_exit();
10692 
10693 	return (0);
10694 }
10695 
10696 static int
10697 bwn_resume(device_t dev)
10698 {
10699 	struct bwn_softc *sc = device_get_softc(dev);
10700 	struct ifnet *ifp = sc->sc_ifp;
10701 
10702 	wlan_serialize_enter();
10703 	if (ifp->if_flags & IFF_UP)
10704 		bwn_init(sc);
10705 	wlan_serialize_exit();
10706 	return (0);
10707 }
10708 
10709 static void
10710 bwn_rfswitch(void *arg)
10711 {
10712 	struct bwn_softc *sc = arg;
10713 	struct bwn_mac *mac = sc->sc_curmac;
10714 	int cur = 0, prev = 0;
10715 
10716 	wlan_serialize_enter();
10717 
10718 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10719 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
10720 
10721 	if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10722 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10723 			& BWN_RF_HWENABLED_HI_MASK))
10724 			cur = 1;
10725 	} else {
10726 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10727 		    & BWN_RF_HWENABLED_LO_MASK)
10728 			cur = 1;
10729 	}
10730 
10731 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10732 		prev = 1;
10733 
10734 	if (cur != prev) {
10735 		if (cur)
10736 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10737 		else
10738 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10739 
10740 		device_printf(sc->sc_dev,
10741 		    "status of RF switch is changed to %s\n",
10742 		    cur ? "ON" : "OFF");
10743 		if (cur != mac->mac_phy.rf_on) {
10744 			if (cur)
10745 				bwn_rf_turnon(mac);
10746 			else
10747 				bwn_rf_turnoff(mac);
10748 		}
10749 	}
10750 
10751 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
10752 	wlan_serialize_exit();
10753 }
10754 
10755 static void
10756 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10757 {
10758 	struct bwn_phy *phy = &mac->mac_phy;
10759 	struct bwn_phy_lp *plp = &phy->phy_lp;
10760 
10761 	plp->plp_antenna = BWN_ANT_DEFAULT;
10762 }
10763 
10764 static int
10765 bwn_phy_lp_init(struct bwn_mac *mac)
10766 {
10767 	static const struct bwn_stxtable tables[] = {
10768 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10769 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10770 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10771 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10772 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10773 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10774 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10775 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10776 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10777 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10778 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10779 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10780 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10781 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10782 		{ 2, 11, 0x40, 0, 0x0f }
10783 	};
10784 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10785 	struct bwn_softc *sc = mac->mac_sc;
10786 	const struct bwn_stxtable *st;
10787 	struct ifnet *ifp = sc->sc_ifp;
10788 	struct ieee80211com *ic = ifp->if_l2com;
10789 	int i, error;
10790 	uint16_t tmp;
10791 
10792 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
10793 	bwn_phy_lp_bbinit(mac);
10794 
10795 	/* initialize RF */
10796 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10797 	DELAY(1);
10798 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10799 	DELAY(1);
10800 
10801 	if (mac->mac_phy.rf_ver == 0x2062)
10802 		bwn_phy_lp_b2062_init(mac);
10803 	else {
10804 		bwn_phy_lp_b2063_init(mac);
10805 
10806 		/* synchronize stx table. */
10807 		for (i = 0; i < N(tables); i++) {
10808 			st = &tables[i];
10809 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
10810 			tmp >>= st->st_rfshift;
10811 			tmp <<= st->st_physhift;
10812 			BWN_PHY_SETMASK(mac,
10813 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10814 			    ~(st->st_mask << st->st_physhift), tmp);
10815 		}
10816 
10817 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10818 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10819 	}
10820 
10821 	/* calibrate RC */
10822 	if (mac->mac_phy.rev >= 2)
10823 		bwn_phy_lp_rxcal_r2(mac);
10824 	else if (!plp->plp_rccap) {
10825 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10826 			bwn_phy_lp_rccal_r12(mac);
10827 	} else
10828 		bwn_phy_lp_set_rccap(mac);
10829 
10830 	error = bwn_phy_lp_switch_channel(mac, 7);
10831 	if (error)
10832 		device_printf(sc->sc_dev,
10833 		    "failed to change channel 7 (%d)\n", error);
10834 	bwn_phy_lp_txpctl_init(mac);
10835 	bwn_phy_lp_calib(mac);
10836 	return (0);
10837 }
10838 
10839 static uint16_t
10840 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10841 {
10842 
10843 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10844 	return (BWN_READ_2(mac, BWN_PHYDATA));
10845 }
10846 
10847 static void
10848 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10849 {
10850 
10851 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10852 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
10853 }
10854 
10855 static void
10856 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10857     uint16_t set)
10858 {
10859 
10860 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10861 	BWN_WRITE_2(mac, BWN_PHYDATA,
10862 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10863 }
10864 
10865 static uint16_t
10866 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10867 {
10868 
10869 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10870 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
10871 		reg |= 0x100;
10872 	if (mac->mac_phy.rev >= 2)
10873 		reg |= 0x200;
10874 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10875 	return BWN_READ_2(mac, BWN_RFDATALO);
10876 }
10877 
10878 static void
10879 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10880 {
10881 
10882 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10883 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10884 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
10885 }
10886 
10887 static void
10888 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10889 {
10890 
10891 	if (on) {
10892 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10893 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10894 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10895 		return;
10896 	}
10897 
10898 	if (mac->mac_phy.rev >= 2) {
10899 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10900 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10901 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10902 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10903 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10904 		return;
10905 	}
10906 
10907 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10908 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10909 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10910 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10911 }
10912 
10913 static int
10914 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10915 {
10916 	struct bwn_phy *phy = &mac->mac_phy;
10917 	struct bwn_phy_lp *plp = &phy->phy_lp;
10918 	int error;
10919 
10920 	if (phy->rf_ver == 0x2063) {
10921 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10922 		if (error)
10923 			return (error);
10924 	} else {
10925 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10926 		if (error)
10927 			return (error);
10928 		bwn_phy_lp_set_anafilter(mac, chan);
10929 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10930 	}
10931 
10932 	plp->plp_chan = chan;
10933 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10934 	return (0);
10935 }
10936 
10937 static uint32_t
10938 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10939 {
10940 	struct bwn_softc *sc = mac->mac_sc;
10941 	struct ifnet *ifp = sc->sc_ifp;
10942 	struct ieee80211com *ic = ifp->if_l2com;
10943 
10944 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10945 }
10946 
10947 static void
10948 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10949 {
10950 	struct bwn_phy *phy = &mac->mac_phy;
10951 	struct bwn_phy_lp *plp = &phy->phy_lp;
10952 
10953 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10954 		return;
10955 
10956 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10957 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10958 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10959 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10960 	plp->plp_antenna = antenna;
10961 }
10962 
10963 static void
10964 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10965 {
10966 
10967 	bwn_phy_lp_calib(mac);
10968 }
10969 
10970 static void
10971 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10972 {
10973 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10974 	struct bwn_softc *sc = mac->mac_sc;
10975 	struct ifnet *ifp = sc->sc_ifp;
10976 	struct ieee80211com *ic = ifp->if_l2com;
10977 
10978 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10979 		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10980 		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10981 		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10982 		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10983 		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10984 		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10985 		return;
10986 	}
10987 
10988 	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10989 	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10990 	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10991 	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10992 	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10993 	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10994 	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10995 	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10996 }
10997 
10998 static void
10999 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11000 {
11001 
11002 	bwn_phy_lp_tblinit(mac);
11003 	if (mac->mac_phy.rev >= 2)
11004 		bwn_phy_lp_bbinit_r2(mac);
11005 	else
11006 		bwn_phy_lp_bbinit_r01(mac);
11007 }
11008 
11009 static void
11010 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11011 {
11012 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11013 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11014 	struct bwn_softc *sc = mac->mac_sc;
11015 	struct ifnet *ifp = sc->sc_ifp;
11016 	struct ieee80211com *ic = ifp->if_l2com;
11017 
11018 	bwn_phy_lp_set_txgain(mac,
11019 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11020 	bwn_phy_lp_set_bbmult(mac, 150);
11021 }
11022 
11023 static void
11024 bwn_phy_lp_calib(struct bwn_mac *mac)
11025 {
11026 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11027 	struct bwn_softc *sc = mac->mac_sc;
11028 	struct ifnet *ifp = sc->sc_ifp;
11029 	struct ieee80211com *ic = ifp->if_l2com;
11030 	const struct bwn_rxcompco *rc = NULL;
11031 	struct bwn_txgain ogain;
11032 	int i, omode, oafeovr, orf, obbmult;
11033 	uint8_t mode, fc = 0;
11034 
11035 	if (plp->plp_chanfullcal != plp->plp_chan) {
11036 		plp->plp_chanfullcal = plp->plp_chan;
11037 		fc = 1;
11038 	}
11039 
11040 	bwn_mac_suspend(mac);
11041 
11042 	/* BlueTooth Coexistance Override */
11043 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11044 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11045 
11046 	if (mac->mac_phy.rev >= 2)
11047 		bwn_phy_lp_digflt_save(mac);
11048 	bwn_phy_lp_get_txpctlmode(mac);
11049 	mode = plp->plp_txpctlmode;
11050 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11051 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11052 		bwn_phy_lp_bugfix(mac);
11053 	if (mac->mac_phy.rev >= 2 && fc == 1) {
11054 		bwn_phy_lp_get_txpctlmode(mac);
11055 		omode = plp->plp_txpctlmode;
11056 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11057 		if (oafeovr)
11058 			ogain = bwn_phy_lp_get_txgain(mac);
11059 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11060 		obbmult = bwn_phy_lp_get_bbmult(mac);
11061 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11062 		if (oafeovr)
11063 			bwn_phy_lp_set_txgain(mac, &ogain);
11064 		bwn_phy_lp_set_bbmult(mac, obbmult);
11065 		bwn_phy_lp_set_txpctlmode(mac, omode);
11066 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11067 	}
11068 	bwn_phy_lp_set_txpctlmode(mac, mode);
11069 	if (mac->mac_phy.rev >= 2)
11070 		bwn_phy_lp_digflt_restore(mac);
11071 
11072 	/* do RX IQ Calculation; assumes that noise is true. */
11073 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11074 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11075 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11076 				rc = &bwn_rxcompco_5354[i];
11077 		}
11078 	} else if (mac->mac_phy.rev >= 2)
11079 		rc = &bwn_rxcompco_r2;
11080 	else {
11081 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11082 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11083 				rc = &bwn_rxcompco_r12[i];
11084 		}
11085 	}
11086 	if (rc == NULL)
11087 		goto fail;
11088 
11089 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11090 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11091 
11092 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11093 
11094 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11095 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11096 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11097 	} else {
11098 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11099 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11100 	}
11101 
11102 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11103 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11104 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11105 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11106 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11107 	bwn_phy_lp_set_deaf(mac, 0);
11108 	/* XXX no checking return value? */
11109 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11110 	bwn_phy_lp_clear_deaf(mac, 0);
11111 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11112 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11113 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11114 
11115 	/* disable RX GAIN override. */
11116 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11117 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11118 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11119 	if (mac->mac_phy.rev >= 2) {
11120 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11121 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11122 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11123 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11124 		}
11125 	} else {
11126 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11127 	}
11128 
11129 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11130 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11131 fail:
11132 	bwn_mac_enable(mac);
11133 }
11134 
11135 static void
11136 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11137 {
11138 
11139 	if (on) {
11140 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11141 		return;
11142 	}
11143 
11144 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11145 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11146 }
11147 
11148 static int
11149 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11150 {
11151 	static const struct bwn_b206x_chan *bc = NULL;
11152 	struct bwn_softc *sc = mac->mac_sc;
11153 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11154 	    tmp[6];
11155 	uint16_t old, scale, tmp16;
11156 	int i, div;
11157 
11158 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
11159 		if (bwn_b2063_chantable[i].bc_chan == chan) {
11160 			bc = &bwn_b2063_chantable[i];
11161 			break;
11162 		}
11163 	}
11164 	if (bc == NULL)
11165 		return (EINVAL);
11166 
11167 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11168 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11169 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11170 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11171 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11172 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11173 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11174 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11175 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11176 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11177 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11178 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11179 
11180 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
11181 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11182 
11183 	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11184 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11185 	freqref = freqxtal * 3;
11186 	div = (freqxtal <= 26000000 ? 1 : 2);
11187 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11188 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11189 		999999) / 1000000) + 1;
11190 
11191 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11192 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11193 	    0xfff8, timeout >> 2);
11194 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11195 	    0xff9f,timeout << 5);
11196 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11197 
11198 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11199 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11200 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11201 
11202 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11203 	    (timeoutref + 1)) - 1;
11204 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11205 	    0xf0, count >> 8);
11206 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11207 
11208 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
11209 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
11210 	while (tmp[1] >= freqref) {
11211 		tmp[0]++;
11212 		tmp[1] -= freqref;
11213 	}
11214 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11215 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11216 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11217 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11218 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11219 
11220 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11221 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11222 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11223 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11224 
11225 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11226 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11227 
11228 	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11229 		scale = 1;
11230 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11231 	} else {
11232 		scale = 0;
11233 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11234 	}
11235 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11236 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11237 
11238 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11239 	    (scale + 1);
11240 	if (tmp[5] > 150)
11241 		tmp[5] = 0;
11242 
11243 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11244 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11245 
11246 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11247 	if (freqxtal > 26000000)
11248 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11249 	else
11250 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11251 
11252 	if (val[0] == 45)
11253 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11254 	else
11255 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11256 
11257 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11258 	DELAY(1);
11259 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11260 
11261 	/* VCO Calibration */
11262 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11263 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11264 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11265 	DELAY(1);
11266 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11267 	DELAY(1);
11268 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11269 	DELAY(1);
11270 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11271 	DELAY(300);
11272 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11273 
11274 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11275 	return (0);
11276 }
11277 
11278 static int
11279 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11280 {
11281 	struct bwn_softc *sc = mac->mac_sc;
11282 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11283 	const struct bwn_b206x_chan *bc = NULL;
11284 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11285 	uint32_t tmp[9];
11286 	int i;
11287 
11288 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
11289 		if (bwn_b2062_chantable[i].bc_chan == chan) {
11290 			bc = &bwn_b2062_chantable[i];
11291 			break;
11292 		}
11293 	}
11294 
11295 	if (bc == NULL)
11296 		return (EINVAL);
11297 
11298 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11299 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11300 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11301 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11302 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11303 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11304 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11305 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11306 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11307 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11308 
11309 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11310 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11311 	bwn_phy_lp_b2062_reset_pllbias(mac);
11312 	tmp[0] = freqxtal / 1000;
11313 	tmp[1] = plp->plp_div * 1000;
11314 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11315 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
11316 		tmp[2] *= 2;
11317 	tmp[3] = 48 * tmp[0];
11318 	tmp[5] = tmp[2] / tmp[3];
11319 	tmp[6] = tmp[2] % tmp[3];
11320 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11321 	tmp[4] = tmp[6] * 0x100;
11322 	tmp[5] = tmp[4] / tmp[3];
11323 	tmp[6] = tmp[4] % tmp[3];
11324 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11325 	tmp[4] = tmp[6] * 0x100;
11326 	tmp[5] = tmp[4] / tmp[3];
11327 	tmp[6] = tmp[4] % tmp[3];
11328 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11329 	tmp[4] = tmp[6] * 0x100;
11330 	tmp[5] = tmp[4] / tmp[3];
11331 	tmp[6] = tmp[4] % tmp[3];
11332 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11333 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
11334 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11335 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11336 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11337 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11338 
11339 	bwn_phy_lp_b2062_vco_calib(mac);
11340 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11341 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11342 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11343 		bwn_phy_lp_b2062_reset_pllbias(mac);
11344 		bwn_phy_lp_b2062_vco_calib(mac);
11345 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11346 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11347 			return (EIO);
11348 		}
11349 	}
11350 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11351 	return (0);
11352 }
11353 
11354 static void
11355 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11356 {
11357 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11358 	uint16_t tmp = (channel == 14);
11359 
11360 	if (mac->mac_phy.rev < 2) {
11361 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11362 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11363 			bwn_phy_lp_set_rccap(mac);
11364 		return;
11365 	}
11366 
11367 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11368 }
11369 
11370 static void
11371 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11372 {
11373 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11374 	struct bwn_softc *sc = mac->mac_sc;
11375 	struct ifnet *ifp = sc->sc_ifp;
11376 	struct ieee80211com *ic = ifp->if_l2com;
11377 	uint16_t iso, tmp[3];
11378 
11379 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11380 
11381 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11382 		iso = plp->plp_txisoband_m;
11383 	else if (freq <= 5320)
11384 		iso = plp->plp_txisoband_l;
11385 	else if (freq <= 5700)
11386 		iso = plp->plp_txisoband_m;
11387 	else
11388 		iso = plp->plp_txisoband_h;
11389 
11390 	tmp[0] = ((iso - 26) / 12) << 12;
11391 	tmp[1] = tmp[0] + 0x1000;
11392 	tmp[2] = tmp[0] + 0x2000;
11393 
11394 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11395 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11396 }
11397 
11398 static void
11399 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11400 {
11401 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11402 	int i;
11403 	static const uint16_t addr[] = {
11404 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11405 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11406 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11407 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11408 		BWN_PHY_OFDM(0xcf),
11409 	};
11410 	static const uint16_t val[] = {
11411 		0xde5e, 0xe832, 0xe331, 0x4d26,
11412 		0x0026, 0x1420, 0x0020, 0xfe08,
11413 		0x0008,
11414 	};
11415 
11416 	for (i = 0; i < N(addr); i++) {
11417 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11418 		BWN_PHY_WRITE(mac, addr[i], val[i]);
11419 	}
11420 }
11421 
11422 static void
11423 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11424 {
11425 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11426 	struct bwn_softc *sc = mac->mac_sc;
11427 	uint16_t ctl;
11428 
11429 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11430 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11431 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11432 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11433 		break;
11434 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11435 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11436 		break;
11437 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11438 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11439 		break;
11440 	default:
11441 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11442 		device_printf(sc->sc_dev, "unknown command mode\n");
11443 		break;
11444 	}
11445 }
11446 
11447 static void
11448 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11449 {
11450 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11451 	uint16_t ctl;
11452 	uint8_t old;
11453 
11454 	bwn_phy_lp_get_txpctlmode(mac);
11455 	old = plp->plp_txpctlmode;
11456 	if (old == mode)
11457 		return;
11458 	plp->plp_txpctlmode = mode;
11459 
11460 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11461 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11462 		    plp->plp_tssiidx);
11463 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11464 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11465 
11466 		/* disable TX GAIN override */
11467 		if (mac->mac_phy.rev < 2)
11468 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11469 		else {
11470 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11471 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11472 		}
11473 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11474 
11475 		plp->plp_txpwridx = -1;
11476 	}
11477 	if (mac->mac_phy.rev >= 2) {
11478 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11479 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11480 		else
11481 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11482 	}
11483 
11484 	/* writes TX Power Control mode */
11485 	switch (plp->plp_txpctlmode) {
11486 	case BWN_PHYLP_TXPCTL_OFF:
11487 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11488 		break;
11489 	case BWN_PHYLP_TXPCTL_ON_HW:
11490 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11491 		break;
11492 	case BWN_PHYLP_TXPCTL_ON_SW:
11493 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11494 		break;
11495 	default:
11496 		ctl = 0;
11497 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11498 	}
11499 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11500 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11501 }
11502 
11503 static void
11504 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11505 {
11506 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11507 	const unsigned int size = 256;
11508 	struct bwn_txgain tg;
11509 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11510 	uint16_t tssinpt, tssiidx, value[2];
11511 	uint8_t mode;
11512 	int8_t txpwridx;
11513 
11514 	tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF,
11515 	    M_INTWAIT | M_ZERO);
11516 
11517 	bwn_phy_lp_get_txpctlmode(mac);
11518 	mode = plp->plp_txpctlmode;
11519 	txpwridx = plp->plp_txpwridx;
11520 	tssinpt = plp->plp_tssinpt;
11521 	tssiidx = plp->plp_tssiidx;
11522 
11523 	bwn_tab_read_multi(mac,
11524 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11525 	    BWN_TAB_4(7, 0x140), size, tabs);
11526 
11527 	bwn_phy_lp_tblinit(mac);
11528 	bwn_phy_lp_bbinit(mac);
11529 	bwn_phy_lp_txpctl_init(mac);
11530 	bwn_phy_lp_rf_onoff(mac, 1);
11531 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11532 
11533 	bwn_tab_write_multi(mac,
11534 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11535 	    BWN_TAB_4(7, 0x140), size, tabs);
11536 
11537 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11538 	plp->plp_tssinpt = tssinpt;
11539 	plp->plp_tssiidx = tssiidx;
11540 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11541 	if (txpwridx != -1) {
11542 		/* set TX power by index */
11543 		plp->plp_txpwridx = txpwridx;
11544 		bwn_phy_lp_get_txpctlmode(mac);
11545 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11546 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11547 		if (mac->mac_phy.rev >= 2) {
11548 			rxcomp = bwn_tab_read(mac,
11549 			    BWN_TAB_4(7, txpwridx + 320));
11550 			txgain = bwn_tab_read(mac,
11551 			    BWN_TAB_4(7, txpwridx + 192));
11552 			tg.tg_pad = (txgain >> 16) & 0xff;
11553 			tg.tg_gm = txgain & 0xff;
11554 			tg.tg_pga = (txgain >> 8) & 0xff;
11555 			tg.tg_dac = (rxcomp >> 28) & 0xff;
11556 			bwn_phy_lp_set_txgain(mac, &tg);
11557 		} else {
11558 			rxcomp = bwn_tab_read(mac,
11559 			    BWN_TAB_4(10, txpwridx + 320));
11560 			txgain = bwn_tab_read(mac,
11561 			    BWN_TAB_4(10, txpwridx + 192));
11562 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11563 			    0xf800, (txgain >> 4) & 0x7fff);
11564 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11565 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11566 		}
11567 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11568 
11569 		/* set TX IQCC */
11570 		value[0] = (rxcomp >> 10) & 0x3ff;
11571 		value[1] = rxcomp & 0x3ff;
11572 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11573 
11574 		coeff = bwn_tab_read(mac,
11575 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11576 		    BWN_TAB_4(10, txpwridx + 448));
11577 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11578 		if (mac->mac_phy.rev >= 2) {
11579 			rfpwr = bwn_tab_read(mac,
11580 			    BWN_TAB_4(7, txpwridx + 576));
11581 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11582 			    rfpwr & 0xffff);
11583 		}
11584 		bwn_phy_lp_set_txgain_override(mac);
11585 	}
11586 	if (plp->plp_rccap)
11587 		bwn_phy_lp_set_rccap(mac);
11588 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11589 	bwn_phy_lp_set_txpctlmode(mac, mode);
11590 	kfree(tabs, M_DEVBUF);
11591 }
11592 
11593 static void
11594 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11595 {
11596 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11597 	int i;
11598 	static const uint16_t addr[] = {
11599 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11600 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11601 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11602 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11603 		BWN_PHY_OFDM(0xcf),
11604 	};
11605 
11606 	for (i = 0; i < N(addr); i++)
11607 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11608 }
11609 
11610 static void
11611 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11612 {
11613 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11614 
11615 	if (mac->mac_phy.rev < 2) {
11616 		bwn_phy_lp_tblinit_r01(mac);
11617 		bwn_phy_lp_tblinit_txgain(mac);
11618 		bwn_phy_lp_set_gaintbl(mac, freq);
11619 		return;
11620 	}
11621 
11622 	bwn_phy_lp_tblinit_r2(mac);
11623 	bwn_phy_lp_tblinit_txgain(mac);
11624 }
11625 
11626 struct bwn_wpair {
11627 	uint16_t		reg;
11628 	uint16_t		value;
11629 };
11630 
11631 struct bwn_smpair {
11632 	uint16_t		offset;
11633 	uint16_t		mask;
11634 	uint16_t		set;
11635 };
11636 
11637 static void
11638 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11639 {
11640 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11641 	struct bwn_softc *sc = mac->mac_sc;
11642 	struct ifnet *ifp = sc->sc_ifp;
11643 	struct ieee80211com *ic = ifp->if_l2com;
11644 	static const struct bwn_wpair v1[] = {
11645 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
11646 		{ BWN_PHY_AFE_CTL, 0x8800 },
11647 		{ BWN_PHY_AFE_CTL_OVR, 0 },
11648 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
11649 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
11650 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
11651 		{ BWN_PHY_OFDM(0xf9), 0 },
11652 		{ BWN_PHY_TR_LOOKUP_1, 0 }
11653 	};
11654 	static const struct bwn_smpair v2[] = {
11655 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11656 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11657 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11658 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11659 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11660 	};
11661 	static const struct bwn_smpair v3[] = {
11662 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11663 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11664 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11665 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11666 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11667 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11668 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11669 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11670 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11671 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11672 
11673 	};
11674 	int i;
11675 
11676 	for (i = 0; i < N(v1); i++)
11677 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11678 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11679 	for (i = 0; i < N(v2); i++)
11680 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11681 
11682 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11683 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11684 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11685 	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11686 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11687 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11688 	} else {
11689 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11690 	}
11691 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11692 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11693 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11694 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11695 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11696 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11697 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11698 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11699 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11700 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11701 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11702 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11703 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11704 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11705 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11706 	} else {
11707 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11708 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11709 	}
11710 	for (i = 0; i < N(v3); i++)
11711 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11712 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11713 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11714 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11715 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11716 	}
11717 
11718 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11719 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11720 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11721 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11722 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11723 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11724 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11725 	} else
11726 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11727 
11728 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11729 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11730 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11731 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11732 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11733 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11734 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11735 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11736 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11737 
11738 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11739 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11740 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11741 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11742 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11743 	}
11744 
11745 	bwn_phy_lp_digflt_save(mac);
11746 }
11747 
11748 static void
11749 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11750 {
11751 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11752 	struct bwn_softc *sc = mac->mac_sc;
11753 	struct ifnet *ifp = sc->sc_ifp;
11754 	struct ieee80211com *ic = ifp->if_l2com;
11755 	static const struct bwn_smpair v1[] = {
11756 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11757 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11758 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11759 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11760 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11761 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11762 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11763 	};
11764 	static const struct bwn_smpair v2[] = {
11765 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11766 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11767 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11768 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11769 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11770 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11771 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11772 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11773 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11774 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11775 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11776 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11777 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11778 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11779 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11780 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11781 	};
11782 	static const struct bwn_smpair v3[] = {
11783 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11784 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11785 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11786 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11787 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11788 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11789 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11790 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11791 	};
11792 	static const struct bwn_smpair v4[] = {
11793 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11794 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11795 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11796 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11797 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11798 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11799 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11800 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11801 	};
11802 	static const struct bwn_smpair v5[] = {
11803 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11804 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11805 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11806 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11807 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11808 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11809 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11810 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11811 	};
11812 	int i;
11813 	uint16_t tmp, tmp2;
11814 
11815 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11816 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11817 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11818 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11819 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11820 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11821 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11822 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11823 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11824 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11825 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11826 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11827 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11828 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11829 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11830 	for (i = 0; i < N(v1); i++)
11831 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11832 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11833 	    0xff00, plp->plp_rxpwroffset);
11834 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11835 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11836 	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11837 		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11838 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11839 		if (mac->mac_phy.rev == 0)
11840 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11841 			    0xffcf, 0x0010);
11842 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11843 	} else {
11844 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11845 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11846 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11847 	}
11848 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11849 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11850 	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11851 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11852 	else
11853 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11854 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11855 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11856 	    0xfff9, (plp->plp_bxarch << 1));
11857 	if (mac->mac_phy.rev == 1 &&
11858 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11859 		for (i = 0; i < N(v2); i++)
11860 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11861 			    v2[i].set);
11862 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11863 	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11864 	    ((mac->mac_phy.rev == 0) &&
11865 	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11866 		for (i = 0; i < N(v3); i++)
11867 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11868 			    v3[i].set);
11869 	} else if (mac->mac_phy.rev == 1 ||
11870 		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11871 		for (i = 0; i < N(v4); i++)
11872 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11873 			    v4[i].set);
11874 	} else {
11875 		for (i = 0; i < N(v5); i++)
11876 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11877 			    v5[i].set);
11878 	}
11879 	if (mac->mac_phy.rev == 1 &&
11880 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11881 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11882 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11883 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11884 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11885 	}
11886 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11887 	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11888 	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11889 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11890 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11891 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11892 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11893 	}
11894 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11895 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11896 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11897 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11898 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11899 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11900 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11901 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11902 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11903 	} else {
11904 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11905 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11906 	}
11907 	if (mac->mac_phy.rev == 1) {
11908 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11909 		tmp2 = (tmp & 0x03e0) >> 5;
11910 		tmp2 |= tmp2 << 5;
11911 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11912 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11913 		tmp2 = (tmp & 0x1f00) >> 8;
11914 		tmp2 |= tmp2 << 5;
11915 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11916 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11917 		tmp2 = tmp & 0x00ff;
11918 		tmp2 |= tmp << 8;
11919 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11920 	}
11921 }
11922 
11923 struct bwn_b2062_freq {
11924 	uint16_t		freq;
11925 	uint8_t			value[6];
11926 };
11927 
11928 static void
11929 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11930 {
11931 #define	CALC_CTL7(freq, div)						\
11932 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11933 #define	CALC_CTL18(freq, div)						\
11934 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11935 #define	CALC_CTL19(freq, div)						\
11936 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11937 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11938 	struct bwn_softc *sc = mac->mac_sc;
11939 	struct ifnet *ifp = sc->sc_ifp;
11940 	struct ieee80211com *ic = ifp->if_l2com;
11941 	static const struct bwn_b2062_freq freqdata_tab[] = {
11942 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
11943 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
11944 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
11945 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
11946 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
11947 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
11948 	};
11949 	static const struct bwn_wpair v1[] = {
11950 		{ BWN_B2062_N_TXCTL3, 0 },
11951 		{ BWN_B2062_N_TXCTL4, 0 },
11952 		{ BWN_B2062_N_TXCTL5, 0 },
11953 		{ BWN_B2062_N_TXCTL6, 0 },
11954 		{ BWN_B2062_N_PDNCTL0, 0x40 },
11955 		{ BWN_B2062_N_PDNCTL0, 0 },
11956 		{ BWN_B2062_N_CALIB_TS, 0x10 },
11957 		{ BWN_B2062_N_CALIB_TS, 0 }
11958 	};
11959 	const struct bwn_b2062_freq *f = NULL;
11960 	uint32_t xtalfreq, ref;
11961 	unsigned int i;
11962 
11963 	bwn_phy_lp_b2062_tblinit(mac);
11964 
11965 	for (i = 0; i < N(v1); i++)
11966 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11967 	if (mac->mac_phy.rev > 0)
11968 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11969 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11970 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11971 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11972 	else
11973 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11974 
11975 	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11976 	    ("%s:%d: fail", __func__, __LINE__));
11977 	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11978 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11979 
11980 	if (xtalfreq <= 30000000) {
11981 		plp->plp_div = 1;
11982 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11983 	} else {
11984 		plp->plp_div = 2;
11985 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11986 	}
11987 
11988 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11989 	    CALC_CTL7(xtalfreq, plp->plp_div));
11990 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11991 	    CALC_CTL18(xtalfreq, plp->plp_div));
11992 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11993 	    CALC_CTL19(xtalfreq, plp->plp_div));
11994 
11995 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11996 	ref &= 0xffff;
11997 	for (i = 0; i < N(freqdata_tab); i++) {
11998 		if (ref < freqdata_tab[i].freq) {
11999 			f = &freqdata_tab[i];
12000 			break;
12001 		}
12002 	}
12003 	if (f == NULL)
12004 		f = &freqdata_tab[N(freqdata_tab) - 1];
12005 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12006 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12007 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12008 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12009 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12010 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12011 #undef CALC_CTL7
12012 #undef CALC_CTL18
12013 #undef CALC_CTL19
12014 }
12015 
12016 static void
12017 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12018 {
12019 
12020 	bwn_phy_lp_b2063_tblinit(mac);
12021 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12022 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12023 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12024 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12025 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12026 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12027 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12028 	if (mac->mac_phy.rev == 2) {
12029 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12030 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12031 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12032 	} else {
12033 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12034 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12035 	}
12036 }
12037 
12038 static void
12039 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12040 {
12041 	struct bwn_softc *sc = mac->mac_sc;
12042 	static const struct bwn_wpair v1[] = {
12043 		{ BWN_B2063_RX_BB_SP8, 0x0 },
12044 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12045 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12046 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
12047 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
12048 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
12049 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
12050 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
12051 	};
12052 	static const struct bwn_wpair v2[] = {
12053 		{ BWN_B2063_TX_BB_SP3, 0x0 },
12054 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12055 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12056 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
12057 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
12058 	};
12059 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12060 	int i;
12061 	uint8_t tmp;
12062 
12063 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12064 
12065 	for (i = 0; i < 2; i++)
12066 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12067 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12068 	for (i = 2; i < N(v1); i++)
12069 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12070 	for (i = 0; i < 10000; i++) {
12071 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12072 			break;
12073 		DELAY(1000);
12074 	}
12075 
12076 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12077 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12078 
12079 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12080 
12081 	for (i = 0; i < N(v2); i++)
12082 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12083 	if (freqxtal == 24000000) {
12084 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12085 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12086 	} else {
12087 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12088 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12089 	}
12090 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12091 	for (i = 0; i < 10000; i++) {
12092 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12093 			break;
12094 		DELAY(1000);
12095 	}
12096 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12097 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12098 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12099 }
12100 
12101 static void
12102 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12103 {
12104 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12105 	struct bwn_softc *sc = mac->mac_sc;
12106 	struct bwn_phy_lp_iq_est ie;
12107 	struct bwn_txgain tx_gains;
12108 	static const uint32_t pwrtbl[21] = {
12109 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12110 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12111 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12112 		0x0004c, 0x0002c, 0x0001a,
12113 	};
12114 	uint32_t npwr, ipwr, sqpwr, tmp;
12115 	int loopback, i, j, sum, error;
12116 	uint16_t save[7];
12117 	uint8_t txo, bbmult, txpctlmode;
12118 
12119 	error = bwn_phy_lp_switch_channel(mac, 7);
12120 	if (error)
12121 		device_printf(sc->sc_dev,
12122 		    "failed to change channel to 7 (%d)\n", error);
12123 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12124 	bbmult = bwn_phy_lp_get_bbmult(mac);
12125 	if (txo)
12126 		tx_gains = bwn_phy_lp_get_txgain(mac);
12127 
12128 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12129 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12130 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12131 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12132 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12133 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12134 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12135 
12136 	bwn_phy_lp_get_txpctlmode(mac);
12137 	txpctlmode = plp->plp_txpctlmode;
12138 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12139 
12140 	/* disable CRS */
12141 	bwn_phy_lp_set_deaf(mac, 1);
12142 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
12143 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12144 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12145 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12146 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12147 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12148 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12149 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12150 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12151 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12152 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12153 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12154 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12155 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12156 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12157 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12158 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12159 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12160 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12161 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12162 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12163 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12164 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12165 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12166 
12167 	loopback = bwn_phy_lp_loopback(mac);
12168 	if (loopback == -1)
12169 		goto done;
12170 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
12171 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12172 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12173 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12174 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12175 
12176 	tmp = 0;
12177 	memset(&ie, 0, sizeof(ie));
12178 	for (i = 128; i <= 159; i++) {
12179 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12180 		sum = 0;
12181 		for (j = 5; j <= 25; j++) {
12182 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12183 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12184 				goto done;
12185 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12186 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12187 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12188 			    12);
12189 			sum += ((ipwr - npwr) * (ipwr - npwr));
12190 			if ((i == 128) || (sum < tmp)) {
12191 				plp->plp_rccap = i;
12192 				tmp = sum;
12193 			}
12194 		}
12195 	}
12196 	bwn_phy_lp_ddfs_turnoff(mac);
12197 done:
12198 	/* restore CRS */
12199 	bwn_phy_lp_clear_deaf(mac, 1);
12200 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12201 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12202 
12203 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12204 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12205 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12206 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12207 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12208 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12209 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12210 
12211 	bwn_phy_lp_set_bbmult(mac, bbmult);
12212 	if (txo)
12213 		bwn_phy_lp_set_txgain(mac, &tx_gains);
12214 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12215 	if (plp->plp_rccap)
12216 		bwn_phy_lp_set_rccap(mac);
12217 }
12218 
12219 static void
12220 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12221 {
12222 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12223 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12224 
12225 	if (mac->mac_phy.rev == 1)
12226 		rc_cap = MIN(rc_cap + 5, 15);
12227 
12228 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12229 	    MAX(plp->plp_rccap - 4, 0x80));
12230 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12231 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12232 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12233 }
12234 
12235 static uint32_t
12236 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12237 {
12238 	uint32_t i, q, r;
12239 
12240 	if (div == 0)
12241 		return (0);
12242 
12243 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12244 		q <<= 1;
12245 		if (r << 1 >= div) {
12246 			q++;
12247 			r = (r << 1) - div;
12248 		}
12249 	}
12250 	if (r << 1 >= div)
12251 		q++;
12252 	return (q);
12253 }
12254 
12255 static void
12256 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12257 {
12258 	struct bwn_softc *sc = mac->mac_sc;
12259 
12260 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12261 	DELAY(20);
12262 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12263 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12264 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12265 	} else {
12266 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12267 	}
12268 	DELAY(5);
12269 }
12270 
12271 static void
12272 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12273 {
12274 
12275 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12276 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12277 	DELAY(200);
12278 }
12279 
12280 static void
12281 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12282 {
12283 #define	FLAG_A	0x01
12284 #define	FLAG_G	0x02
12285 	struct bwn_softc *sc = mac->mac_sc;
12286 	struct ifnet *ifp = sc->sc_ifp;
12287 	struct ieee80211com *ic = ifp->if_l2com;
12288 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12289 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12290 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12291 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12292 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12293 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12294 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12295 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12296 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12297 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12298 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12299 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12300 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12301 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12302 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12303 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12304 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12305 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12306 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12307 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12308 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12309 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12310 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12311 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12312 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12313 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12314 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12315 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12316 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12317 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12318 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12319 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12320 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12321 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12322 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12323 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12324 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12325 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12326 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12327 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12328 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12329 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12330 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12331 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12332 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12333 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12334 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12335 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12336 	};
12337 	const struct bwn_b206x_rfinit_entry *br;
12338 	unsigned int i;
12339 
12340 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12341 		br = &bwn_b2062_init_tab[i];
12342 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12343 			if (br->br_flags & FLAG_G)
12344 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12345 		} else {
12346 			if (br->br_flags & FLAG_A)
12347 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12348 		}
12349 	}
12350 #undef FLAG_A
12351 #undef FLAG_B
12352 }
12353 
12354 static void
12355 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12356 {
12357 #define	FLAG_A	0x01
12358 #define	FLAG_G	0x02
12359 	struct bwn_softc *sc = mac->mac_sc;
12360 	struct ifnet *ifp = sc->sc_ifp;
12361 	struct ieee80211com *ic = ifp->if_l2com;
12362 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12363 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12364 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12365 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12366 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12367 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12368 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12369 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12370 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12371 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12372 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12373 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12374 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12375 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12376 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12377 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12378 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12379 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12380 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12381 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12382 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12383 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12384 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12385 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12386 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12387 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12388 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12389 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12390 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12391 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12392 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12393 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12394 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12395 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12396 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12397 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12398 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12399 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12400 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12401 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12402 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12403 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12404 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12405 	};
12406 	const struct bwn_b206x_rfinit_entry *br;
12407 	unsigned int i;
12408 
12409 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12410 		br = &bwn_b2063_init_tab[i];
12411 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12412 			if (br->br_flags & FLAG_G)
12413 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12414 		} else {
12415 			if (br->br_flags & FLAG_A)
12416 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12417 		}
12418 	}
12419 #undef FLAG_A
12420 #undef FLAG_B
12421 }
12422 
12423 static void
12424 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12425     int count, void *_data)
12426 {
12427 	unsigned int i;
12428 	uint32_t offset, type;
12429 	uint8_t *data = _data;
12430 
12431 	type = BWN_TAB_GETTYPE(typenoffset);
12432 	offset = BWN_TAB_GETOFFSET(typenoffset);
12433 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12434 
12435 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12436 
12437 	for (i = 0; i < count; i++) {
12438 		switch (type) {
12439 		case BWN_TAB_8BIT:
12440 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12441 			data++;
12442 			break;
12443 		case BWN_TAB_16BIT:
12444 			*((uint16_t *)data) = BWN_PHY_READ(mac,
12445 			    BWN_PHY_TABLEDATALO);
12446 			data += 2;
12447 			break;
12448 		case BWN_TAB_32BIT:
12449 			*((uint32_t *)data) = BWN_PHY_READ(mac,
12450 			    BWN_PHY_TABLEDATAHI);
12451 			*((uint32_t *)data) <<= 16;
12452 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
12453 			    BWN_PHY_TABLEDATALO);
12454 			data += 4;
12455 			break;
12456 		default:
12457 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12458 		}
12459 	}
12460 }
12461 
12462 static void
12463 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12464     int count, const void *_data)
12465 {
12466 	uint32_t offset, type, value;
12467 	const uint8_t *data = _data;
12468 	unsigned int i;
12469 
12470 	type = BWN_TAB_GETTYPE(typenoffset);
12471 	offset = BWN_TAB_GETOFFSET(typenoffset);
12472 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12473 
12474 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12475 
12476 	for (i = 0; i < count; i++) {
12477 		switch (type) {
12478 		case BWN_TAB_8BIT:
12479 			value = *data;
12480 			data++;
12481 			KASSERT(!(value & ~0xff),
12482 			    ("%s:%d: fail", __func__, __LINE__));
12483 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12484 			break;
12485 		case BWN_TAB_16BIT:
12486 			value = *((const uint16_t *)data);
12487 			data += 2;
12488 			KASSERT(!(value & ~0xffff),
12489 			    ("%s:%d: fail", __func__, __LINE__));
12490 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12491 			break;
12492 		case BWN_TAB_32BIT:
12493 			value = *((const uint32_t *)data);
12494 			data += 4;
12495 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12496 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12497 			break;
12498 		default:
12499 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12500 		}
12501 	}
12502 }
12503 
12504 static struct bwn_txgain
12505 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12506 {
12507 	struct bwn_txgain tg;
12508 	uint16_t tmp;
12509 
12510 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12511 	if (mac->mac_phy.rev < 2) {
12512 		tmp = BWN_PHY_READ(mac,
12513 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12514 		tg.tg_gm = tmp & 0x0007;
12515 		tg.tg_pga = (tmp & 0x0078) >> 3;
12516 		tg.tg_pad = (tmp & 0x780) >> 7;
12517 		return (tg);
12518 	}
12519 
12520 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12521 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12522 	tg.tg_gm = tmp & 0xff;
12523 	tg.tg_pga = (tmp >> 8) & 0xff;
12524 	return (tg);
12525 }
12526 
12527 static uint8_t
12528 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12529 {
12530 
12531 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12532 }
12533 
12534 static void
12535 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12536 {
12537 	uint16_t pa;
12538 
12539 	if (mac->mac_phy.rev < 2) {
12540 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12541 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12542 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12543 		bwn_phy_lp_set_txgain_override(mac);
12544 		return;
12545 	}
12546 
12547 	pa = bwn_phy_lp_get_pa_gain(mac);
12548 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12549 	    (tg->tg_pga << 8) | tg->tg_gm);
12550 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12551 	    tg->tg_pad | (pa << 6));
12552 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12553 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12554 	    tg->tg_pad | (pa << 8));
12555 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12556 	bwn_phy_lp_set_txgain_override(mac);
12557 }
12558 
12559 static void
12560 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12561 {
12562 
12563 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12564 }
12565 
12566 static void
12567 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12568 {
12569 	uint16_t trsw = (tx << 1) | rx;
12570 
12571 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12572 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12573 }
12574 
12575 static void
12576 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12577 {
12578 	struct bwn_softc *sc = mac->mac_sc;
12579 	struct ifnet *ifp = sc->sc_ifp;
12580 	struct ieee80211com *ic = ifp->if_l2com;
12581 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12582 
12583 	if (mac->mac_phy.rev < 2) {
12584 		trsw = gain & 0x1;
12585 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12586 		ext_lna = (gain & 2) >> 1;
12587 
12588 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12589 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12590 		    0xfbff, ext_lna << 10);
12591 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12592 		    0xf7ff, ext_lna << 11);
12593 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12594 	} else {
12595 		low_gain = gain & 0xffff;
12596 		high_gain = (gain >> 16) & 0xf;
12597 		ext_lna = (gain >> 21) & 0x1;
12598 		trsw = ~(gain >> 20) & 0x1;
12599 
12600 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12601 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12602 		    0xfdff, ext_lna << 9);
12603 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12604 		    0xfbff, ext_lna << 10);
12605 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12606 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12607 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12608 			tmp = (gain >> 2) & 0x3;
12609 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12610 			    0xe7ff, tmp<<11);
12611 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12612 			    tmp << 3);
12613 		}
12614 	}
12615 
12616 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12617 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12618 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12619 	if (mac->mac_phy.rev >= 2) {
12620 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12621 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12622 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12623 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12624 		}
12625 		return;
12626 	}
12627 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12628 }
12629 
12630 static void
12631 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12632 {
12633 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12634 
12635 	if (user)
12636 		plp->plp_crsusr_off = 1;
12637 	else
12638 		plp->plp_crssys_off = 1;
12639 
12640 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12641 }
12642 
12643 static void
12644 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12645 {
12646 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12647 	struct bwn_softc *sc = mac->mac_sc;
12648 	struct ifnet *ifp = sc->sc_ifp;
12649 	struct ieee80211com *ic = ifp->if_l2com;
12650 
12651 	if (user)
12652 		plp->plp_crsusr_off = 0;
12653 	else
12654 		plp->plp_crssys_off = 0;
12655 
12656 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
12657 		return;
12658 
12659 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12660 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12661 	else
12662 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12663 }
12664 
12665 static unsigned int
12666 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12667 {
12668 	/* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12669 	static uint8_t sqrt_table[256] = {
12670 		10, 14, 17, 20, 22, 24, 26, 28,
12671 		30, 31, 33, 34, 36, 37, 38, 40,
12672 		41, 42, 43, 44, 45, 46, 47, 48,
12673 		50, 50, 51, 52, 53, 54, 55, 56,
12674 		57, 58, 59, 60, 60, 61, 62, 63,
12675 		64, 64, 65, 66, 67, 67, 68, 69,
12676 		70, 70, 71, 72, 72, 73, 74, 74,
12677 		75, 76, 76, 77, 78, 78, 79, 80,
12678 		80, 81, 81, 82, 83, 83, 84, 84,
12679 		85, 86, 86, 87, 87, 88, 88, 89,
12680 		90, 90, 91, 91, 92, 92, 93, 93,
12681 		94, 94, 95, 95, 96, 96, 97, 97,
12682 		98, 98, 99, 100, 100, 100, 101, 101,
12683 		102, 102, 103, 103, 104, 104, 105, 105,
12684 		106, 106, 107, 107, 108, 108, 109, 109,
12685 		110, 110, 110, 111, 111, 112, 112, 113,
12686 		113, 114, 114, 114, 115, 115, 116, 116,
12687 		117, 117, 117, 118, 118, 119, 119, 120,
12688 		120, 120, 121, 121, 122, 122, 122, 123,
12689 		123, 124, 124, 124, 125, 125, 126, 126,
12690 		126, 127, 127, 128, 128, 128, 129, 129,
12691 		130, 130, 130, 131, 131, 131, 132, 132,
12692 		133, 133, 133, 134, 134, 134, 135, 135,
12693 		136, 136, 136, 137, 137, 137, 138, 138,
12694 		138, 139, 139, 140, 140, 140, 141, 141,
12695 		141, 142, 142, 142, 143, 143, 143, 144,
12696 		144, 144, 145, 145, 145, 146, 146, 146,
12697 		147, 147, 147, 148, 148, 148, 149, 149,
12698 		150, 150, 150, 150, 151, 151, 151, 152,
12699 		152, 152, 153, 153, 153, 154, 154, 154,
12700 		155, 155, 155, 156, 156, 156, 157, 157,
12701 		157, 158, 158, 158, 159, 159, 159, 160
12702 	};
12703 
12704 	if (x == 0)
12705 		return (0);
12706 	if (x >= 256) {
12707 		unsigned int tmp;
12708 
12709 		for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12710 			/* do nothing */ ;
12711 		return (tmp);
12712 	}
12713 	return (sqrt_table[x - 1] / 10);
12714 }
12715 
12716 static int
12717 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12718 {
12719 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
12720 	int _t;								\
12721 	_t = _x - 20;							\
12722 	if (_t >= 0) {							\
12723 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12724 	} else {							\
12725 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12726 	}								\
12727 } while (0)
12728 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
12729 	int _t;								\
12730 	_t = _x - 11;							\
12731 	if (_t >= 0)							\
12732 		_v = (_y << (31 - _x)) / (_z >> _t);			\
12733 	else								\
12734 		_v = (_y << (31 - _x)) / (_z << -_t);			\
12735 } while (0)
12736 	struct bwn_phy_lp_iq_est ie;
12737 	uint16_t v0, v1;
12738 	int tmp[2], ret;
12739 
12740 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12741 	v0 = v1 >> 8;
12742 	v1 |= 0xff;
12743 
12744 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12745 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12746 
12747 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12748 	if (ret == 0)
12749 		goto done;
12750 
12751 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12752 		ret = 0;
12753 		goto done;
12754 	}
12755 
12756 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12757 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12758 
12759 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12760 	v0 = tmp[0] >> 3;
12761 	v1 = tmp[1] >> 4;
12762 done:
12763 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12764 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12765 	return ret;
12766 #undef CALC_COEFF
12767 #undef CALC_COEFF2
12768 }
12769 
12770 static void
12771 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12772 {
12773 	static const uint16_t noisescale[] = {
12774 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12775 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12776 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12777 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12778 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12779 	};
12780 	static const uint16_t crsgainnft[] = {
12781 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12782 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12783 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12784 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12785 		0x013d,
12786 	};
12787 	static const uint16_t filterctl[] = {
12788 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12789 		0xff53, 0x0127,
12790 	};
12791 	static const uint32_t psctl[] = {
12792 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12793 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12794 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12795 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12796 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12797 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12798 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12799 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12800 	};
12801 	static const uint16_t ofdmcckgain_r0[] = {
12802 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12803 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12804 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12805 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12806 		0x755d,
12807 	};
12808 	static const uint16_t ofdmcckgain_r1[] = {
12809 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12810 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12811 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12812 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12813 		0x755d,
12814 	};
12815 	static const uint16_t gaindelta[] = {
12816 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12817 		0x0000,
12818 	};
12819 	static const uint32_t txpwrctl[] = {
12820 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12821 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12822 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12823 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12824 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12825 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12826 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12827 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12828 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12829 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12830 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12831 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12832 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000,
12846 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12847 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12848 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12849 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12850 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12851 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12852 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12853 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12854 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12855 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12856 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12857 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12858 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12859 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12860 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12861 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12862 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12863 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12864 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12865 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12866 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12867 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12868 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12869 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12870 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12871 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12872 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12873 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12874 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12875 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12876 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12877 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12878 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12879 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12880 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12881 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12882 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12883 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12884 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12885 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12886 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12887 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12888 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12889 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12890 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12891 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12892 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12893 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12894 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12895 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12896 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12897 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12898 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12899 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12900 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12901 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12902 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12903 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12904 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12905 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12906 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12907 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12908 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12909 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12910 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12911 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12912 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12913 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12914 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12915 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12916 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12917 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12918 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12919 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12920 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12921 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12922 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12923 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12924 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12925 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12926 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12927 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12928 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12929 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12930 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12931 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12932 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12933 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12934 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12935 		0x00000702,
12936 	};
12937 
12938 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12939 
12940 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12941 	    bwn_tab_sigsq_tbl);
12942 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12943 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12944 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12945 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12946 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12947 	    bwn_tab_pllfrac_tbl);
12948 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12949 	    bwn_tabl_iqlocal_tbl);
12950 	if (mac->mac_phy.rev == 0) {
12951 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12952 		    ofdmcckgain_r0);
12953 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12954 		    ofdmcckgain_r0);
12955 	} else {
12956 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12957 		    ofdmcckgain_r1);
12958 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12959 		    ofdmcckgain_r1);
12960 	}
12961 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12962 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12963 }
12964 
12965 static void
12966 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12967 {
12968 	struct bwn_softc *sc = mac->mac_sc;
12969 	int i;
12970 	static const uint16_t noisescale[] = {
12971 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12972 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12973 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12974 		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12975 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12976 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12977 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12978 	};
12979 	static const uint32_t filterctl[] = {
12980 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12981 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12982 	};
12983 	static const uint32_t psctl[] = {
12984 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12985 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12986 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12987 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12988 	};
12989 	static const uint32_t gainidx[] = {
12990 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12992 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12993 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12994 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12995 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12996 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12997 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12998 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12999 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13000 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13001 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13002 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13003 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13004 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13005 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13006 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13007 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13008 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13009 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13010 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13011 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13012 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13013 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13014 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13015 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13016 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13017 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13018 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13019 		0x0000001a, 0x64ca55ad, 0x0000001a
13020 	};
13021 	static const uint16_t auxgainidx[] = {
13022 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13023 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13024 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13025 		0x0004, 0x0016
13026 	};
13027 	static const uint16_t swctl[] = {
13028 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13029 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13030 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13031 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13032 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13033 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13034 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13035 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13036 	};
13037 	static const uint8_t hf[] = {
13038 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13039 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13040 	};
13041 	static const uint32_t gainval[] = {
13042 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13043 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13044 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13045 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13046 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13047 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13048 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13049 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13050 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13051 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13052 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13053 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13054 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13055 		0x000000f1, 0x00000000, 0x00000000
13056 	};
13057 	static const uint16_t gain[] = {
13058 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13059 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13060 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13061 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13062 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13063 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13064 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13065 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13066 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13067 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13068 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13069 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13070 	};
13071 	static const uint32_t papdeps[] = {
13072 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13073 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13074 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13075 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13076 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13077 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13078 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13079 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13080 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13081 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13082 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13083 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13084 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13085 	};
13086 	static const uint32_t papdmult[] = {
13087 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13088 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13089 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13090 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13091 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13092 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13093 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13094 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13095 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13096 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13097 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13098 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13099 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13100 	};
13101 	static const uint32_t gainidx_a0[] = {
13102 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13103 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13104 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13105 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13106 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13107 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13108 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13109 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13110 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13111 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13112 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13113 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13114 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13115 	};
13116 	static const uint16_t auxgainidx_a0[] = {
13117 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13118 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13119 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13120 		0x0002, 0x0014
13121 	};
13122 	static const uint32_t gainval_a0[] = {
13123 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13124 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13125 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13126 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13127 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13128 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13129 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13130 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13131 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13132 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13133 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13134 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13135 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13136 		0x000000f7, 0x00000000, 0x00000000
13137 	};
13138 	static const uint16_t gain_a0[] = {
13139 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13140 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13141 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13142 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13143 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13144 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13145 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13146 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13147 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13148 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13149 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13150 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13151 	};
13152 
13153 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13154 
13155 	for (i = 0; i < 704; i++)
13156 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13157 
13158 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13159 	    bwn_tab_sigsq_tbl);
13160 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13161 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13162 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13163 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13164 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13165 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13166 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13167 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13168 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13169 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13170 	    bwn_tab_pllfrac_tbl);
13171 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13172 	    bwn_tabl_iqlocal_tbl);
13173 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13174 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13175 
13176 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13177 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
13178 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13179 		    gainidx_a0);
13180 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13181 		    auxgainidx_a0);
13182 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13183 		    gainval_a0);
13184 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13185 	}
13186 }
13187 
13188 static void
13189 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13190 {
13191 	struct bwn_softc *sc = mac->mac_sc;
13192 	struct ifnet *ifp = sc->sc_ifp;
13193 	struct ieee80211com *ic = ifp->if_l2com;
13194 	static struct bwn_txgain_entry txgain_r2[] = {
13195 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13196 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13197 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13198 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13199 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13200 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13201 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13202 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13203 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13204 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13205 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13206 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13207 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13208 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13209 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13210 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13211 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13212 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13213 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13214 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13215 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13216 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13217 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13218 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13219 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13220 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13221 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13222 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13223 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13224 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13225 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13226 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13227 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13228 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13229 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13230 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13231 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13232 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13233 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13234 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13235 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13236 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13237 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13238 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13239 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13240 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13241 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13242 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13243 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13244 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13245 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13246 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13247 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13248 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13249 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13250 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13251 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13252 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13253 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13254 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13255 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13256 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13257 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13258 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13259 	};
13260 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13261 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13262 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13263 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13264 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13265 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13266 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13267 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13268 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13269 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13270 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13271 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13272 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13273 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13274 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13275 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13276 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13277 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13278 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13279 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13280 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13281 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13282 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13283 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13284 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13285 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13286 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13287 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13288 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13289 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13290 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13291 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13292 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13293 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13294 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13295 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13296 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13297 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13298 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13299 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13300 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13301 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13302 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13303 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13304 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13305 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13306 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13307 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13308 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13309 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13310 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13311 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13312 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13313 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13314 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13315 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13316 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13317 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13318 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13319 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13320 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13321 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13322 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13323 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13324 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13325 	};
13326 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13327 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13328 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13329 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13330 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13331 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13332 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13333 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13334 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13335 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13336 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13337 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13338 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13339 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13340 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13341 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13342 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13343 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13344 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13345 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13346 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13347 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13348 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13349 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13350 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13351 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13352 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13353 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13354 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13355 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13356 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13357 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13358 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13359 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13360 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13361 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13362 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13363 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13364 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13365 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13366 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13367 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13368 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13369 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13370 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13371 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13372 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13373 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13374 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13375 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13376 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13377 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13378 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13379 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13380 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13381 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13382 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13383 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13384 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13385 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13386 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13387 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13388 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13389 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13390 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13391 	};
13392 	static struct bwn_txgain_entry txgain_r0[] = {
13393 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13394 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13395 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13396 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13397 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13398 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13399 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13400 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13401 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13402 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13403 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13404 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13405 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13406 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13407 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13408 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13409 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13410 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13411 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13412 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13413 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13414 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13415 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13416 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13417 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13418 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13419 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13420 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13421 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13422 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13423 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13424 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13425 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13426 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13427 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13428 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13429 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13430 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13431 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13432 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13433 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13434 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13435 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13436 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13437 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13438 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13439 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13440 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13441 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13442 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13443 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13444 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13445 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13446 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13447 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13448 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13449 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13450 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13451 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13452 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13453 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13454 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13455 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13456 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13457 	};
13458 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13459 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13460 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13461 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13462 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13463 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13464 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13465 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13466 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13467 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13468 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13469 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13470 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13471 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13472 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13473 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13474 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13475 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13476 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13477 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13478 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13479 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13480 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13481 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13482 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13483 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13484 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13485 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13486 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13487 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13488 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13489 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13490 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13491 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13492 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13493 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13494 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13495 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13496 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13497 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13498 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13499 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13500 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13501 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13502 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13503 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13504 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13505 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13506 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13507 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13508 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13509 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13510 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13511 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13512 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13513 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13514 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13515 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13516 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13517 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13518 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13519 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13520 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13521 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13522 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13523 	};
13524 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13525 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13526 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13527 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13528 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13529 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13530 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13531 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13532 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13533 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13534 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13535 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13536 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13537 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13538 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13539 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13540 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13541 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13542 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13543 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13544 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13545 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13546 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13547 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13548 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13549 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13550 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13551 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13552 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13553 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13554 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13555 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13556 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13557 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13558 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13559 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13560 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13561 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13562 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13563 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13564 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13565 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13566 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13567 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13568 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13569 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13570 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13571 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13572 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13573 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13574 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13575 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13576 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13577 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13578 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13579 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13580 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13581 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13582 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13583 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13584 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13585 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13586 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13587 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13588 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13589 	};
13590 	static struct bwn_txgain_entry txgain_r1[] = {
13591 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13592 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13593 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13594 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13595 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13596 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13597 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13598 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13599 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13600 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13601 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13602 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13603 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13604 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13605 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13606 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13607 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13608 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13609 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13610 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13611 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13612 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13613 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13614 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13615 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13616 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13617 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13618 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13619 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13620 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13621 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13622 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13623 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13624 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13625 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13626 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13627 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13628 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13629 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13630 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13631 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13632 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13633 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13634 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13635 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13636 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13637 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13638 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13639 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13640 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13641 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13642 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13643 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13644 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13645 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13646 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13647 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13648 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13649 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13650 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13651 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13652 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13653 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13654 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13655 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13656 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13657 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13658 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13659 		{ 7, 11, 6, 0, 71 }
13660 	};
13661 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13662 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13663 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13664 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13665 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13666 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13667 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13668 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13669 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13670 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13671 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13672 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13673 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13674 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13675 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13676 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13677 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13678 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13679 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13680 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13681 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13682 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13683 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13684 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13685 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13686 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13687 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13688 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13689 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13690 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13691 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13692 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13693 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13694 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13695 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13696 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13697 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13698 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13699 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13700 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13701 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13702 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13703 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13704 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13705 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13706 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13707 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13708 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13709 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13710 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13711 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13712 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13713 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13714 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13715 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13716 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13717 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13718 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13719 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13720 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13721 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13722 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13723 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13724 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13725 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13726 	};
13727 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13728 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13729 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13730 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13731 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13732 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13733 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13734 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13735 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13736 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13737 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13738 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13739 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13740 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13741 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13742 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13743 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13744 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13745 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13746 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13747 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13748 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13749 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13750 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13751 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13752 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13753 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13754 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13755 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13756 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13757 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13758 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13759 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13760 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13761 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13762 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13763 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13764 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13765 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13766 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13767 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13768 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13769 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13770 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13771 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13772 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13773 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13774 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13775 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13776 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13777 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13778 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13779 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13780 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13781 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13782 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13783 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13784 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13785 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13786 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13787 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13788 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13789 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13790 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13791 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13792 	};
13793 
13794 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13795 		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13796 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13797 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13798 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13799 			    txgain_2ghz_r2);
13800 		else
13801 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13802 			    txgain_5ghz_r2);
13803 		return;
13804 	}
13805 
13806 	if (mac->mac_phy.rev == 0) {
13807 		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13808 		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13809 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13810 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13811 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13812 			    txgain_2ghz_r0);
13813 		else
13814 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13815 			    txgain_5ghz_r0);
13816 		return;
13817 	}
13818 
13819 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13820 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13821 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13822 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13823 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13824 	else
13825 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13826 }
13827 
13828 static void
13829 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13830 {
13831 	uint32_t offset, type;
13832 
13833 	type = BWN_TAB_GETTYPE(typeoffset);
13834 	offset = BWN_TAB_GETOFFSET(typeoffset);
13835 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13836 
13837 	switch (type) {
13838 	case BWN_TAB_8BIT:
13839 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13840 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13841 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13842 		break;
13843 	case BWN_TAB_16BIT:
13844 		KASSERT(!(value & ~0xffff),
13845 		    ("%s:%d: fail", __func__, __LINE__));
13846 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13847 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13848 		break;
13849 	case BWN_TAB_32BIT:
13850 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13851 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13852 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13853 		break;
13854 	default:
13855 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13856 	}
13857 }
13858 
13859 static int
13860 bwn_phy_lp_loopback(struct bwn_mac *mac)
13861 {
13862 	struct bwn_phy_lp_iq_est ie;
13863 	int i, index = -1;
13864 	uint32_t tmp;
13865 
13866 	memset(&ie, 0, sizeof(ie));
13867 
13868 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
13869 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13870 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13871 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13872 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13873 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13874 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13875 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13876 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13877 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13878 	for (i = 0; i < 32; i++) {
13879 		bwn_phy_lp_set_rxgain_idx(mac, i);
13880 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13881 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13882 			continue;
13883 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13884 		if ((tmp > 4000) && (tmp < 10000)) {
13885 			index = i;
13886 			break;
13887 		}
13888 	}
13889 	bwn_phy_lp_ddfs_turnoff(mac);
13890 	return (index);
13891 }
13892 
13893 static void
13894 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13895 {
13896 
13897 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13898 }
13899 
13900 static void
13901 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13902     int incr1, int incr2, int scale_idx)
13903 {
13904 
13905 	bwn_phy_lp_ddfs_turnoff(mac);
13906 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13907 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13908 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13909 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13910 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13911 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13912 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13913 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13914 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13915 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13916 }
13917 
13918 static uint8_t
13919 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13920     struct bwn_phy_lp_iq_est *ie)
13921 {
13922 	int i;
13923 
13924 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13925 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13926 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13927 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13928 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13929 
13930 	for (i = 0; i < 500; i++) {
13931 		if (!(BWN_PHY_READ(mac,
13932 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13933 			break;
13934 		DELAY(1000);
13935 	}
13936 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13937 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13938 		return 0;
13939 	}
13940 
13941 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13942 	ie->ie_iqprod <<= 16;
13943 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13944 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13945 	ie->ie_ipwr <<= 16;
13946 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13947 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13948 	ie->ie_qpwr <<= 16;
13949 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13950 
13951 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13952 	return 1;
13953 }
13954 
13955 static uint32_t
13956 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13957 {
13958 	uint32_t offset, type, value;
13959 
13960 	type = BWN_TAB_GETTYPE(typeoffset);
13961 	offset = BWN_TAB_GETOFFSET(typeoffset);
13962 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13963 
13964 	switch (type) {
13965 	case BWN_TAB_8BIT:
13966 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13967 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13968 		break;
13969 	case BWN_TAB_16BIT:
13970 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13971 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13972 		break;
13973 	case BWN_TAB_32BIT:
13974 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13975 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13976 		value <<= 16;
13977 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13978 		break;
13979 	default:
13980 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13981 		value = 0;
13982 	}
13983 
13984 	return (value);
13985 }
13986 
13987 static void
13988 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13989 {
13990 
13991 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13992 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13993 }
13994 
13995 static void
13996 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13997 {
13998 	uint16_t ctl;
13999 
14000 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14001 	ctl |= dac << 7;
14002 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14003 }
14004 
14005 static void
14006 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14007 {
14008 
14009 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14010 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14011 }
14012 
14013 static void
14014 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14015 {
14016 
14017 	if (mac->mac_phy.rev < 2)
14018 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14019 	else {
14020 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14021 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14022 	}
14023 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14024 }
14025 
14026 static uint16_t
14027 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14028 {
14029 
14030 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14031 }
14032 
14033 static uint8_t
14034 bwn_nbits(int32_t val)
14035 {
14036 	uint32_t tmp;
14037 	uint8_t nbits = 0;
14038 
14039 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
14040 		nbits++;
14041 	return (nbits);
14042 }
14043 
14044 static void
14045 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14046     struct bwn_txgain_entry *table)
14047 {
14048 	int i;
14049 
14050 	for (i = offset; i < count; i++)
14051 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14052 }
14053 
14054 static void
14055 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14056     struct bwn_txgain_entry data)
14057 {
14058 
14059 	if (mac->mac_phy.rev >= 2)
14060 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14061 	else
14062 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14063 }
14064 
14065 static void
14066 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14067     struct bwn_txgain_entry te)
14068 {
14069 	struct bwn_softc *sc = mac->mac_sc;
14070 	struct ifnet *ifp = sc->sc_ifp;
14071 	struct ieee80211com *ic = ifp->if_l2com;
14072 	uint32_t tmp;
14073 
14074 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14075 
14076 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14077 	if (mac->mac_phy.rev >= 3) {
14078 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14079 		    (0x10 << 24) : (0x70 << 24));
14080 	} else {
14081 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14082 		    (0x14 << 24) : (0x7f << 24));
14083 	}
14084 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14085 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14086 	    te.te_bbmult << 20 | te.te_dac << 28);
14087 }
14088 
14089 static void
14090 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14091     struct bwn_txgain_entry te)
14092 {
14093 
14094 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14095 
14096 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14097 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14098 	    te.te_dac);
14099 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14100 }
14101 
14102 static void
14103 bwn_sysctl_node(struct bwn_softc *sc)
14104 {
14105 	struct bwn_mac *mac;
14106 	struct bwn_stats *stats;
14107 	struct sysctl_ctx_list *ctx;
14108 	struct sysctl_oid *tree;
14109 
14110 	/* XXX assume that count of MAC is only 1. */
14111 
14112 	if ((mac = sc->sc_curmac) == NULL)
14113 		return;
14114 	stats = &mac->mac_stats;
14115 
14116 	ctx = &sc->sc_sysctl_ctx;
14117 	tree = sc->sc_sysctl_tree;
14118 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14119 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14120 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14121 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14122 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14123 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14124 
14125 #ifdef BWN_DEBUG
14126 	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14127 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14128 #endif
14129 }
14130 
14131 static device_method_t bwn_methods[] = {
14132 	/* Device interface */
14133 	DEVMETHOD(device_probe,		bwn_probe),
14134 	DEVMETHOD(device_attach,	bwn_attach),
14135 	DEVMETHOD(device_detach,	bwn_detach),
14136 	DEVMETHOD(device_suspend,	bwn_suspend),
14137 	DEVMETHOD(device_resume,	bwn_resume),
14138 	DEVMETHOD_END
14139 };
14140 static driver_t bwn_driver = {
14141 	"bwn",
14142 	bwn_methods,
14143 	sizeof(struct bwn_softc)
14144 };
14145 static devclass_t bwn_devclass;
14146 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14147 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14148 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
14149 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
14150 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
14151