xref: /freebsd/sys/dev/bwn/if_bwn.c (revision aa64588d28258aef88cc33b8043112e8856948d0)
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$");
32 
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/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_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60 
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
66 
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
72 
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
75 
76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
77 
78 /*
79  * Tunable & sysctl variables.
80  */
81 
82 #ifdef BWN_DEBUG
83 static	int bwn_debug = 0;
84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
85     "Broadcom debugging printfs");
86 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
87 enum {
88 	BWN_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
89 	BWN_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
90 	BWN_DEBUG_STATE		= 0x00000004,	/* 802.11 state transitions */
91 	BWN_DEBUG_TXPOW		= 0x00000008,	/* tx power processing */
92 	BWN_DEBUG_RESET		= 0x00000010,	/* reset processing */
93 	BWN_DEBUG_OPS		= 0x00000020,	/* bwn_ops processing */
94 	BWN_DEBUG_BEACON	= 0x00000040,	/* beacon handling */
95 	BWN_DEBUG_WATCHDOG	= 0x00000080,	/* watchdog timeout */
96 	BWN_DEBUG_INTR		= 0x00000100,	/* ISR */
97 	BWN_DEBUG_CALIBRATE	= 0x00000200,	/* periodic calibration */
98 	BWN_DEBUG_NODE		= 0x00000400,	/* node management */
99 	BWN_DEBUG_LED		= 0x00000800,	/* led management */
100 	BWN_DEBUG_CMD		= 0x00001000,	/* cmd submission */
101 	BWN_DEBUG_LO		= 0x00002000,	/* LO */
102 	BWN_DEBUG_FW		= 0x00004000,	/* firmware */
103 	BWN_DEBUG_WME		= 0x00008000,	/* WME */
104 	BWN_DEBUG_RF		= 0x00010000,	/* RF */
105 	BWN_DEBUG_FATAL		= 0x80000000,	/* fatal errors */
106 	BWN_DEBUG_ANY		= 0xffffffff
107 };
108 #define	DPRINTF(sc, m, fmt, ...) do {			\
109 	if (sc->sc_debug & (m))				\
110 		printf(fmt, __VA_ARGS__);		\
111 } while (0)
112 #else
113 #define	DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
114 #endif
115 
116 static int	bwn_bfp = 0;		/* use "Bad Frames Preemption" */
117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
118     "uses Bad Frames Preemption");
119 static int	bwn_bluetooth = 1;
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
121     "turns on Bluetooth Coexistence");
122 static int	bwn_hwpctl = 0;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
124     "uses H/W power control");
125 static int	bwn_msi_disable = 0;		/* MSI disabled  */
126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
127 static int	bwn_usedma = 1;
128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
129     "uses DMA");
130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
131 static int	bwn_wme = 1;
132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
133     "uses WME support");
134 
135 static int	bwn_attach_pre(struct bwn_softc *);
136 static int	bwn_attach_post(struct bwn_softc *);
137 static void	bwn_sprom_bugfixes(device_t);
138 static void	bwn_init(void *);
139 static int	bwn_init_locked(struct bwn_softc *);
140 static int	bwn_ioctl(struct ifnet *, u_long, caddr_t);
141 static void	bwn_start(struct ifnet *);
142 static int	bwn_attach_core(struct bwn_mac *);
143 static void	bwn_reset_core(struct bwn_mac *, uint32_t);
144 static int	bwn_phy_getinfo(struct bwn_mac *, int);
145 static int	bwn_chiptest(struct bwn_mac *);
146 static int	bwn_setup_channels(struct bwn_mac *, int, int);
147 static int	bwn_phy_g_attach(struct bwn_mac *);
148 static void	bwn_phy_g_detach(struct bwn_mac *);
149 static void	bwn_phy_g_init_pre(struct bwn_mac *);
150 static int	bwn_phy_g_prepare_hw(struct bwn_mac *);
151 static int	bwn_phy_g_init(struct bwn_mac *);
152 static void	bwn_phy_g_exit(struct bwn_mac *);
153 static uint16_t	bwn_phy_g_read(struct bwn_mac *, uint16_t);
154 static void	bwn_phy_g_write(struct bwn_mac *, uint16_t,
155 		    uint16_t);
156 static uint16_t	bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
157 static void	bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
158 		    uint16_t);
159 static int	bwn_phy_g_hwpctl(struct bwn_mac *);
160 static void	bwn_phy_g_rf_onoff(struct bwn_mac *, int);
161 static int	bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
162 static uint32_t	bwn_phy_g_get_default_chan(struct bwn_mac *);
163 static void	bwn_phy_g_set_antenna(struct bwn_mac *, int);
164 static int	bwn_phy_g_im(struct bwn_mac *, int);
165 static int	bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
166 static void	bwn_phy_g_set_txpwr(struct bwn_mac *);
167 static void	bwn_phy_g_task_15s(struct bwn_mac *);
168 static void	bwn_phy_g_task_60s(struct bwn_mac *);
169 static uint16_t	bwn_phy_g_txctl(struct bwn_mac *);
170 static void	bwn_phy_switch_analog(struct bwn_mac *, int);
171 static uint16_t	bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
172 static void	bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
173 		    uint16_t);
174 static uint32_t	bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
175 static void	bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
176 		    uint32_t);
177 static void	bwn_shm_ctlword(struct bwn_mac *, uint16_t,
178 		    uint16_t);
179 static void	bwn_addchannels(struct ieee80211_channel [], int, int *,
180 		    const struct bwn_channelinfo *, int);
181 static int	bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
182 		    const struct ieee80211_bpf_params *);
183 static void	bwn_updateslot(struct ifnet *);
184 static void	bwn_update_promisc(struct ifnet *);
185 static void	bwn_wme_init(struct bwn_mac *);
186 static int	bwn_wme_update(struct ieee80211com *);
187 static void	bwn_wme_clear(struct bwn_softc *);
188 static void	bwn_wme_load(struct bwn_mac *);
189 static void	bwn_wme_loadparams(struct bwn_mac *,
190 		    const struct wmeParams *, uint16_t);
191 static void	bwn_scan_start(struct ieee80211com *);
192 static void	bwn_scan_end(struct ieee80211com *);
193 static void	bwn_set_channel(struct ieee80211com *);
194 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
195 		    const char [IFNAMSIZ], int, int,
196 		    int, const uint8_t [IEEE80211_ADDR_LEN],
197 		    const uint8_t [IEEE80211_ADDR_LEN]);
198 static void	bwn_vap_delete(struct ieee80211vap *);
199 static void	bwn_stop(struct bwn_softc *, int);
200 static void	bwn_stop_locked(struct bwn_softc *, int);
201 static int	bwn_core_init(struct bwn_mac *);
202 static void	bwn_core_start(struct bwn_mac *);
203 static void	bwn_core_exit(struct bwn_mac *);
204 static void	bwn_bt_disable(struct bwn_mac *);
205 static int	bwn_chip_init(struct bwn_mac *);
206 static uint64_t	bwn_hf_read(struct bwn_mac *);
207 static void	bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void	bwn_set_txretry(struct bwn_mac *, int, int);
209 static void	bwn_rate_init(struct bwn_mac *);
210 static void	bwn_set_phytxctl(struct bwn_mac *);
211 static void	bwn_spu_setdelay(struct bwn_mac *, int);
212 static void	bwn_bt_enable(struct bwn_mac *);
213 static void	bwn_set_macaddr(struct bwn_mac *);
214 static void	bwn_crypt_init(struct bwn_mac *);
215 static void	bwn_chip_exit(struct bwn_mac *);
216 static int	bwn_fw_fillinfo(struct bwn_mac *);
217 static int	bwn_fw_loaducode(struct bwn_mac *);
218 static int	bwn_gpio_init(struct bwn_mac *);
219 static int	bwn_fw_loadinitvals(struct bwn_mac *);
220 static int	bwn_phy_init(struct bwn_mac *);
221 static void	bwn_set_txantenna(struct bwn_mac *, int);
222 static void	bwn_set_opmode(struct bwn_mac *);
223 static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t	bwn_plcp_getcck(const uint8_t);
225 static uint8_t	bwn_plcp_getofdm(const uint8_t);
226 static void	bwn_pio_init(struct bwn_mac *);
227 static uint16_t	bwn_pio_idx2base(struct bwn_mac *, int);
228 static void	bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
229 		    int);
230 static void	bwn_pio_setupqueue_rx(struct bwn_mac *,
231 		    struct bwn_pio_rxqueue *, int);
232 static void	bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t	bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
234 		    uint16_t);
235 static void	bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int	bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t	bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void	bwn_pio_handle_txeof(struct bwn_mac *,
239 		    const struct bwn_txstatus *);
240 static uint16_t	bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t	bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void	bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
243 		    uint16_t);
244 static void	bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
245 		    uint32_t);
246 static int	bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
247 		    struct mbuf *);
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t	bwn_pio_write_multi_4(struct bwn_mac *,
250 		    struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void	bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
252 		    uint16_t, uint32_t);
253 static uint16_t	bwn_pio_write_multi_2(struct bwn_mac *,
254 		    struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t	bwn_pio_write_mbuf_2(struct bwn_mac *,
256 		    struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258 		    uint16_t, struct bwn_pio_txpkt **);
259 static void	bwn_dma_init(struct bwn_mac *);
260 static void	bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int	bwn_dma_mask2type(uint64_t);
262 static uint64_t	bwn_dma_mask(struct bwn_mac *);
263 static uint16_t	bwn_dma_base(int, int);
264 static void	bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void	bwn_dma_32_getdesc(struct bwn_dma_ring *,
266 		    int, struct bwn_dmadesc_generic **,
267 		    struct bwn_dmadesc_meta **);
268 static void	bwn_dma_32_setdesc(struct bwn_dma_ring *,
269 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
270 		    int, int);
271 static void	bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void	bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void	bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int	bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void	bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void	bwn_dma_64_getdesc(struct bwn_dma_ring *,
277 		    int, struct bwn_dmadesc_generic **,
278 		    struct bwn_dmadesc_meta **);
279 static void	bwn_dma_64_setdesc(struct bwn_dma_ring *,
280 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
281 		    int, int);
282 static void	bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void	bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void	bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int	bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void	bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int	bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void	bwn_dma_setup(struct bwn_dma_ring *);
289 static void	bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void	bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void	bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int	bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void	bwn_dma_rx(struct bwn_dma_ring *);
294 static int	bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void	bwn_dma_free_descbuf(struct bwn_dma_ring *,
296 		    struct bwn_dmadesc_meta *);
297 static void	bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int	bwn_dma_gettype(struct bwn_mac *);
299 static void	bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int	bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int	bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void	bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int	bwn_dma_newbuf(struct bwn_dma_ring *,
304 		    struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
305 		    int);
306 static void	bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
307 		    bus_size_t, int);
308 static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void	bwn_dma_handle_txeof(struct bwn_mac *,
310 		    const struct bwn_txstatus *);
311 static int	bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
312 		    struct mbuf *);
313 static int	bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
315 		    uint8_t);
316 static int	bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
318 		    int, int, int);
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320 		    const struct bwn_txstatus *, uint16_t, int *);
321 static void	bwn_dma_free(struct bwn_mac *);
322 static void	bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t	bwn_has_hwpctl(struct bwn_mac *);
324 static void	bwn_phy_init_b5(struct bwn_mac *);
325 static void	bwn_phy_init_b6(struct bwn_mac *);
326 static void	bwn_phy_init_a(struct bwn_mac *);
327 static void	bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t	bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void	bwn_lo_g_init(struct bwn_mac *);
330 static void	bwn_lo_g_adjust(struct bwn_mac *);
331 static void	bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333 		    const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void	bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void	bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void	bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void	bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338 		    const struct bwn_bbatt *, const struct bwn_rfatt *,
339 		    uint8_t);
340 static void	bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t	bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void	bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void	bwn_wa_init(struct bwn_mac *);
344 static void	bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
345 		    uint16_t);
346 static void	bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void	bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
348 		    uint32_t);
349 static void	bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
350 		    uint16_t);
351 static void	bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void	bwn_mac_suspend(struct bwn_mac *);
353 static void	bwn_mac_enable(struct bwn_mac *);
354 static void	bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t	bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void	bwn_nrssi_offset(struct bwn_mac *);
357 static void	bwn_nrssi_threshold(struct bwn_mac *);
358 static void	bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void	bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360 		    int16_t);
361 static void	bwn_set_original_gains(struct bwn_mac *);
362 static void	bwn_hwpctl_early_init(struct bwn_mac *);
363 static void	bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t	bwn_phy_g_chan2freq(uint8_t);
365 static int	bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int	bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367 		    const char *, struct bwn_fwfile *);
368 static void	bwn_release_firmware(struct bwn_mac *);
369 static void	bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t	bwn_fwcaps_read(struct bwn_mac *);
371 static int	bwn_fwinitvals_write(struct bwn_mac *,
372 		    const struct bwn_fwinitvals *, size_t, size_t);
373 static int	bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t	bwn_ant2phy(int);
375 static void	bwn_mac_write_bssid(struct bwn_mac *);
376 static void	bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377 		    const uint8_t *);
378 static void	bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379 		    const uint8_t *, size_t, const uint8_t *);
380 static void	bwn_key_macwrite(struct bwn_mac *, uint8_t,
381 		    const uint8_t *);
382 static void	bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
383 		    const uint8_t *);
384 static void	bwn_phy_exit(struct bwn_mac *);
385 static void	bwn_core_stop(struct bwn_mac *);
386 static int	bwn_switch_band(struct bwn_softc *,
387 		    struct ieee80211_channel *);
388 static void	bwn_phy_reset(struct bwn_mac *);
389 static int	bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void	bwn_set_pretbtt(struct bwn_mac *);
391 static int	bwn_intr(void *);
392 static void	bwn_intrtask(void *, int);
393 static void	bwn_restart(struct bwn_mac *, const char *);
394 static void	bwn_intr_ucode_debug(struct bwn_mac *);
395 static void	bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void	bwn_intr_atim_end(struct bwn_mac *);
397 static void	bwn_intr_beacon(struct bwn_mac *);
398 static void	bwn_intr_pmq(struct bwn_mac *);
399 static void	bwn_intr_noise(struct bwn_mac *);
400 static void	bwn_intr_txeof(struct bwn_mac *);
401 static void	bwn_hwreset(void *, int);
402 static void	bwn_handle_fwpanic(struct bwn_mac *);
403 static void	bwn_load_beacon0(struct bwn_mac *);
404 static void	bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t	bwn_jssi_read(struct bwn_mac *);
406 static void	bwn_noise_gensample(struct bwn_mac *);
407 static void	bwn_handle_txeof(struct bwn_mac *,
408 		    const struct bwn_txstatus *);
409 static void	bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void	bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static void	bwn_start_locked(struct ifnet *);
412 static int	bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
413 		    struct mbuf *);
414 static int	bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
415 static int	bwn_set_txhdr(struct bwn_mac *,
416 		    struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
417 		    uint16_t);
418 static void	bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
419 		    const uint8_t);
420 static uint8_t	bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
421 static uint8_t	bwn_get_fbrate(uint8_t);
422 static int	bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
423 static void	bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
424 static void	bwn_phy_lock(struct bwn_mac *);
425 static void	bwn_phy_unlock(struct bwn_mac *);
426 static void	bwn_rf_lock(struct bwn_mac *);
427 static void	bwn_rf_unlock(struct bwn_mac *);
428 static void	bwn_txpwr(void *, int);
429 static void	bwn_tasks(void *);
430 static void	bwn_task_15s(struct bwn_mac *);
431 static void	bwn_task_30s(struct bwn_mac *);
432 static void	bwn_task_60s(struct bwn_mac *);
433 static int	bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
434 		    uint8_t);
435 static int	bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
436 static void	bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
437 		    const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
438 		    int, int);
439 static void	bwn_tsf_read(struct bwn_mac *, uint64_t *);
440 static void	bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
441 static void	bwn_set_slot_time(struct bwn_mac *, uint16_t);
442 static void	bwn_watchdog(void *);
443 static void	bwn_dma_stop(struct bwn_mac *);
444 static void	bwn_pio_stop(struct bwn_mac *);
445 static void	bwn_dma_ringstop(struct bwn_dma_ring **);
446 static void	bwn_led_attach(struct bwn_mac *);
447 static void	bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
448 static void	bwn_led_event(struct bwn_mac *, int);
449 static void	bwn_led_blink_start(struct bwn_mac *, int, int);
450 static void	bwn_led_blink_next(void *);
451 static void	bwn_led_blink_end(void *);
452 static void	bwn_rfswitch(void *);
453 static void	bwn_rf_turnon(struct bwn_mac *);
454 static void	bwn_rf_turnoff(struct bwn_mac *);
455 static void	bwn_phy_lp_init_pre(struct bwn_mac *);
456 static int	bwn_phy_lp_init(struct bwn_mac *);
457 static uint16_t	bwn_phy_lp_read(struct bwn_mac *, uint16_t);
458 static void	bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
459 static void	bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
460 		    uint16_t);
461 static uint16_t	bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
462 static void	bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void	bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
464 static int	bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
465 static uint32_t	bwn_phy_lp_get_default_chan(struct bwn_mac *);
466 static void	bwn_phy_lp_set_antenna(struct bwn_mac *, int);
467 static void	bwn_phy_lp_task_60s(struct bwn_mac *);
468 static void	bwn_phy_lp_readsprom(struct bwn_mac *);
469 static void	bwn_phy_lp_bbinit(struct bwn_mac *);
470 static void	bwn_phy_lp_txpctl_init(struct bwn_mac *);
471 static void	bwn_phy_lp_calib(struct bwn_mac *);
472 static void	bwn_phy_lp_switch_analog(struct bwn_mac *, int);
473 static int	bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
474 static int	bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
475 static void	bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
476 static void	bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
477 static void	bwn_phy_lp_digflt_save(struct bwn_mac *);
478 static void	bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
479 static void	bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
480 static void	bwn_phy_lp_bugfix(struct bwn_mac *);
481 static void	bwn_phy_lp_digflt_restore(struct bwn_mac *);
482 static void	bwn_phy_lp_tblinit(struct bwn_mac *);
483 static void	bwn_phy_lp_bbinit_r2(struct bwn_mac *);
484 static void	bwn_phy_lp_bbinit_r01(struct bwn_mac *);
485 static void	bwn_phy_lp_b2062_init(struct bwn_mac *);
486 static void	bwn_phy_lp_b2063_init(struct bwn_mac *);
487 static void	bwn_phy_lp_rxcal_r2(struct bwn_mac *);
488 static void	bwn_phy_lp_rccal_r12(struct bwn_mac *);
489 static void	bwn_phy_lp_set_rccap(struct bwn_mac *);
490 static uint32_t	bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
491 static void	bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
492 static void	bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
493 static void	bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
494 		    const void *);
495 static void	bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
496 static struct bwn_txgain
497 		bwn_phy_lp_get_txgain(struct bwn_mac *);
498 static uint8_t	bwn_phy_lp_get_bbmult(struct bwn_mac *);
499 static void	bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
500 static void	bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
501 static void	bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
502 static void	bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
503 static void	bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
504 static int	bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
505 static void	bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
506 static void	bwn_phy_lp_tblinit_r01(struct bwn_mac *);
507 static void	bwn_phy_lp_tblinit_r2(struct bwn_mac *);
508 static void	bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
509 static void	bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
510 static void	bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
511 static void	bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
512 static int	bwn_phy_lp_loopback(struct bwn_mac *);
513 static void	bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
514 static void	bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
515 		    int);
516 static uint8_t	bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
517 		    struct bwn_phy_lp_iq_est *);
518 static void	bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
519 static uint32_t	bwn_tab_read(struct bwn_mac *, uint32_t);
520 static void	bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
521 static void	bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
522 static void	bwn_phy_lp_set_txgain_override(struct bwn_mac *);
523 static uint16_t	bwn_phy_lp_get_pa_gain(struct bwn_mac *);
524 static uint8_t	bwn_nbits(int32_t);
525 static void	bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
526 		    struct bwn_txgain_entry *);
527 static void	bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
528 		    struct bwn_txgain_entry);
529 static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
530 		    struct bwn_txgain_entry);
531 static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
532 		    struct bwn_txgain_entry);
533 static void	bwn_sysctl_node(struct bwn_softc *);
534 
535 static struct resource_spec bwn_res_spec_legacy[] = {
536 	{ SYS_RES_IRQ,		0,		RF_ACTIVE | RF_SHAREABLE },
537 	{ -1,			0,		0 }
538 };
539 
540 static struct resource_spec bwn_res_spec_msi[] = {
541 	{ SYS_RES_IRQ,		1,		RF_ACTIVE },
542 	{ -1,			0,		0 }
543 };
544 
545 static const struct bwn_channelinfo bwn_chantable_bg = {
546 	.channels = {
547 		{ 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
548 		{ 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
549 		{ 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
550 		{ 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
551 		{ 2472, 13, 30 }, { 2484, 14, 30 } },
552 	.nchannels = 14
553 };
554 
555 static const struct bwn_channelinfo bwn_chantable_a = {
556 	.channels = {
557 		{ 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
558 		{ 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
559 		{ 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
560 		{ 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
561 		{ 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
562 		{ 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
563 		{ 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
564 		{ 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
565 		{ 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
566 		{ 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
567 		{ 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
568 		{ 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
569 		{ 6080, 216, 30 } },
570 	.nchannels = 37
571 };
572 
573 static const struct bwn_channelinfo bwn_chantable_n = {
574 	.channels = {
575 		{ 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
576 		{ 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
577 		{ 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
578 		{ 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
579 		{ 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
580 		{ 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
581 		{ 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
582 		{ 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
583 		{ 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
584 		{ 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
585 		{ 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
586 		{ 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
587 		{ 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
588 		{ 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
589 		{ 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
590 		{ 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
591 		{ 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
592 		{ 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
593 		{ 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
594 		{ 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
595 		{ 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
596 		{ 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
597 		{ 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
598 		{ 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
599 		{ 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
600 		{ 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
601 		{ 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
602 		{ 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
603 		{ 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
604 		{ 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
605 		{ 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
606 		{ 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
607 		{ 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
608 		{ 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
609 		{ 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
610 		{ 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
611 		{ 6130, 226, 30 }, { 6140, 228, 30 } },
612 	.nchannels = 110
613 };
614 
615 static const uint8_t bwn_b2063_chantable_data[33][12] = {
616 	{ 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617 	{ 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618 	{ 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619 	{ 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620 	{ 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621 	{ 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
622 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
623 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
624 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
625 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
626 	{ 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
627 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
628 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
629 	{ 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
630 	{ 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631 	{ 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
633 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
634 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
635 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638 	{ 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639 	{ 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
641 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642 	{ 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646 	{ 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647 	{ 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648 	{ 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
649 };
650 
651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
652 	{ 1, 2412, bwn_b2063_chantable_data[0] },
653 	{ 2, 2417, bwn_b2063_chantable_data[0] },
654 	{ 3, 2422, bwn_b2063_chantable_data[0] },
655 	{ 4, 2427, bwn_b2063_chantable_data[1] },
656 	{ 5, 2432, bwn_b2063_chantable_data[1] },
657 	{ 6, 2437, bwn_b2063_chantable_data[1] },
658 	{ 7, 2442, bwn_b2063_chantable_data[1] },
659 	{ 8, 2447, bwn_b2063_chantable_data[1] },
660 	{ 9, 2452, bwn_b2063_chantable_data[2] },
661 	{ 10, 2457, bwn_b2063_chantable_data[2] },
662 	{ 11, 2462, bwn_b2063_chantable_data[3] },
663 	{ 12, 2467, bwn_b2063_chantable_data[3] },
664 	{ 13, 2472, bwn_b2063_chantable_data[3] },
665 	{ 14, 2484, bwn_b2063_chantable_data[4] },
666 	{ 34, 5170, bwn_b2063_chantable_data[5] },
667 	{ 36, 5180, bwn_b2063_chantable_data[6] },
668 	{ 38, 5190, bwn_b2063_chantable_data[7] },
669 	{ 40, 5200, bwn_b2063_chantable_data[8] },
670 	{ 42, 5210, bwn_b2063_chantable_data[9] },
671 	{ 44, 5220, bwn_b2063_chantable_data[10] },
672 	{ 46, 5230, bwn_b2063_chantable_data[11] },
673 	{ 48, 5240, bwn_b2063_chantable_data[12] },
674 	{ 52, 5260, bwn_b2063_chantable_data[13] },
675 	{ 56, 5280, bwn_b2063_chantable_data[14] },
676 	{ 60, 5300, bwn_b2063_chantable_data[14] },
677 	{ 64, 5320, bwn_b2063_chantable_data[15] },
678 	{ 100, 5500, bwn_b2063_chantable_data[16] },
679 	{ 104, 5520, bwn_b2063_chantable_data[17] },
680 	{ 108, 5540, bwn_b2063_chantable_data[18] },
681 	{ 112, 5560, bwn_b2063_chantable_data[19] },
682 	{ 116, 5580, bwn_b2063_chantable_data[20] },
683 	{ 120, 5600, bwn_b2063_chantable_data[21] },
684 	{ 124, 5620, bwn_b2063_chantable_data[21] },
685 	{ 128, 5640, bwn_b2063_chantable_data[22] },
686 	{ 132, 5660, bwn_b2063_chantable_data[22] },
687 	{ 136, 5680, bwn_b2063_chantable_data[22] },
688 	{ 140, 5700, bwn_b2063_chantable_data[23] },
689 	{ 149, 5745, bwn_b2063_chantable_data[23] },
690 	{ 153, 5765, bwn_b2063_chantable_data[23] },
691 	{ 157, 5785, bwn_b2063_chantable_data[23] },
692 	{ 161, 5805, bwn_b2063_chantable_data[23] },
693 	{ 165, 5825, bwn_b2063_chantable_data[23] },
694 	{ 184, 4920, bwn_b2063_chantable_data[24] },
695 	{ 188, 4940, bwn_b2063_chantable_data[25] },
696 	{ 192, 4960, bwn_b2063_chantable_data[26] },
697 	{ 196, 4980, bwn_b2063_chantable_data[27] },
698 	{ 200, 5000, bwn_b2063_chantable_data[28] },
699 	{ 204, 5020, bwn_b2063_chantable_data[29] },
700 	{ 208, 5040, bwn_b2063_chantable_data[30] },
701 	{ 212, 5060, bwn_b2063_chantable_data[31] },
702 	{ 216, 5080, bwn_b2063_chantable_data[32] }
703 };
704 
705 static const uint8_t bwn_b2062_chantable_data[22][12] = {
706 	{ 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
707 	{ 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708 	{ 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 	{ 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710 	{ 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711 	{ 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712 	{ 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713 	{ 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 	{ 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715 	{ 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716 	{ 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717 	{ 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718 	{ 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719 	{ 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720 	{ 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721 	{ 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722 	{ 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723 	{ 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724 	{ 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725 	{ 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726 	{ 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
727 	{ 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
728 };
729 
730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
731 	{ 1, 2412, bwn_b2062_chantable_data[0] },
732 	{ 2, 2417, bwn_b2062_chantable_data[0] },
733 	{ 3, 2422, bwn_b2062_chantable_data[0] },
734 	{ 4, 2427, bwn_b2062_chantable_data[0] },
735 	{ 5, 2432, bwn_b2062_chantable_data[0] },
736 	{ 6, 2437, bwn_b2062_chantable_data[0] },
737 	{ 7, 2442, bwn_b2062_chantable_data[0] },
738 	{ 8, 2447, bwn_b2062_chantable_data[0] },
739 	{ 9, 2452, bwn_b2062_chantable_data[0] },
740 	{ 10, 2457, bwn_b2062_chantable_data[0] },
741 	{ 11, 2462, bwn_b2062_chantable_data[0] },
742 	{ 12, 2467, bwn_b2062_chantable_data[0] },
743 	{ 13, 2472, bwn_b2062_chantable_data[0] },
744 	{ 14, 2484, bwn_b2062_chantable_data[0] },
745 	{ 34, 5170, bwn_b2062_chantable_data[1] },
746 	{ 38, 5190, bwn_b2062_chantable_data[2] },
747 	{ 42, 5210, bwn_b2062_chantable_data[2] },
748 	{ 46, 5230, bwn_b2062_chantable_data[3] },
749 	{ 36, 5180, bwn_b2062_chantable_data[4] },
750 	{ 40, 5200, bwn_b2062_chantable_data[5] },
751 	{ 44, 5220, bwn_b2062_chantable_data[6] },
752 	{ 48, 5240, bwn_b2062_chantable_data[3] },
753 	{ 52, 5260, bwn_b2062_chantable_data[3] },
754 	{ 56, 5280, bwn_b2062_chantable_data[3] },
755 	{ 60, 5300, bwn_b2062_chantable_data[7] },
756 	{ 64, 5320, bwn_b2062_chantable_data[8] },
757 	{ 100, 5500, bwn_b2062_chantable_data[9] },
758 	{ 104, 5520, bwn_b2062_chantable_data[10] },
759 	{ 108, 5540, bwn_b2062_chantable_data[10] },
760 	{ 112, 5560, bwn_b2062_chantable_data[10] },
761 	{ 116, 5580, bwn_b2062_chantable_data[11] },
762 	{ 120, 5600, bwn_b2062_chantable_data[12] },
763 	{ 124, 5620, bwn_b2062_chantable_data[12] },
764 	{ 128, 5640, bwn_b2062_chantable_data[12] },
765 	{ 132, 5660, bwn_b2062_chantable_data[12] },
766 	{ 136, 5680, bwn_b2062_chantable_data[12] },
767 	{ 140, 5700, bwn_b2062_chantable_data[12] },
768 	{ 149, 5745, bwn_b2062_chantable_data[12] },
769 	{ 153, 5765, bwn_b2062_chantable_data[12] },
770 	{ 157, 5785, bwn_b2062_chantable_data[12] },
771 	{ 161, 5805, bwn_b2062_chantable_data[12] },
772 	{ 165, 5825, bwn_b2062_chantable_data[12] },
773 	{ 184, 4920, bwn_b2062_chantable_data[13] },
774 	{ 188, 4940, bwn_b2062_chantable_data[14] },
775 	{ 192, 4960, bwn_b2062_chantable_data[15] },
776 	{ 196, 4980, bwn_b2062_chantable_data[16] },
777 	{ 200, 5000, bwn_b2062_chantable_data[17] },
778 	{ 204, 5020, bwn_b2062_chantable_data[18] },
779 	{ 208, 5040, bwn_b2062_chantable_data[19] },
780 	{ 212, 5060, bwn_b2062_chantable_data[20] },
781 	{ 216, 5080, bwn_b2062_chantable_data[21] }
782 };
783 
784 /* for LP PHY */
785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
786 	{  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
787 	{  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
788 	{  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
789 	{ 13, -66, 13 }, { 14, -66, 13 },
790 };
791 
792 /* for LP PHY */
793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
794 	{   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
795 	{   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
796 	{   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
797 	{  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
798 	{  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
799 	{  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
800 	{  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
801 	{ 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
802 	{ 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
803 	{ 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
804 	{ 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
805 	{ 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
806 	{ 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
807 };
808 
809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
810 
811 static const uint8_t bwn_tab_sigsq_tbl[] = {
812 	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
813 	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
814 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
815 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
816 	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
817 	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
818 };
819 
820 static const uint8_t bwn_tab_pllfrac_tbl[] = {
821 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
822 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
823 };
824 
825 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
826 	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
827 	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
828 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
830 	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
831 	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
832 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
836 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838 };
839 
840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
846 
847 #define	VENDOR_LED_ACT(vendor)				\
848 {							\
849 	.vid = PCI_VENDOR_##vendor,			\
850 	.led_act = { BWN_VENDOR_LED_ACT_##vendor }	\
851 }
852 
853 static const struct {
854 	uint16_t	vid;
855 	uint8_t		led_act[BWN_LED_MAX];
856 } bwn_vendor_led_act[] = {
857 	VENDOR_LED_ACT(COMPAQ),
858 	VENDOR_LED_ACT(ASUSTEK)
859 };
860 
861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
862 	{ BWN_VENDOR_LED_ACT_DEFAULT };
863 
864 #undef VENDOR_LED_ACT
865 
866 static const struct {
867 	int		on_dur;
868 	int		off_dur;
869 } bwn_led_duration[109] = {
870 	[0]	= { 400, 100 },
871 	[2]	= { 150, 75 },
872 	[4]	= { 90, 45 },
873 	[11]	= { 66, 34 },
874 	[12]	= { 53, 26 },
875 	[18]	= { 42, 21 },
876 	[22]	= { 35, 17 },
877 	[24]	= { 32, 16 },
878 	[36]	= { 21, 10 },
879 	[48]	= { 16, 8 },
880 	[72]	= { 11, 5 },
881 	[96]	= { 9, 4 },
882 	[108]	= { 7, 3 }
883 };
884 
885 static const uint16_t bwn_wme_shm_offsets[] = {
886 	[0] = BWN_WME_BESTEFFORT,
887 	[1] = BWN_WME_BACKGROUND,
888 	[2] = BWN_WME_VOICE,
889 	[3] = BWN_WME_VIDEO,
890 };
891 
892 static const struct siba_devid bwn_devs[] = {
893 	SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
894 	SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
895 	SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
896 	SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
897 	SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
898 	SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
899 	SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
900 	SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
901 	SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
902 };
903 
904 static int
905 bwn_probe(device_t dev)
906 {
907 	int i;
908 
909 	for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
910 		if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
911 		    siba_get_device(dev) == bwn_devs[i].sd_device &&
912 		    siba_get_revid(dev) == bwn_devs[i].sd_rev)
913 			return (BUS_PROBE_DEFAULT);
914 	}
915 
916 	return (ENXIO);
917 }
918 
919 static int
920 bwn_attach(device_t dev)
921 {
922 	struct bwn_mac *mac;
923 	struct bwn_softc *sc = device_get_softc(dev);
924 	int error, i, msic, reg;
925 
926 	sc->sc_dev = dev;
927 #ifdef BWN_DEBUG
928 	sc->sc_debug = bwn_debug;
929 #endif
930 
931 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
932 		error = bwn_attach_pre(sc);
933 		if (error != 0)
934 			return (error);
935 		bwn_sprom_bugfixes(dev);
936 		sc->sc_flags |= BWN_FLAG_ATTACHED;
937 	}
938 
939 	if (!TAILQ_EMPTY(&sc->sc_maclist)) {
940 		if (siba_get_pci_device(dev) != 0x4313 &&
941 		    siba_get_pci_device(dev) != 0x431a &&
942 		    siba_get_pci_device(dev) != 0x4321) {
943 			device_printf(sc->sc_dev,
944 			    "skip 802.11 cores\n");
945 			return (ENODEV);
946 		}
947 	}
948 
949 	mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
950 	    M_NOWAIT | M_ZERO);
951 	if (mac == NULL)
952 		return (ENOMEM);
953 	mac->mac_sc = sc;
954 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
955 	if (bwn_bfp != 0)
956 		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
957 
958 	TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
959 	TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
960 	TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
961 
962 	error = bwn_attach_core(mac);
963 	if (error)
964 		goto fail0;
965 	bwn_led_attach(mac);
966 
967 	device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
968 	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
969 	    siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
970 	    mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
971 	    mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
972 	    mac->mac_phy.rf_rev);
973 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
974 		device_printf(sc->sc_dev, "DMA (%d bits)\n",
975 		    mac->mac_method.dma.dmatype);
976 	else
977 		device_printf(sc->sc_dev, "PIO\n");
978 
979 	/*
980 	 * setup PCI resources and interrupt.
981 	 */
982 	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
983 		msic = pci_msi_count(dev);
984 		if (bootverbose)
985 			device_printf(sc->sc_dev, "MSI count : %d\n", msic);
986 	} else
987 		msic = 0;
988 
989 	mac->mac_intr_spec = bwn_res_spec_legacy;
990 	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
991 		if (pci_alloc_msi(dev, &msic) == 0) {
992 			device_printf(sc->sc_dev,
993 			    "Using %d MSI messages\n", msic);
994 			mac->mac_intr_spec = bwn_res_spec_msi;
995 			mac->mac_msi = 1;
996 		}
997 	}
998 
999 	error = bus_alloc_resources(dev, mac->mac_intr_spec,
1000 	    mac->mac_res_irq);
1001 	if (error) {
1002 		device_printf(sc->sc_dev,
1003 		    "couldn't allocate IRQ resources (%d)\n", error);
1004 		goto fail1;
1005 	}
1006 
1007 	if (mac->mac_msi == 0)
1008 		error = bus_setup_intr(dev, mac->mac_res_irq[0],
1009 		    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1010 		    &mac->mac_intrhand[0]);
1011 	else {
1012 		for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1013 			error = bus_setup_intr(dev, mac->mac_res_irq[i],
1014 			    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1015 			    &mac->mac_intrhand[i]);
1016 			if (error != 0) {
1017 				device_printf(sc->sc_dev,
1018 				    "couldn't setup interrupt (%d)\n", error);
1019 				break;
1020 			}
1021 		}
1022 	}
1023 
1024 	TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1025 
1026 	/*
1027 	 * calls attach-post routine
1028 	 */
1029 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1030 		bwn_attach_post(sc);
1031 
1032 	return (0);
1033 fail1:
1034 	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1035 		pci_release_msi(dev);
1036 fail0:
1037 	free(mac, M_DEVBUF);
1038 	return (error);
1039 }
1040 
1041 static int
1042 bwn_is_valid_ether_addr(uint8_t *addr)
1043 {
1044 	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1045 
1046 	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1047 		return (FALSE);
1048 
1049 	return (TRUE);
1050 }
1051 
1052 static int
1053 bwn_attach_post(struct bwn_softc *sc)
1054 {
1055 	struct ieee80211com *ic;
1056 	struct ifnet *ifp = sc->sc_ifp;
1057 
1058 	ic = ifp->if_l2com;
1059 	ic->ic_ifp = ifp;
1060 	/* XXX not right but it's not used anywhere important */
1061 	ic->ic_phytype = IEEE80211_T_OFDM;
1062 	ic->ic_opmode = IEEE80211_M_STA;
1063 	ic->ic_caps =
1064 		  IEEE80211_C_STA		/* station mode supported */
1065 		| IEEE80211_C_MONITOR		/* monitor mode */
1066 		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
1067 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
1068 		| IEEE80211_C_SHSLOT		/* short slot time supported */
1069 		| IEEE80211_C_WME		/* WME/WMM supported */
1070 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
1071 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
1072 		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
1073 		;
1074 
1075 	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;	/* s/w bmiss */
1076 
1077 	/* call MI attach routine. */
1078 	ieee80211_ifattach(ic,
1079 	    bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1080 	    siba_sprom_get_mac_80211a(sc->sc_dev) :
1081 	    siba_sprom_get_mac_80211bg(sc->sc_dev));
1082 
1083 	ic->ic_headroom = sizeof(struct bwn_txhdr);
1084 
1085 	/* override default methods */
1086 	ic->ic_raw_xmit = bwn_raw_xmit;
1087 	ic->ic_updateslot = bwn_updateslot;
1088 	ic->ic_update_promisc = bwn_update_promisc;
1089 	ic->ic_wme.wme_update = bwn_wme_update;
1090 
1091 	ic->ic_scan_start = bwn_scan_start;
1092 	ic->ic_scan_end = bwn_scan_end;
1093 	ic->ic_set_channel = bwn_set_channel;
1094 
1095 	ic->ic_vap_create = bwn_vap_create;
1096 	ic->ic_vap_delete = bwn_vap_delete;
1097 
1098 	ieee80211_radiotap_attach(ic,
1099 	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1100 	    BWN_TX_RADIOTAP_PRESENT,
1101 	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1102 	    BWN_RX_RADIOTAP_PRESENT);
1103 
1104 	bwn_sysctl_node(sc);
1105 
1106 	if (bootverbose)
1107 		ieee80211_announce(ic);
1108 	return (0);
1109 }
1110 
1111 static void
1112 bwn_phy_detach(struct bwn_mac *mac)
1113 {
1114 
1115 	if (mac->mac_phy.detach != NULL)
1116 		mac->mac_phy.detach(mac);
1117 }
1118 
1119 static int
1120 bwn_detach(device_t dev)
1121 {
1122 	struct bwn_softc *sc = device_get_softc(dev);
1123 	struct bwn_mac *mac = sc->sc_curmac;
1124 	struct ifnet *ifp = sc->sc_ifp;
1125 	struct ieee80211com *ic = ifp->if_l2com;
1126 	int i;
1127 
1128 	sc->sc_flags |= BWN_FLAG_INVALID;
1129 
1130 	if (device_is_attached(sc->sc_dev)) {
1131 		bwn_stop(sc, 1);
1132 		bwn_dma_free(mac);
1133 		callout_drain(&sc->sc_led_blink_ch);
1134 		callout_drain(&sc->sc_rfswitch_ch);
1135 		callout_drain(&sc->sc_task_ch);
1136 		callout_drain(&sc->sc_watchdog_ch);
1137 		bwn_phy_detach(mac);
1138 		if (ifp != NULL) {
1139 			ieee80211_draintask(ic, &mac->mac_hwreset);
1140 			ieee80211_draintask(ic, &mac->mac_txpower);
1141 			ieee80211_ifdetach(ic);
1142 			if_free(ifp);
1143 		}
1144 	}
1145 	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1146 	taskqueue_free(sc->sc_tq);
1147 
1148 	for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1149 		if (mac->mac_intrhand[i] != NULL) {
1150 			bus_teardown_intr(dev, mac->mac_res_irq[i],
1151 			    mac->mac_intrhand[i]);
1152 			mac->mac_intrhand[i] = NULL;
1153 		}
1154 	}
1155 	bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1156 	if (mac->mac_msi != 0)
1157 		pci_release_msi(dev);
1158 
1159 	BWN_LOCK_DESTROY(sc);
1160 	return (0);
1161 }
1162 
1163 static int
1164 bwn_attach_pre(struct bwn_softc *sc)
1165 {
1166 	struct ifnet *ifp;
1167 	int error = 0;
1168 
1169 	BWN_LOCK_INIT(sc);
1170 	TAILQ_INIT(&sc->sc_maclist);
1171 	callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1172 	callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1173 	callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1174 
1175 	sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1176 		taskqueue_thread_enqueue, &sc->sc_tq);
1177 	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1178 		"%s taskq", device_get_nameunit(sc->sc_dev));
1179 
1180 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1181 	if (ifp == NULL) {
1182 		device_printf(sc->sc_dev, "can not if_alloc()\n");
1183 		error = ENOSPC;
1184 		goto fail;
1185 	}
1186 
1187 	/* set these up early for if_printf use */
1188 	if_initname(ifp, device_get_name(sc->sc_dev),
1189 	    device_get_unit(sc->sc_dev));
1190 
1191 	ifp->if_softc = sc;
1192 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1193 	ifp->if_init = bwn_init;
1194 	ifp->if_ioctl = bwn_ioctl;
1195 	ifp->if_start = bwn_start;
1196 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1197 	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1198 	IFQ_SET_READY(&ifp->if_snd);
1199 
1200 	return (0);
1201 
1202 fail:	BWN_LOCK_DESTROY(sc);
1203 	return (error);
1204 }
1205 
1206 static void
1207 bwn_sprom_bugfixes(device_t dev)
1208 {
1209 #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
1210 	((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&		\
1211 	 (siba_get_pci_device(dev) == _device) &&			\
1212 	 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&	\
1213 	 (siba_get_pci_subdevice(dev) == _subdevice))
1214 
1215 	if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1216 	    siba_get_pci_subdevice(dev) == 0x4e &&
1217 	    siba_get_pci_revid(dev) > 0x40)
1218 		siba_sprom_set_bf_lo(dev,
1219 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1220 	if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1221 	    siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1222 		siba_sprom_set_bf_lo(dev,
1223 		    siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1224 	if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1225 		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1226 		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1227 		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1228 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1229 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1230 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1231 		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1232 			siba_sprom_set_bf_lo(dev,
1233 			    siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1234 	}
1235 #undef	BWN_ISDEV
1236 }
1237 
1238 static int
1239 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1240 {
1241 #define	IS_RUNNING(ifp) \
1242 	((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1243 	struct bwn_softc *sc = ifp->if_softc;
1244 	struct ieee80211com *ic = ifp->if_l2com;
1245 	struct ifreq *ifr = (struct ifreq *)data;
1246 	int error = 0, startall;
1247 
1248 	switch (cmd) {
1249 	case SIOCSIFFLAGS:
1250 		startall = 0;
1251 		if (IS_RUNNING(ifp)) {
1252 			bwn_update_promisc(ifp);
1253 		} else if (ifp->if_flags & IFF_UP) {
1254 			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1255 				bwn_init(sc);
1256 				startall = 1;
1257 			}
1258 		} else
1259 			bwn_stop(sc, 1);
1260 		if (startall)
1261 			ieee80211_start_all(ic);
1262 		break;
1263 	case SIOCGIFMEDIA:
1264 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1265 		break;
1266 	case SIOCGIFADDR:
1267 		error = ether_ioctl(ifp, cmd, data);
1268 		break;
1269 	default:
1270 		error = EINVAL;
1271 		break;
1272 	}
1273 	return (error);
1274 }
1275 
1276 static void
1277 bwn_start(struct ifnet *ifp)
1278 {
1279 	struct bwn_softc *sc = ifp->if_softc;
1280 
1281 	BWN_LOCK(sc);
1282 	bwn_start_locked(ifp);
1283 	BWN_UNLOCK(sc);
1284 }
1285 
1286 static void
1287 bwn_start_locked(struct ifnet *ifp)
1288 {
1289 	struct bwn_softc *sc = ifp->if_softc;
1290 	struct bwn_mac *mac = sc->sc_curmac;
1291 	struct ieee80211_frame *wh;
1292 	struct ieee80211_node *ni;
1293 	struct ieee80211_key *k;
1294 	struct mbuf *m;
1295 
1296 	BWN_ASSERT_LOCKED(sc);
1297 
1298 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1299 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
1300 		return;
1301 
1302 	for (;;) {
1303 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);	/* XXX: LOCK */
1304 		if (m == NULL)
1305 			break;
1306 
1307 		if (bwn_tx_isfull(sc, m))
1308 			break;
1309 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1310 		if (ni == NULL) {
1311 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
1312 			m_freem(m);
1313 			ifp->if_oerrors++;
1314 			continue;
1315 		}
1316 		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1317 		wh = mtod(m, struct ieee80211_frame *);
1318 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1319 			k = ieee80211_crypto_encap(ni, m);
1320 			if (k == NULL) {
1321 				ieee80211_free_node(ni);
1322 				m_freem(m);
1323 				ifp->if_oerrors++;
1324 				continue;
1325 			}
1326 		}
1327 		wh = NULL;	/* Catch any invalid use */
1328 
1329 		if (bwn_tx_start(sc, ni, m) != 0) {
1330 			if (ni != NULL)
1331 				ieee80211_free_node(ni);
1332 			ifp->if_oerrors++;
1333 			continue;
1334 		}
1335 
1336 		sc->sc_watchdog_timer = 5;
1337 	}
1338 }
1339 
1340 static int
1341 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1342 {
1343 	struct bwn_dma_ring *dr;
1344 	struct bwn_mac *mac = sc->sc_curmac;
1345 	struct bwn_pio_txqueue *tq;
1346 	struct ifnet *ifp = sc->sc_ifp;
1347 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1348 
1349 	BWN_ASSERT_LOCKED(sc);
1350 
1351 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1352 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1353 		if (dr->dr_stop == 1 ||
1354 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1355 			dr->dr_stop = 1;
1356 			goto full;
1357 		}
1358 	} else {
1359 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1360 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1361 		    pktlen > (tq->tq_size - tq->tq_used)) {
1362 			tq->tq_stop = 1;
1363 			goto full;
1364 		}
1365 	}
1366 	return (0);
1367 full:
1368 	IFQ_DRV_PREPEND(&ifp->if_snd, m);
1369 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1370 	return (1);
1371 }
1372 
1373 static int
1374 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1375 {
1376 	struct bwn_mac *mac = sc->sc_curmac;
1377 	int error;
1378 
1379 	BWN_ASSERT_LOCKED(sc);
1380 
1381 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1382 		m_freem(m);
1383 		return (ENXIO);
1384 	}
1385 
1386 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1387 	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1388 	if (error) {
1389 		m_freem(m);
1390 		return (error);
1391 	}
1392 	return (0);
1393 }
1394 
1395 static int
1396 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1397 {
1398 	struct bwn_pio_txpkt *tp;
1399 	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1400 	struct bwn_softc *sc = mac->mac_sc;
1401 	struct bwn_txhdr txhdr;
1402 	struct mbuf *m_new;
1403 	uint32_t ctl32;
1404 	int error;
1405 	uint16_t ctl16;
1406 
1407 	BWN_ASSERT_LOCKED(sc);
1408 
1409 	/* XXX TODO send packets after DTIM */
1410 
1411 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1412 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1413 	tp->tp_ni = ni;
1414 	tp->tp_m = m;
1415 
1416 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1417 	if (error) {
1418 		device_printf(sc->sc_dev, "tx fail\n");
1419 		return (error);
1420 	}
1421 
1422 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1423 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1424 	tq->tq_free--;
1425 
1426 	if (siba_get_revid(sc->sc_dev) >= 8) {
1427 		/*
1428 		 * XXX please removes m_defrag(9)
1429 		 */
1430 		m_new = m_defrag(m, M_DONTWAIT);
1431 		if (m_new == NULL) {
1432 			device_printf(sc->sc_dev,
1433 			    "%s: can't defrag TX buffer\n",
1434 			    __func__);
1435 			return (ENOBUFS);
1436 		}
1437 		if (m_new->m_next != NULL)
1438 			device_printf(sc->sc_dev,
1439 			    "TODO: fragmented packets for PIO\n");
1440 		tp->tp_m = m_new;
1441 
1442 		/* send HEADER */
1443 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1444 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1445 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1446 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1447 		/* send BODY */
1448 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1449 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1450 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1451 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1452 	} else {
1453 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1454 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1455 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1456 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1457 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1458 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1459 		    ctl16 | BWN_PIO_TXCTL_EOF);
1460 	}
1461 
1462 	return (0);
1463 }
1464 
1465 static struct bwn_pio_txqueue *
1466 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1467 {
1468 
1469 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1470 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1471 
1472 	switch (prio) {
1473 	case 0:
1474 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1475 	case 1:
1476 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1477 	case 2:
1478 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1479 	case 3:
1480 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1481 	}
1482 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1483 	return (NULL);
1484 }
1485 
1486 static int
1487 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1488 {
1489 #define	BWN_GET_TXHDRCACHE(slot)					\
1490 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1491 	struct bwn_dma *dma = &mac->mac_method.dma;
1492 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1493 	struct bwn_dmadesc_generic *desc;
1494 	struct bwn_dmadesc_meta *mt;
1495 	struct bwn_softc *sc = mac->mac_sc;
1496 	struct ifnet *ifp = sc->sc_ifp;
1497 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1498 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1499 
1500 	BWN_ASSERT_LOCKED(sc);
1501 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1502 
1503 	/* XXX send after DTIM */
1504 
1505 	slot = bwn_dma_getslot(dr);
1506 	dr->getdesc(dr, slot, &desc, &mt);
1507 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1508 	    ("%s:%d: fail", __func__, __LINE__));
1509 
1510 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1511 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1512 	    BWN_DMA_COOKIE(dr, slot));
1513 	if (error)
1514 		goto fail;
1515 	error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1516 	    BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1517 	    &mt->mt_paddr, BUS_DMA_NOWAIT);
1518 	if (error) {
1519 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1520 		    __func__, error);
1521 		goto fail;
1522 	}
1523 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1524 	    BUS_DMASYNC_PREWRITE);
1525 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1526 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1527 	    BUS_DMASYNC_PREWRITE);
1528 
1529 	slot = bwn_dma_getslot(dr);
1530 	dr->getdesc(dr, slot, &desc, &mt);
1531 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1532 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1533 	mt->mt_m = m;
1534 	mt->mt_ni = ni;
1535 
1536 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1537 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1538 	if (error && error != EFBIG) {
1539 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1540 		    __func__, error);
1541 		goto fail;
1542 	}
1543 	if (error) {    /* error == EFBIG */
1544 		struct mbuf *m_new;
1545 
1546 		m_new = m_defrag(m, M_DONTWAIT);
1547 		if (m_new == NULL) {
1548 			if_printf(ifp, "%s: can't defrag TX buffer\n",
1549 			    __func__);
1550 			error = ENOBUFS;
1551 			goto fail;
1552 		} else {
1553 			m = m_new;
1554 		}
1555 
1556 		mt->mt_m = m;
1557 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1558 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1559 		if (error) {
1560 			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1561 			    __func__, error);
1562 			goto fail;
1563 		}
1564 	}
1565 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1566 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1567 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1568 	    BUS_DMASYNC_PREWRITE);
1569 
1570 	/* XXX send after DTIM */
1571 
1572 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1573 	return (0);
1574 fail:
1575 	dr->dr_curslot = backup[0];
1576 	dr->dr_usedslot = backup[1];
1577 	return (error);
1578 #undef BWN_GET_TXHDRCACHE
1579 }
1580 
1581 static void
1582 bwn_watchdog(void *arg)
1583 {
1584 	struct bwn_softc *sc = arg;
1585 	struct ifnet *ifp = sc->sc_ifp;
1586 
1587 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1588 		if_printf(ifp, "device timeout\n");
1589 		ifp->if_oerrors++;
1590 	}
1591 	callout_schedule(&sc->sc_watchdog_ch, hz);
1592 }
1593 
1594 static int
1595 bwn_attach_core(struct bwn_mac *mac)
1596 {
1597 	struct bwn_softc *sc = mac->mac_sc;
1598 	int error, have_bg = 0, have_a = 0;
1599 	uint32_t high;
1600 
1601 	KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1602 	    ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1603 
1604 	siba_powerup(sc->sc_dev, 0);
1605 
1606 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1607 	bwn_reset_core(mac,
1608 	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1609 	error = bwn_phy_getinfo(mac, high);
1610 	if (error)
1611 		goto fail;
1612 
1613 	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1614 	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1615 	if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1616 	    siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1617 	    siba_get_pci_device(sc->sc_dev) != 0x4324) {
1618 		have_a = have_bg = 0;
1619 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1620 			have_a = 1;
1621 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1622 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1623 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1624 			have_bg = 1;
1625 		else
1626 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1627 			    mac->mac_phy.type));
1628 	}
1629 	/* XXX turns off PHY A because it's not supported */
1630 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1631 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1632 		have_a = 0;
1633 		have_bg = 1;
1634 	}
1635 
1636 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1637 		mac->mac_phy.attach = bwn_phy_g_attach;
1638 		mac->mac_phy.detach = bwn_phy_g_detach;
1639 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1640 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1641 		mac->mac_phy.init = bwn_phy_g_init;
1642 		mac->mac_phy.exit = bwn_phy_g_exit;
1643 		mac->mac_phy.phy_read = bwn_phy_g_read;
1644 		mac->mac_phy.phy_write = bwn_phy_g_write;
1645 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1646 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1647 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1648 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1649 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1650 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1651 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1652 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1653 		mac->mac_phy.set_im = bwn_phy_g_im;
1654 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1655 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1656 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1657 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1658 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1659 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1660 		mac->mac_phy.init = bwn_phy_lp_init;
1661 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1662 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1663 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1664 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1665 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1666 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1667 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1668 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1669 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1670 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1671 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1672 	} else {
1673 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1674 		    mac->mac_phy.type);
1675 		error = ENXIO;
1676 		goto fail;
1677 	}
1678 
1679 	mac->mac_phy.gmode = have_bg;
1680 	if (mac->mac_phy.attach != NULL) {
1681 		error = mac->mac_phy.attach(mac);
1682 		if (error) {
1683 			device_printf(sc->sc_dev, "failed\n");
1684 			goto fail;
1685 		}
1686 	}
1687 
1688 	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1689 
1690 	error = bwn_chiptest(mac);
1691 	if (error)
1692 		goto fail;
1693 	error = bwn_setup_channels(mac, have_bg, have_a);
1694 	if (error) {
1695 		device_printf(sc->sc_dev, "failed to setup channels\n");
1696 		goto fail;
1697 	}
1698 
1699 	if (sc->sc_curmac == NULL)
1700 		sc->sc_curmac = mac;
1701 
1702 	error = bwn_dma_attach(mac);
1703 	if (error != 0) {
1704 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1705 		goto fail;
1706 	}
1707 
1708 	mac->mac_phy.switch_analog(mac, 0);
1709 
1710 	siba_dev_down(sc->sc_dev, 0);
1711 fail:
1712 	siba_powerdown(sc->sc_dev);
1713 	return (error);
1714 }
1715 
1716 static void
1717 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1718 {
1719 	struct bwn_softc *sc = mac->mac_sc;
1720 	uint32_t low, ctl;
1721 
1722 	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1723 
1724 	siba_dev_up(sc->sc_dev, flags);
1725 	DELAY(2000);
1726 
1727 	low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1728 	    ~BWN_TGSLOW_PHYRESET;
1729 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1730 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1731 	DELAY(1000);
1732 	siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1733 	siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1734 	DELAY(1000);
1735 
1736 	if (mac->mac_phy.switch_analog != NULL)
1737 		mac->mac_phy.switch_analog(mac, 1);
1738 
1739 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1740 	if (flags & BWN_TGSLOW_SUPPORT_G)
1741 		ctl |= BWN_MACCTL_GMODE;
1742 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1743 }
1744 
1745 static int
1746 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1747 {
1748 	struct bwn_phy *phy = &mac->mac_phy;
1749 	struct bwn_softc *sc = mac->mac_sc;
1750 	uint32_t tmp;
1751 
1752 	/* PHY */
1753 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1754 	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1755 	phy->rf_on = 1;
1756 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1757 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1758 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1759 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1760 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1761 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1762 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1763 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1764 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1765 		goto unsupphy;
1766 
1767 	/* RADIO */
1768 	if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1769 		if (siba_get_chiprev(sc->sc_dev) == 0)
1770 			tmp = 0x3205017f;
1771 		else if (siba_get_chiprev(sc->sc_dev) == 1)
1772 			tmp = 0x4205017f;
1773 		else
1774 			tmp = 0x5205017f;
1775 	} else {
1776 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1777 		tmp = BWN_READ_2(mac, BWN_RFDATALO);
1778 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1779 		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1780 	}
1781 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1782 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1783 	phy->rf_manuf = (tmp & 0x00000fff);
1784 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1785 		goto unsupradio;
1786 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1787 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1788 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1789 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1790 	    (phy->type == BWN_PHYTYPE_N &&
1791 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1792 	    (phy->type == BWN_PHYTYPE_LP &&
1793 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1794 		goto unsupradio;
1795 
1796 	return (0);
1797 unsupphy:
1798 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1799 	    "analog %#x)\n",
1800 	    phy->type, phy->rev, phy->analog);
1801 	return (ENXIO);
1802 unsupradio:
1803 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1804 	    "rev %#x)\n",
1805 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1806 	return (ENXIO);
1807 }
1808 
1809 static int
1810 bwn_chiptest(struct bwn_mac *mac)
1811 {
1812 #define	TESTVAL0	0x55aaaa55
1813 #define	TESTVAL1	0xaa5555aa
1814 	struct bwn_softc *sc = mac->mac_sc;
1815 	uint32_t v, backup;
1816 
1817 	BWN_LOCK(sc);
1818 
1819 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1820 
1821 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1822 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1823 		goto error;
1824 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1825 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1826 		goto error;
1827 
1828 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1829 
1830 	if ((siba_get_revid(sc->sc_dev) >= 3) &&
1831 	    (siba_get_revid(sc->sc_dev) <= 10)) {
1832 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1833 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1834 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1835 			goto error;
1836 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1837 			goto error;
1838 	}
1839 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1840 
1841 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1842 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1843 		goto error;
1844 
1845 	BWN_UNLOCK(sc);
1846 	return (0);
1847 error:
1848 	BWN_UNLOCK(sc);
1849 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1850 	return (ENODEV);
1851 }
1852 
1853 #define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1854 #define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1855 
1856 static int
1857 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1858 {
1859 	struct bwn_softc *sc = mac->mac_sc;
1860 	struct ifnet *ifp = sc->sc_ifp;
1861 	struct ieee80211com *ic = ifp->if_l2com;
1862 
1863 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1864 	ic->ic_nchans = 0;
1865 
1866 	if (have_bg)
1867 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1868 		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1869 	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1870 		if (have_a)
1871 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1872 			    &ic->ic_nchans, &bwn_chantable_n,
1873 			    IEEE80211_CHAN_HTA);
1874 	} else {
1875 		if (have_a)
1876 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1877 			    &ic->ic_nchans, &bwn_chantable_a,
1878 			    IEEE80211_CHAN_A);
1879 	}
1880 
1881 	mac->mac_phy.supports_2ghz = have_bg;
1882 	mac->mac_phy.supports_5ghz = have_a;
1883 
1884 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1885 }
1886 
1887 static uint32_t
1888 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1889 {
1890 	uint32_t ret;
1891 
1892 	BWN_ASSERT_LOCKED(mac->mac_sc);
1893 
1894 	if (way == BWN_SHARED) {
1895 		KASSERT((offset & 0x0001) == 0,
1896 		    ("%s:%d warn", __func__, __LINE__));
1897 		if (offset & 0x0003) {
1898 			bwn_shm_ctlword(mac, way, offset >> 2);
1899 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1900 			ret <<= 16;
1901 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1902 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1903 			goto out;
1904 		}
1905 		offset >>= 2;
1906 	}
1907 	bwn_shm_ctlword(mac, way, offset);
1908 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1909 out:
1910 	return (ret);
1911 }
1912 
1913 static uint16_t
1914 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1915 {
1916 	uint16_t ret;
1917 
1918 	BWN_ASSERT_LOCKED(mac->mac_sc);
1919 
1920 	if (way == BWN_SHARED) {
1921 		KASSERT((offset & 0x0001) == 0,
1922 		    ("%s:%d warn", __func__, __LINE__));
1923 		if (offset & 0x0003) {
1924 			bwn_shm_ctlword(mac, way, offset >> 2);
1925 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1926 			goto out;
1927 		}
1928 		offset >>= 2;
1929 	}
1930 	bwn_shm_ctlword(mac, way, offset);
1931 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1932 out:
1933 
1934 	return (ret);
1935 }
1936 
1937 static void
1938 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1939     uint16_t offset)
1940 {
1941 	uint32_t control;
1942 
1943 	control = way;
1944 	control <<= 16;
1945 	control |= offset;
1946 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1947 }
1948 
1949 static void
1950 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1951     uint32_t value)
1952 {
1953 	BWN_ASSERT_LOCKED(mac->mac_sc);
1954 
1955 	if (way == BWN_SHARED) {
1956 		KASSERT((offset & 0x0001) == 0,
1957 		    ("%s:%d warn", __func__, __LINE__));
1958 		if (offset & 0x0003) {
1959 			bwn_shm_ctlword(mac, way, offset >> 2);
1960 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1961 				    (value >> 16) & 0xffff);
1962 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1963 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1964 			return;
1965 		}
1966 		offset >>= 2;
1967 	}
1968 	bwn_shm_ctlword(mac, way, offset);
1969 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1970 }
1971 
1972 static void
1973 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1974     uint16_t value)
1975 {
1976 	BWN_ASSERT_LOCKED(mac->mac_sc);
1977 
1978 	if (way == BWN_SHARED) {
1979 		KASSERT((offset & 0x0001) == 0,
1980 		    ("%s:%d warn", __func__, __LINE__));
1981 		if (offset & 0x0003) {
1982 			bwn_shm_ctlword(mac, way, offset >> 2);
1983 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1984 			return;
1985 		}
1986 		offset >>= 2;
1987 	}
1988 	bwn_shm_ctlword(mac, way, offset);
1989 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1990 }
1991 
1992 static void
1993 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1994     int txpow)
1995 {
1996 
1997 	c->ic_freq = freq;
1998 	c->ic_flags = flags;
1999 	c->ic_ieee = ieee;
2000 	c->ic_minpower = 0;
2001 	c->ic_maxpower = 2 * txpow;
2002 	c->ic_maxregpower = txpow;
2003 }
2004 
2005 static void
2006 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2007     const struct bwn_channelinfo *ci, int flags)
2008 {
2009 	struct ieee80211_channel *c;
2010 	int i;
2011 
2012 	c = &chans[*nchans];
2013 
2014 	for (i = 0; i < ci->nchannels; i++) {
2015 		const struct bwn_channel *hc;
2016 
2017 		hc = &ci->channels[i];
2018 		if (*nchans >= maxchans)
2019 			break;
2020 		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2021 		c++, (*nchans)++;
2022 		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2023 			/* g channel have a separate b-only entry */
2024 			if (*nchans >= maxchans)
2025 				break;
2026 			c[0] = c[-1];
2027 			c[-1].ic_flags = IEEE80211_CHAN_B;
2028 			c++, (*nchans)++;
2029 		}
2030 		if (flags == IEEE80211_CHAN_HTG) {
2031 			/* HT g channel have a separate g-only entry */
2032 			if (*nchans >= maxchans)
2033 				break;
2034 			c[-1].ic_flags = IEEE80211_CHAN_G;
2035 			c[0] = c[-1];
2036 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2037 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
2038 			c++, (*nchans)++;
2039 		}
2040 		if (flags == IEEE80211_CHAN_HTA) {
2041 			/* HT a channel have a separate a-only entry */
2042 			if (*nchans >= maxchans)
2043 				break;
2044 			c[-1].ic_flags = IEEE80211_CHAN_A;
2045 			c[0] = c[-1];
2046 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2047 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
2048 			c++, (*nchans)++;
2049 		}
2050 	}
2051 }
2052 
2053 static int
2054 bwn_phy_g_attach(struct bwn_mac *mac)
2055 {
2056 	struct bwn_softc *sc = mac->mac_sc;
2057 	struct bwn_phy *phy = &mac->mac_phy;
2058 	struct bwn_phy_g *pg = &phy->phy_g;
2059 	unsigned int i;
2060 	int16_t pab0, pab1, pab2;
2061 	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2062 	int8_t bg;
2063 
2064 	bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2065 	pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2066 	pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2067 	pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2068 
2069 	if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2070 		device_printf(sc->sc_dev, "not supported anymore\n");
2071 
2072 	pg->pg_flags = 0;
2073 	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2074 	    pab2 == -1) {
2075 		pg->pg_idletssi = 52;
2076 		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2077 		return (0);
2078 	}
2079 
2080 	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2081 	pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2082 	if (pg->pg_tssi2dbm == NULL) {
2083 		device_printf(sc->sc_dev, "failed to allocate buffer\n");
2084 		return (ENOMEM);
2085 	}
2086 	for (i = 0; i < 64; i++) {
2087 		int32_t m1, m2, f, q, delta;
2088 		int8_t j = 0;
2089 
2090 		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2091 		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2092 		f = 256;
2093 
2094 		do {
2095 			if (j > 15) {
2096 				device_printf(sc->sc_dev,
2097 				    "failed to generate tssi2dBm\n");
2098 				free(pg->pg_tssi2dbm, M_DEVBUF);
2099 				return (ENOMEM);
2100 			}
2101 			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2102 			    f, 2048);
2103 			delta = abs(q - f);
2104 			f = q;
2105 			j++;
2106 		} while (delta >= 2);
2107 
2108 		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2109 		    128);
2110 	}
2111 
2112 	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2113 	return (0);
2114 }
2115 
2116 static void
2117 bwn_phy_g_detach(struct bwn_mac *mac)
2118 {
2119 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2120 
2121 	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2122 		free(pg->pg_tssi2dbm, M_DEVBUF);
2123 		pg->pg_tssi2dbm = NULL;
2124 	}
2125 	pg->pg_flags = 0;
2126 }
2127 
2128 static void
2129 bwn_phy_g_init_pre(struct bwn_mac *mac)
2130 {
2131 	struct bwn_phy *phy = &mac->mac_phy;
2132 	struct bwn_phy_g *pg = &phy->phy_g;
2133 	void *tssi2dbm;
2134 	int idletssi;
2135 	unsigned int i;
2136 
2137 	tssi2dbm = pg->pg_tssi2dbm;
2138 	idletssi = pg->pg_idletssi;
2139 
2140 	memset(pg, 0, sizeof(*pg));
2141 
2142 	pg->pg_tssi2dbm = tssi2dbm;
2143 	pg->pg_idletssi = idletssi;
2144 
2145 	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2146 
2147 	for (i = 0; i < N(pg->pg_nrssi); i++)
2148 		pg->pg_nrssi[i] = -1000;
2149 	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2150 		pg->pg_nrssi_lt[i] = i;
2151 	pg->pg_lofcal = 0xffff;
2152 	pg->pg_initval = 0xffff;
2153 	pg->pg_immode = BWN_IMMODE_NONE;
2154 	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2155 	pg->pg_avgtssi = 0xff;
2156 
2157 	pg->pg_loctl.tx_bias = 0xff;
2158 	TAILQ_INIT(&pg->pg_loctl.calib_list);
2159 }
2160 
2161 static int
2162 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2163 {
2164 	struct bwn_phy *phy = &mac->mac_phy;
2165 	struct bwn_phy_g *pg = &phy->phy_g;
2166 	struct bwn_softc *sc = mac->mac_sc;
2167 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2168 	static const struct bwn_rfatt rfatt0[] = {
2169 		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
2170 		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2171 		{ 3, 1 }, { 4, 1 }
2172 	};
2173 	static const struct bwn_rfatt rfatt1[] = {
2174 		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2175 		{ 14, 1 }
2176 	};
2177 	static const struct bwn_rfatt rfatt2[] = {
2178 		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2179 		{ 9, 1 }
2180 	};
2181 	static const struct bwn_bbatt bbatt_0[] = {
2182 		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2183 	};
2184 
2185 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2186 
2187 	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2188 		pg->pg_bbatt.att = 0;
2189 	else
2190 		pg->pg_bbatt.att = 2;
2191 
2192 	/* prepare Radio Attenuation */
2193 	pg->pg_rfatt.padmix = 0;
2194 
2195 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2196 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2197 		if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2198 			pg->pg_rfatt.att = 2;
2199 			goto done;
2200 		} else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2201 			pg->pg_rfatt.att = 3;
2202 			goto done;
2203 		}
2204 	}
2205 
2206 	if (phy->type == BWN_PHYTYPE_A) {
2207 		pg->pg_rfatt.att = 0x60;
2208 		goto done;
2209 	}
2210 
2211 	switch (phy->rf_ver) {
2212 	case 0x2050:
2213 		switch (phy->rf_rev) {
2214 		case 0:
2215 			pg->pg_rfatt.att = 5;
2216 			goto done;
2217 		case 1:
2218 			if (phy->type == BWN_PHYTYPE_G) {
2219 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2220 				    SIBA_BOARDVENDOR_BCM &&
2221 				    siba_get_pci_subdevice(sc->sc_dev) ==
2222 				    SIBA_BOARD_BCM4309G &&
2223 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2224 					pg->pg_rfatt.att = 3;
2225 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2226 				    SIBA_BOARDVENDOR_BCM &&
2227 				    siba_get_pci_subdevice(sc->sc_dev) ==
2228 				    SIBA_BOARD_BU4306)
2229 					pg->pg_rfatt.att = 3;
2230 				else
2231 					pg->pg_rfatt.att = 1;
2232 			} else {
2233 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2234 				    SIBA_BOARDVENDOR_BCM &&
2235 				    siba_get_pci_subdevice(sc->sc_dev) ==
2236 				    SIBA_BOARD_BCM4309G &&
2237 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2238 					pg->pg_rfatt.att = 7;
2239 				else
2240 					pg->pg_rfatt.att = 6;
2241 			}
2242 			goto done;
2243 		case 2:
2244 			if (phy->type == BWN_PHYTYPE_G) {
2245 				if (siba_get_pci_subvendor(sc->sc_dev) ==
2246 				    SIBA_BOARDVENDOR_BCM &&
2247 				    siba_get_pci_subdevice(sc->sc_dev) ==
2248 				    SIBA_BOARD_BCM4309G &&
2249 				    siba_get_pci_revid(sc->sc_dev) >= 30)
2250 					pg->pg_rfatt.att = 3;
2251 				else if (siba_get_pci_subvendor(sc->sc_dev) ==
2252 				    SIBA_BOARDVENDOR_BCM &&
2253 				    siba_get_pci_subdevice(sc->sc_dev) ==
2254 				    SIBA_BOARD_BU4306)
2255 					pg->pg_rfatt.att = 5;
2256 				else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2257 					pg->pg_rfatt.att = 4;
2258 				else
2259 					pg->pg_rfatt.att = 3;
2260 			} else
2261 				pg->pg_rfatt.att = 6;
2262 			goto done;
2263 		case 3:
2264 			pg->pg_rfatt.att = 5;
2265 			goto done;
2266 		case 4:
2267 		case 5:
2268 			pg->pg_rfatt.att = 1;
2269 			goto done;
2270 		case 6:
2271 		case 7:
2272 			pg->pg_rfatt.att = 5;
2273 			goto done;
2274 		case 8:
2275 			pg->pg_rfatt.att = 0xa;
2276 			pg->pg_rfatt.padmix = 1;
2277 			goto done;
2278 		case 9:
2279 		default:
2280 			pg->pg_rfatt.att = 5;
2281 			goto done;
2282 		}
2283 		break;
2284 	case 0x2053:
2285 		switch (phy->rf_rev) {
2286 		case 1:
2287 			pg->pg_rfatt.att = 6;
2288 			goto done;
2289 		}
2290 		break;
2291 	}
2292 	pg->pg_rfatt.att = 5;
2293 done:
2294 	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2295 
2296 	if (!bwn_has_hwpctl(mac)) {
2297 		lo->rfatt.array = rfatt0;
2298 		lo->rfatt.len = N(rfatt0);
2299 		lo->rfatt.min = 0;
2300 		lo->rfatt.max = 9;
2301 		goto genbbatt;
2302 	}
2303 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2304 		lo->rfatt.array = rfatt1;
2305 		lo->rfatt.len = N(rfatt1);
2306 		lo->rfatt.min = 0;
2307 		lo->rfatt.max = 14;
2308 		goto genbbatt;
2309 	}
2310 	lo->rfatt.array = rfatt2;
2311 	lo->rfatt.len = N(rfatt2);
2312 	lo->rfatt.min = 0;
2313 	lo->rfatt.max = 9;
2314 genbbatt:
2315 	lo->bbatt.array = bbatt_0;
2316 	lo->bbatt.len = N(bbatt_0);
2317 	lo->bbatt.min = 0;
2318 	lo->bbatt.max = 8;
2319 
2320 	BWN_READ_4(mac, BWN_MACCTL);
2321 	if (phy->rev == 1) {
2322 		phy->gmode = 0;
2323 		bwn_reset_core(mac, 0);
2324 		bwn_phy_g_init_sub(mac);
2325 		phy->gmode = 1;
2326 		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2327 	}
2328 	return (0);
2329 }
2330 
2331 static uint16_t
2332 bwn_phy_g_txctl(struct bwn_mac *mac)
2333 {
2334 	struct bwn_phy *phy = &mac->mac_phy;
2335 
2336 	if (phy->rf_ver != 0x2050)
2337 		return (0);
2338 	if (phy->rf_rev == 1)
2339 		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2340 	if (phy->rf_rev < 6)
2341 		return (BWN_TXCTL_PA2DB);
2342 	if (phy->rf_rev == 8)
2343 		return (BWN_TXCTL_TXMIX);
2344 	return (0);
2345 }
2346 
2347 static int
2348 bwn_phy_g_init(struct bwn_mac *mac)
2349 {
2350 
2351 	bwn_phy_g_init_sub(mac);
2352 	return (0);
2353 }
2354 
2355 static void
2356 bwn_phy_g_exit(struct bwn_mac *mac)
2357 {
2358 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2359 	struct bwn_lo_calib *cal, *tmp;
2360 
2361 	if (lo == NULL)
2362 		return;
2363 	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2364 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2365 		free(cal, M_DEVBUF);
2366 	}
2367 }
2368 
2369 static uint16_t
2370 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2371 {
2372 
2373 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2374 	return (BWN_READ_2(mac, BWN_PHYDATA));
2375 }
2376 
2377 static void
2378 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2379 {
2380 
2381 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2382 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
2383 }
2384 
2385 static uint16_t
2386 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2387 {
2388 
2389 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2390 	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2391 	return (BWN_READ_2(mac, BWN_RFDATALO));
2392 }
2393 
2394 static void
2395 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2396 {
2397 
2398 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2399 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
2400 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
2401 }
2402 
2403 static int
2404 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2405 {
2406 
2407 	return (mac->mac_phy.rev >= 6);
2408 }
2409 
2410 static void
2411 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2412 {
2413 	struct bwn_phy *phy = &mac->mac_phy;
2414 	struct bwn_phy_g *pg = &phy->phy_g;
2415 	unsigned int channel;
2416 	uint16_t rfover, rfoverval;
2417 
2418 	if (on) {
2419 		if (phy->rf_on)
2420 			return;
2421 
2422 		BWN_PHY_WRITE(mac, 0x15, 0x8000);
2423 		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2424 		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2425 		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2426 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2427 			    pg->pg_radioctx_over);
2428 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2429 			    pg->pg_radioctx_overval);
2430 			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2431 		}
2432 		channel = phy->chan;
2433 		bwn_phy_g_switch_chan(mac, 6, 1);
2434 		bwn_phy_g_switch_chan(mac, channel, 0);
2435 		return;
2436 	}
2437 
2438 	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2439 	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2440 	pg->pg_radioctx_over = rfover;
2441 	pg->pg_radioctx_overval = rfoverval;
2442 	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2443 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2444 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2445 }
2446 
2447 static int
2448 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2449 {
2450 
2451 	if ((newchan < 1) || (newchan > 14))
2452 		return (EINVAL);
2453 	bwn_phy_g_switch_chan(mac, newchan, 0);
2454 
2455 	return (0);
2456 }
2457 
2458 static uint32_t
2459 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2460 {
2461 
2462 	return (1);
2463 }
2464 
2465 static void
2466 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2467 {
2468 	struct bwn_phy *phy = &mac->mac_phy;
2469 	uint64_t hf;
2470 	int autodiv = 0;
2471 	uint16_t tmp;
2472 
2473 	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2474 		autodiv = 1;
2475 
2476 	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2477 	bwn_hf_write(mac, hf);
2478 
2479 	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2480 	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2481 	    ((autodiv ? BWN_ANTAUTO1 : antenna)
2482 		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
2483 
2484 	if (autodiv) {
2485 		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2486 		if (antenna == BWN_ANTAUTO1)
2487 			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2488 		else
2489 			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2490 		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2491 	}
2492 	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2493 	if (autodiv)
2494 		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2495 	else
2496 		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2497 	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2498 	if (phy->rev >= 2) {
2499 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2500 		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2501 		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2502 		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2503 		    0x15);
2504 		if (phy->rev == 2)
2505 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2506 		else
2507 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2508 			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2509 			    8);
2510 	}
2511 	if (phy->rev >= 6)
2512 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2513 
2514 	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2515 	bwn_hf_write(mac, hf);
2516 }
2517 
2518 static int
2519 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2520 {
2521 	struct bwn_phy *phy = &mac->mac_phy;
2522 	struct bwn_phy_g *pg = &phy->phy_g;
2523 
2524 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2525 	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2526 
2527 	if (phy->rev == 0 || !phy->gmode)
2528 		return (ENODEV);
2529 
2530 	pg->pg_aci_wlan_automatic = 0;
2531 	return (0);
2532 }
2533 
2534 static int
2535 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2536 {
2537 	struct bwn_phy *phy = &mac->mac_phy;
2538 	struct bwn_phy_g *pg = &phy->phy_g;
2539 	struct bwn_softc *sc = mac->mac_sc;
2540 	unsigned int tssi;
2541 	int cck, ofdm;
2542 	int power;
2543 	int rfatt, bbatt;
2544 	unsigned int max;
2545 
2546 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2547 
2548 	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2549 	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2550 	if (cck < 0 && ofdm < 0) {
2551 		if (ignore_tssi == 0)
2552 			return (BWN_TXPWR_RES_DONE);
2553 		cck = 0;
2554 		ofdm = 0;
2555 	}
2556 	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2557 	if (pg->pg_avgtssi != 0xff)
2558 		tssi = (tssi + pg->pg_avgtssi) / 2;
2559 	pg->pg_avgtssi = tssi;
2560 	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2561 
2562 	max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2563 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2564 		max -= 3;
2565 	if (max >= 120) {
2566 		device_printf(sc->sc_dev, "invalid max TX-power value\n");
2567 		max = 80;
2568 		siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2569 	}
2570 
2571 	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2572 	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2573 	     tssi, 0x00), 0x3f)]);
2574 	if (power == 0)
2575 		return (BWN_TXPWR_RES_DONE);
2576 
2577 	rfatt = -((power + 7) / 8);
2578 	bbatt = (-(power / 2)) - (4 * rfatt);
2579 	if ((rfatt == 0) && (bbatt == 0))
2580 		return (BWN_TXPWR_RES_DONE);
2581 	pg->pg_bbatt_delta = bbatt;
2582 	pg->pg_rfatt_delta = rfatt;
2583 	return (BWN_TXPWR_RES_NEED_ADJUST);
2584 }
2585 
2586 static void
2587 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2588 {
2589 	struct bwn_phy *phy = &mac->mac_phy;
2590 	struct bwn_phy_g *pg = &phy->phy_g;
2591 	struct bwn_softc *sc = mac->mac_sc;
2592 	int rfatt, bbatt;
2593 	uint8_t txctl;
2594 
2595 	bwn_mac_suspend(mac);
2596 
2597 	BWN_ASSERT_LOCKED(sc);
2598 
2599 	bbatt = pg->pg_bbatt.att;
2600 	bbatt += pg->pg_bbatt_delta;
2601 	rfatt = pg->pg_rfatt.att;
2602 	rfatt += pg->pg_rfatt_delta;
2603 
2604 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2605 	txctl = pg->pg_txctl;
2606 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2607 		if (rfatt <= 1) {
2608 			if (txctl == 0) {
2609 				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2610 				rfatt += 2;
2611 				bbatt += 2;
2612 			} else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2613 			    BWN_BFL_PACTRL) {
2614 				bbatt += 4 * (rfatt - 2);
2615 				rfatt = 2;
2616 			}
2617 		} else if (rfatt > 4 && txctl) {
2618 			txctl = 0;
2619 			if (bbatt < 3) {
2620 				rfatt -= 3;
2621 				bbatt += 2;
2622 			} else {
2623 				rfatt -= 2;
2624 				bbatt -= 2;
2625 			}
2626 		}
2627 	}
2628 	pg->pg_txctl = txctl;
2629 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2630 	pg->pg_rfatt.att = rfatt;
2631 	pg->pg_bbatt.att = bbatt;
2632 
2633 	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2634 
2635 	bwn_phy_lock(mac);
2636 	bwn_rf_lock(mac);
2637 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2638 	    pg->pg_txctl);
2639 	bwn_rf_unlock(mac);
2640 	bwn_phy_unlock(mac);
2641 
2642 	bwn_mac_enable(mac);
2643 }
2644 
2645 static void
2646 bwn_phy_g_task_15s(struct bwn_mac *mac)
2647 {
2648 	struct bwn_phy *phy = &mac->mac_phy;
2649 	struct bwn_phy_g *pg = &phy->phy_g;
2650 	struct bwn_softc *sc = mac->mac_sc;
2651 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2652 	unsigned long expire, now;
2653 	struct bwn_lo_calib *cal, *tmp;
2654 	uint8_t expired = 0;
2655 
2656 	bwn_mac_suspend(mac);
2657 
2658 	if (lo == NULL)
2659 		goto fail;
2660 
2661 	BWN_GETTIME(now);
2662 	if (bwn_has_hwpctl(mac)) {
2663 		expire = now - BWN_LO_PWRVEC_EXPIRE;
2664 		if (time_before(lo->pwr_vec_read_time, expire)) {
2665 			bwn_lo_get_powervector(mac);
2666 			bwn_phy_g_dc_lookup_init(mac, 0);
2667 		}
2668 		goto fail;
2669 	}
2670 
2671 	expire = now - BWN_LO_CALIB_EXPIRE;
2672 	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2673 		if (!time_before(cal->calib_time, expire))
2674 			continue;
2675 		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2676 		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2677 			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2678 			expired = 1;
2679 		}
2680 
2681 		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2682 		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2683 		    cal->ctl.i, cal->ctl.q);
2684 
2685 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2686 		free(cal, M_DEVBUF);
2687 	}
2688 	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2689 		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2690 		    &pg->pg_rfatt);
2691 		if (cal == NULL) {
2692 			device_printf(sc->sc_dev,
2693 			    "failed to recalibrate LO\n");
2694 			goto fail;
2695 		}
2696 		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2697 		bwn_lo_write(mac, &cal->ctl);
2698 	}
2699 
2700 fail:
2701 	bwn_mac_enable(mac);
2702 }
2703 
2704 static void
2705 bwn_phy_g_task_60s(struct bwn_mac *mac)
2706 {
2707 	struct bwn_phy *phy = &mac->mac_phy;
2708 	struct bwn_softc *sc = mac->mac_sc;
2709 	uint8_t old = phy->chan;
2710 
2711 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2712 		return;
2713 
2714 	bwn_mac_suspend(mac);
2715 	bwn_nrssi_slope_11g(mac);
2716 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2717 		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2718 		bwn_switch_channel(mac, old);
2719 	}
2720 	bwn_mac_enable(mac);
2721 }
2722 
2723 static void
2724 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2725 {
2726 
2727 	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2728 }
2729 
2730 static int
2731 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2732 	const struct ieee80211_bpf_params *params)
2733 {
2734 	struct ieee80211com *ic = ni->ni_ic;
2735 	struct ifnet *ifp = ic->ic_ifp;
2736 	struct bwn_softc *sc = ifp->if_softc;
2737 	struct bwn_mac *mac = sc->sc_curmac;
2738 
2739 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2740 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
2741 		ieee80211_free_node(ni);
2742 		m_freem(m);
2743 		return (ENETDOWN);
2744 	}
2745 
2746 	BWN_LOCK(sc);
2747 	if (bwn_tx_isfull(sc, m)) {
2748 		ieee80211_free_node(ni);
2749 		m_freem(m);
2750 		ifp->if_oerrors++;
2751 		BWN_UNLOCK(sc);
2752 		return (ENOBUFS);
2753 	}
2754 
2755 	if (bwn_tx_start(sc, ni, m) != 0) {
2756 		if (ni != NULL)
2757 			ieee80211_free_node(ni);
2758 		ifp->if_oerrors++;
2759 	}
2760 	sc->sc_watchdog_timer = 5;
2761 	BWN_UNLOCK(sc);
2762 	return (0);
2763 }
2764 
2765 /*
2766  * Callback from the 802.11 layer to update the slot time
2767  * based on the current setting.  We use it to notify the
2768  * firmware of ERP changes and the f/w takes care of things
2769  * like slot time and preamble.
2770  */
2771 static void
2772 bwn_updateslot(struct ifnet *ifp)
2773 {
2774 	struct bwn_softc *sc = ifp->if_softc;
2775 	struct ieee80211com *ic = ifp->if_l2com;
2776 	struct bwn_mac *mac;
2777 
2778 	BWN_LOCK(sc);
2779 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2780 		mac = (struct bwn_mac *)sc->sc_curmac;
2781 		bwn_set_slot_time(mac,
2782 		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2783 	}
2784 	BWN_UNLOCK(sc);
2785 }
2786 
2787 /*
2788  * Callback from the 802.11 layer after a promiscuous mode change.
2789  * Note this interface does not check the operating mode as this
2790  * is an internal callback and we are expected to honor the current
2791  * state (e.g. this is used for setting the interface in promiscuous
2792  * mode when operating in hostap mode to do ACS).
2793  */
2794 static void
2795 bwn_update_promisc(struct ifnet *ifp)
2796 {
2797 	struct bwn_softc *sc = ifp->if_softc;
2798 	struct bwn_mac *mac = sc->sc_curmac;
2799 
2800 	BWN_LOCK(sc);
2801 	mac = sc->sc_curmac;
2802 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2803 		if (ifp->if_flags & IFF_PROMISC)
2804 			sc->sc_filters |= BWN_MACCTL_PROMISC;
2805 		else
2806 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2807 		bwn_set_opmode(mac);
2808 	}
2809 	BWN_UNLOCK(sc);
2810 }
2811 
2812 /*
2813  * Callback from the 802.11 layer to update WME parameters.
2814  */
2815 static int
2816 bwn_wme_update(struct ieee80211com *ic)
2817 {
2818 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2819 	struct bwn_mac *mac = sc->sc_curmac;
2820 	struct wmeParams *wmep;
2821 	int i;
2822 
2823 	BWN_LOCK(sc);
2824 	mac = sc->sc_curmac;
2825 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2826 		bwn_mac_suspend(mac);
2827 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
2828 			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2829 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2830 		}
2831 		bwn_mac_enable(mac);
2832 	}
2833 	BWN_UNLOCK(sc);
2834 	return (0);
2835 }
2836 
2837 static void
2838 bwn_scan_start(struct ieee80211com *ic)
2839 {
2840 	struct ifnet *ifp = ic->ic_ifp;
2841 	struct bwn_softc *sc = ifp->if_softc;
2842 	struct bwn_mac *mac;
2843 
2844 	BWN_LOCK(sc);
2845 	mac = sc->sc_curmac;
2846 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847 		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2848 		bwn_set_opmode(mac);
2849 		/* disable CFP update during scan */
2850 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2851 	}
2852 	BWN_UNLOCK(sc);
2853 }
2854 
2855 static void
2856 bwn_scan_end(struct ieee80211com *ic)
2857 {
2858 	struct ifnet *ifp = ic->ic_ifp;
2859 	struct bwn_softc *sc = ifp->if_softc;
2860 	struct bwn_mac *mac;
2861 
2862 	BWN_LOCK(sc);
2863 	mac = sc->sc_curmac;
2864 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2865 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2866 		bwn_set_opmode(mac);
2867 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2868 	}
2869 	BWN_UNLOCK(sc);
2870 }
2871 
2872 static void
2873 bwn_set_channel(struct ieee80211com *ic)
2874 {
2875 	struct ifnet *ifp = ic->ic_ifp;
2876 	struct bwn_softc *sc = ifp->if_softc;
2877 	struct bwn_mac *mac = sc->sc_curmac;
2878 	struct bwn_phy *phy = &mac->mac_phy;
2879 	int chan, error;
2880 
2881 	BWN_LOCK(sc);
2882 
2883 	error = bwn_switch_band(sc, ic->ic_curchan);
2884 	if (error)
2885 		goto fail;;
2886 	bwn_mac_suspend(mac);
2887 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2888 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2889 	if (chan != phy->chan)
2890 		bwn_switch_channel(mac, chan);
2891 
2892 	/* TX power level */
2893 	if (ic->ic_curchan->ic_maxpower != 0 &&
2894 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
2895 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2896 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2897 		    BWN_TXPWR_IGNORE_TSSI);
2898 	}
2899 
2900 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2901 	if (phy->set_antenna)
2902 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2903 
2904 	if (sc->sc_rf_enabled != phy->rf_on) {
2905 		if (sc->sc_rf_enabled) {
2906 			bwn_rf_turnon(mac);
2907 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2908 				device_printf(sc->sc_dev,
2909 				    "please turns on the RF switch\n");
2910 		} else
2911 			bwn_rf_turnoff(mac);
2912 	}
2913 
2914 	bwn_mac_enable(mac);
2915 
2916 fail:
2917 	/*
2918 	 * Setup radio tap channel freq and flags
2919 	 */
2920 	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2921 		htole16(ic->ic_curchan->ic_freq);
2922 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2923 		htole16(ic->ic_curchan->ic_flags & 0xffff);
2924 
2925 	BWN_UNLOCK(sc);
2926 }
2927 
2928 static struct ieee80211vap *
2929 bwn_vap_create(struct ieee80211com *ic,
2930 	const char name[IFNAMSIZ], int unit, int opmode, int flags,
2931 	const uint8_t bssid[IEEE80211_ADDR_LEN],
2932 	const uint8_t mac0[IEEE80211_ADDR_LEN])
2933 {
2934 	struct ifnet *ifp = ic->ic_ifp;
2935 	struct bwn_softc *sc = ifp->if_softc;
2936 	struct ieee80211vap *vap;
2937 	struct bwn_vap *bvp;
2938 	uint8_t mac[IEEE80211_ADDR_LEN];
2939 
2940 	IEEE80211_ADDR_COPY(mac, mac0);
2941 	switch (opmode) {
2942 	case IEEE80211_M_HOSTAP:
2943 	case IEEE80211_M_MBSS:
2944 	case IEEE80211_M_STA:
2945 	case IEEE80211_M_WDS:
2946 	case IEEE80211_M_MONITOR:
2947 	case IEEE80211_M_IBSS:
2948 	case IEEE80211_M_AHDEMO:
2949 		break;
2950 	default:
2951 		return (NULL);
2952 	}
2953 
2954 	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2955 
2956 	bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2957 	    M_80211_VAP, M_NOWAIT | M_ZERO);
2958 	if (bvp == NULL) {
2959 		device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2960 		return (NULL);
2961 	}
2962 	vap = &bvp->bv_vap;
2963 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2964 	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2965 	/* override with driver methods */
2966 	bvp->bv_newstate = vap->iv_newstate;
2967 	vap->iv_newstate = bwn_newstate;
2968 
2969 	/* override max aid so sta's cannot assoc when we're out of sta id's */
2970 	vap->iv_max_aid = BWN_STAID_MAX;
2971 
2972 	ieee80211_ratectl_init(vap);
2973 
2974 	/* complete setup */
2975 	ieee80211_vap_attach(vap, ieee80211_media_change,
2976 	    ieee80211_media_status);
2977 	return (vap);
2978 }
2979 
2980 static void
2981 bwn_vap_delete(struct ieee80211vap *vap)
2982 {
2983 	struct bwn_vap *bvp = BWN_VAP(vap);
2984 
2985 	ieee80211_ratectl_deinit(vap);
2986 	ieee80211_vap_detach(vap);
2987 	free(bvp, M_80211_VAP);
2988 }
2989 
2990 static void
2991 bwn_init(void *arg)
2992 {
2993 	struct bwn_softc *sc = arg;
2994 	struct ifnet *ifp = sc->sc_ifp;
2995 	struct ieee80211com *ic = ifp->if_l2com;
2996 	int error = 0;
2997 
2998 	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2999 		__func__, ifp->if_flags);
3000 
3001 	BWN_LOCK(sc);
3002 	error = bwn_init_locked(sc);
3003 	BWN_UNLOCK(sc);
3004 
3005 	if (error == 0)
3006 		ieee80211_start_all(ic);	/* start all vap's */
3007 }
3008 
3009 static int
3010 bwn_init_locked(struct bwn_softc *sc)
3011 {
3012 	struct bwn_mac *mac;
3013 	struct ifnet *ifp = sc->sc_ifp;
3014 	int error;
3015 
3016 	BWN_ASSERT_LOCKED(sc);
3017 
3018 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3019 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3020 	sc->sc_filters = 0;
3021 	bwn_wme_clear(sc);
3022 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3023 	sc->sc_rf_enabled = 1;
3024 
3025 	mac = sc->sc_curmac;
3026 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3027 		error = bwn_core_init(mac);
3028 		if (error != 0)
3029 			return (error);
3030 	}
3031 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
3032 		bwn_core_start(mac);
3033 
3034 	bwn_set_opmode(mac);
3035 	bwn_set_pretbtt(mac);
3036 	bwn_spu_setdelay(mac, 0);
3037 	bwn_set_macaddr(mac);
3038 
3039 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
3040 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3041 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3042 
3043 	return (0);
3044 }
3045 
3046 static void
3047 bwn_stop(struct bwn_softc *sc, int statechg)
3048 {
3049 
3050 	BWN_LOCK(sc);
3051 	bwn_stop_locked(sc, statechg);
3052 	BWN_UNLOCK(sc);
3053 }
3054 
3055 static void
3056 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3057 {
3058 	struct bwn_mac *mac = sc->sc_curmac;
3059 	struct ifnet *ifp = sc->sc_ifp;
3060 
3061 	BWN_ASSERT_LOCKED(sc);
3062 
3063 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3064 		/* XXX FIXME opmode not based on VAP */
3065 		bwn_set_opmode(mac);
3066 		bwn_set_macaddr(mac);
3067 	}
3068 
3069 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3070 		bwn_core_stop(mac);
3071 
3072 	callout_stop(&sc->sc_led_blink_ch);
3073 	sc->sc_led_blinking = 0;
3074 
3075 	bwn_core_exit(mac);
3076 	sc->sc_rf_enabled = 0;
3077 
3078 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3079 }
3080 
3081 static void
3082 bwn_wme_clear(struct bwn_softc *sc)
3083 {
3084 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
3085 	struct wmeParams *p;
3086 	unsigned int i;
3087 
3088 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3089 	    ("%s:%d: fail", __func__, __LINE__));
3090 
3091 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
3092 		p = &(sc->sc_wmeParams[i]);
3093 
3094 		switch (bwn_wme_shm_offsets[i]) {
3095 		case BWN_WME_VOICE:
3096 			p->wmep_txopLimit = 0;
3097 			p->wmep_aifsn = 2;
3098 			/* XXX FIXME: log2(cwmin) */
3099 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3100 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3101 			break;
3102 		case BWN_WME_VIDEO:
3103 			p->wmep_txopLimit = 0;
3104 			p->wmep_aifsn = 2;
3105 			/* XXX FIXME: log2(cwmin) */
3106 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3107 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3108 			break;
3109 		case BWN_WME_BESTEFFORT:
3110 			p->wmep_txopLimit = 0;
3111 			p->wmep_aifsn = 3;
3112 			/* XXX FIXME: log2(cwmin) */
3113 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3114 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3115 			break;
3116 		case BWN_WME_BACKGROUND:
3117 			p->wmep_txopLimit = 0;
3118 			p->wmep_aifsn = 7;
3119 			/* XXX FIXME: log2(cwmin) */
3120 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3121 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3122 			break;
3123 		default:
3124 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3125 		}
3126 	}
3127 }
3128 
3129 static int
3130 bwn_core_init(struct bwn_mac *mac)
3131 {
3132 	struct bwn_softc *sc = mac->mac_sc;
3133 	uint64_t hf;
3134 	int error;
3135 
3136 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3137 	    ("%s:%d: fail", __func__, __LINE__));
3138 
3139 	siba_powerup(sc->sc_dev, 0);
3140 	if (!siba_dev_isup(sc->sc_dev))
3141 		bwn_reset_core(mac,
3142 		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3143 
3144 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3145 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3146 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3147 	BWN_GETTIME(mac->mac_phy.nexttime);
3148 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3149 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3150 	mac->mac_stats.link_noise = -95;
3151 	mac->mac_reason_intr = 0;
3152 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
3153 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3154 #ifdef BWN_DEBUG
3155 	if (sc->sc_debug & BWN_DEBUG_XMIT)
3156 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3157 #endif
3158 	mac->mac_suspended = 1;
3159 	mac->mac_task_state = 0;
3160 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3161 
3162 	mac->mac_phy.init_pre(mac);
3163 
3164 	siba_pcicore_intr(sc->sc_dev);
3165 
3166 	siba_fix_imcfglobug(sc->sc_dev);
3167 	bwn_bt_disable(mac);
3168 	if (mac->mac_phy.prepare_hw) {
3169 		error = mac->mac_phy.prepare_hw(mac);
3170 		if (error)
3171 			goto fail0;
3172 	}
3173 	error = bwn_chip_init(mac);
3174 	if (error)
3175 		goto fail0;
3176 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3177 	    siba_get_revid(sc->sc_dev));
3178 	hf = bwn_hf_read(mac);
3179 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3180 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3181 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3182 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3183 		if (mac->mac_phy.rev == 1)
3184 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3185 	}
3186 	if (mac->mac_phy.rf_ver == 0x2050) {
3187 		if (mac->mac_phy.rf_rev < 6)
3188 			hf |= BWN_HF_FORCE_VCO_RECALC;
3189 		if (mac->mac_phy.rf_rev == 6)
3190 			hf |= BWN_HF_4318_TSSI;
3191 	}
3192 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3193 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3194 	if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3195 	    (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3196 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3197 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3198 	bwn_hf_write(mac, hf);
3199 
3200 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3201 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3202 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3203 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3204 
3205 	bwn_rate_init(mac);
3206 	bwn_set_phytxctl(mac);
3207 
3208 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3209 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3210 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3211 
3212 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3213 		bwn_pio_init(mac);
3214 	else
3215 		bwn_dma_init(mac);
3216 	if (error)
3217 		goto fail1;
3218 	bwn_wme_init(mac);
3219 	bwn_spu_setdelay(mac, 1);
3220 	bwn_bt_enable(mac);
3221 
3222 	siba_powerup(sc->sc_dev,
3223 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3224 	bwn_set_macaddr(mac);
3225 	bwn_crypt_init(mac);
3226 
3227 	/* XXX LED initializatin */
3228 
3229 	mac->mac_status = BWN_MAC_STATUS_INITED;
3230 
3231 	return (error);
3232 
3233 fail1:
3234 	bwn_chip_exit(mac);
3235 fail0:
3236 	siba_powerdown(sc->sc_dev);
3237 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3238 	    ("%s:%d: fail", __func__, __LINE__));
3239 	return (error);
3240 }
3241 
3242 static void
3243 bwn_core_start(struct bwn_mac *mac)
3244 {
3245 	struct bwn_softc *sc = mac->mac_sc;
3246 	uint32_t tmp;
3247 
3248 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3249 	    ("%s:%d: fail", __func__, __LINE__));
3250 
3251 	if (siba_get_revid(sc->sc_dev) < 5)
3252 		return;
3253 
3254 	while (1) {
3255 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3256 		if (!(tmp & 0x00000001))
3257 			break;
3258 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3259 	}
3260 
3261 	bwn_mac_enable(mac);
3262 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3263 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3264 
3265 	mac->mac_status = BWN_MAC_STATUS_STARTED;
3266 }
3267 
3268 static void
3269 bwn_core_exit(struct bwn_mac *mac)
3270 {
3271 	struct bwn_softc *sc = mac->mac_sc;
3272 	uint32_t macctl;
3273 
3274 	BWN_ASSERT_LOCKED(mac->mac_sc);
3275 
3276 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3277 	    ("%s:%d: fail", __func__, __LINE__));
3278 
3279 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
3280 		return;
3281 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
3282 
3283 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3284 	macctl &= ~BWN_MACCTL_MCODE_RUN;
3285 	macctl |= BWN_MACCTL_MCODE_JMP0;
3286 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3287 
3288 	bwn_dma_stop(mac);
3289 	bwn_pio_stop(mac);
3290 	bwn_chip_exit(mac);
3291 	mac->mac_phy.switch_analog(mac, 0);
3292 	siba_dev_down(sc->sc_dev, 0);
3293 	siba_powerdown(sc->sc_dev);
3294 }
3295 
3296 static void
3297 bwn_bt_disable(struct bwn_mac *mac)
3298 {
3299 	struct bwn_softc *sc = mac->mac_sc;
3300 
3301 	(void)sc;
3302 	/* XXX do nothing yet */
3303 }
3304 
3305 static int
3306 bwn_chip_init(struct bwn_mac *mac)
3307 {
3308 	struct bwn_softc *sc = mac->mac_sc;
3309 	struct bwn_phy *phy = &mac->mac_phy;
3310 	uint32_t macctl;
3311 	int error;
3312 
3313 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3314 	if (phy->gmode)
3315 		macctl |= BWN_MACCTL_GMODE;
3316 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3317 
3318 	error = bwn_fw_fillinfo(mac);
3319 	if (error)
3320 		return (error);
3321 	error = bwn_fw_loaducode(mac);
3322 	if (error)
3323 		return (error);
3324 
3325 	error = bwn_gpio_init(mac);
3326 	if (error)
3327 		return (error);
3328 
3329 	error = bwn_fw_loadinitvals(mac);
3330 	if (error) {
3331 		siba_gpio_set(sc->sc_dev, 0);
3332 		return (error);
3333 	}
3334 	phy->switch_analog(mac, 1);
3335 	error = bwn_phy_init(mac);
3336 	if (error) {
3337 		siba_gpio_set(sc->sc_dev, 0);
3338 		return (error);
3339 	}
3340 	if (phy->set_im)
3341 		phy->set_im(mac, BWN_IMMODE_NONE);
3342 	if (phy->set_antenna)
3343 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
3344 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3345 
3346 	if (phy->type == BWN_PHYTYPE_B)
3347 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3348 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
3349 	if (siba_get_revid(sc->sc_dev) < 5)
3350 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
3351 
3352 	BWN_WRITE_4(mac, BWN_MACCTL,
3353 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3354 	BWN_WRITE_4(mac, BWN_MACCTL,
3355 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3356 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3357 
3358 	bwn_set_opmode(mac);
3359 	if (siba_get_revid(sc->sc_dev) < 3) {
3360 		BWN_WRITE_2(mac, 0x060e, 0x0000);
3361 		BWN_WRITE_2(mac, 0x0610, 0x8000);
3362 		BWN_WRITE_2(mac, 0x0604, 0x0000);
3363 		BWN_WRITE_2(mac, 0x0606, 0x0200);
3364 	} else {
3365 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
3366 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
3367 	}
3368 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3369 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3370 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3371 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3372 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3373 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3374 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3375 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3376 	    siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3377 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3378 	return (error);
3379 }
3380 
3381 /* read hostflags */
3382 static uint64_t
3383 bwn_hf_read(struct bwn_mac *mac)
3384 {
3385 	uint64_t ret;
3386 
3387 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3388 	ret <<= 16;
3389 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3390 	ret <<= 16;
3391 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3392 	return (ret);
3393 }
3394 
3395 static void
3396 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3397 {
3398 
3399 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3400 	    (value & 0x00000000ffffull));
3401 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3402 	    (value & 0x0000ffff0000ull) >> 16);
3403 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3404 	    (value & 0xffff00000000ULL) >> 32);
3405 }
3406 
3407 static void
3408 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3409 {
3410 
3411 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3412 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3413 }
3414 
3415 static void
3416 bwn_rate_init(struct bwn_mac *mac)
3417 {
3418 
3419 	switch (mac->mac_phy.type) {
3420 	case BWN_PHYTYPE_A:
3421 	case BWN_PHYTYPE_G:
3422 	case BWN_PHYTYPE_LP:
3423 	case BWN_PHYTYPE_N:
3424 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3425 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3426 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3427 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3428 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3429 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3430 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3431 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
3432 			break;
3433 		/* FALLTHROUGH */
3434 	case BWN_PHYTYPE_B:
3435 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3436 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3437 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3438 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3439 		break;
3440 	default:
3441 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3442 	}
3443 }
3444 
3445 static void
3446 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3447 {
3448 	uint16_t offset;
3449 
3450 	if (ofdm) {
3451 		offset = 0x480;
3452 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3453 	} else {
3454 		offset = 0x4c0;
3455 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3456 	}
3457 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3458 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
3459 }
3460 
3461 static uint8_t
3462 bwn_plcp_getcck(const uint8_t bitrate)
3463 {
3464 
3465 	switch (bitrate) {
3466 	case BWN_CCK_RATE_1MB:
3467 		return (0x0a);
3468 	case BWN_CCK_RATE_2MB:
3469 		return (0x14);
3470 	case BWN_CCK_RATE_5MB:
3471 		return (0x37);
3472 	case BWN_CCK_RATE_11MB:
3473 		return (0x6e);
3474 	}
3475 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3476 	return (0);
3477 }
3478 
3479 static uint8_t
3480 bwn_plcp_getofdm(const uint8_t bitrate)
3481 {
3482 
3483 	switch (bitrate) {
3484 	case BWN_OFDM_RATE_6MB:
3485 		return (0xb);
3486 	case BWN_OFDM_RATE_9MB:
3487 		return (0xf);
3488 	case BWN_OFDM_RATE_12MB:
3489 		return (0xa);
3490 	case BWN_OFDM_RATE_18MB:
3491 		return (0xe);
3492 	case BWN_OFDM_RATE_24MB:
3493 		return (0x9);
3494 	case BWN_OFDM_RATE_36MB:
3495 		return (0xd);
3496 	case BWN_OFDM_RATE_48MB:
3497 		return (0x8);
3498 	case BWN_OFDM_RATE_54MB:
3499 		return (0xc);
3500 	}
3501 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3502 	return (0);
3503 }
3504 
3505 static void
3506 bwn_set_phytxctl(struct bwn_mac *mac)
3507 {
3508 	uint16_t ctl;
3509 
3510 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3511 	    BWN_TX_PHY_TXPWR);
3512 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3513 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3514 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3515 }
3516 
3517 static void
3518 bwn_pio_init(struct bwn_mac *mac)
3519 {
3520 	struct bwn_pio *pio = &mac->mac_method.pio;
3521 
3522 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3523 	    & ~BWN_MACCTL_BIGENDIAN);
3524 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3525 
3526 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3527 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3528 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3529 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3530 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3531 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3532 }
3533 
3534 static void
3535 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3536     int index)
3537 {
3538 	struct bwn_pio_txpkt *tp;
3539 	struct bwn_softc *sc = mac->mac_sc;
3540 	unsigned int i;
3541 
3542 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3543 	tq->tq_index = index;
3544 
3545 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3546 	if (siba_get_revid(sc->sc_dev) >= 8)
3547 		tq->tq_size = 1920;
3548 	else {
3549 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3550 		tq->tq_size -= 80;
3551 	}
3552 
3553 	TAILQ_INIT(&tq->tq_pktlist);
3554 	for (i = 0; i < N(tq->tq_pkts); i++) {
3555 		tp = &(tq->tq_pkts[i]);
3556 		tp->tp_index = i;
3557 		tp->tp_queue = tq;
3558 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3559 	}
3560 }
3561 
3562 static uint16_t
3563 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3564 {
3565 	struct bwn_softc *sc = mac->mac_sc;
3566 	static const uint16_t bases[] = {
3567 		BWN_PIO_BASE0,
3568 		BWN_PIO_BASE1,
3569 		BWN_PIO_BASE2,
3570 		BWN_PIO_BASE3,
3571 		BWN_PIO_BASE4,
3572 		BWN_PIO_BASE5,
3573 		BWN_PIO_BASE6,
3574 		BWN_PIO_BASE7,
3575 	};
3576 	static const uint16_t bases_rev11[] = {
3577 		BWN_PIO11_BASE0,
3578 		BWN_PIO11_BASE1,
3579 		BWN_PIO11_BASE2,
3580 		BWN_PIO11_BASE3,
3581 		BWN_PIO11_BASE4,
3582 		BWN_PIO11_BASE5,
3583 	};
3584 
3585 	if (siba_get_revid(sc->sc_dev) >= 11) {
3586 		if (index >= N(bases_rev11))
3587 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
3588 		return (bases_rev11[index]);
3589 	}
3590 	if (index >= N(bases))
3591 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
3592 	return (bases[index]);
3593 }
3594 
3595 static void
3596 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3597     int index)
3598 {
3599 	struct bwn_softc *sc = mac->mac_sc;
3600 
3601 	prq->prq_mac = mac;
3602 	prq->prq_rev = siba_get_revid(sc->sc_dev);
3603 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3604 	bwn_dma_rxdirectfifo(mac, index, 1);
3605 }
3606 
3607 static void
3608 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3609 {
3610 	if (tq == NULL)
3611 		return;
3612 	bwn_pio_cancel_tx_packets(tq);
3613 }
3614 
3615 static void
3616 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3617 {
3618 
3619 	bwn_destroy_pioqueue_tx(pio);
3620 }
3621 
3622 static uint16_t
3623 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3624     uint16_t offset)
3625 {
3626 
3627 	return (BWN_READ_2(mac, tq->tq_base + offset));
3628 }
3629 
3630 static void
3631 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3632 {
3633 	uint32_t ctl;
3634 	int type;
3635 	uint16_t base;
3636 
3637 	type = bwn_dma_mask2type(bwn_dma_mask(mac));
3638 	base = bwn_dma_base(type, idx);
3639 	if (type == BWN_DMA_64BIT) {
3640 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3641 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3642 		if (enable)
3643 			ctl |= BWN_DMA64_RXDIRECTFIFO;
3644 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3645 	} else {
3646 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3647 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3648 		if (enable)
3649 			ctl |= BWN_DMA32_RXDIRECTFIFO;
3650 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3651 	}
3652 }
3653 
3654 static uint64_t
3655 bwn_dma_mask(struct bwn_mac *mac)
3656 {
3657 	uint32_t tmp;
3658 	uint16_t base;
3659 
3660 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3661 	if (tmp & SIBA_TGSHIGH_DMA64)
3662 		return (BWN_DMA_BIT_MASK(64));
3663 	base = bwn_dma_base(0, 0);
3664 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3665 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3666 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
3667 		return (BWN_DMA_BIT_MASK(32));
3668 
3669 	return (BWN_DMA_BIT_MASK(30));
3670 }
3671 
3672 static int
3673 bwn_dma_mask2type(uint64_t dmamask)
3674 {
3675 
3676 	if (dmamask == BWN_DMA_BIT_MASK(30))
3677 		return (BWN_DMA_30BIT);
3678 	if (dmamask == BWN_DMA_BIT_MASK(32))
3679 		return (BWN_DMA_32BIT);
3680 	if (dmamask == BWN_DMA_BIT_MASK(64))
3681 		return (BWN_DMA_64BIT);
3682 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3683 	return (BWN_DMA_30BIT);
3684 }
3685 
3686 static void
3687 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3688 {
3689 	struct bwn_pio_txpkt *tp;
3690 	unsigned int i;
3691 
3692 	for (i = 0; i < N(tq->tq_pkts); i++) {
3693 		tp = &(tq->tq_pkts[i]);
3694 		if (tp->tp_m) {
3695 			m_freem(tp->tp_m);
3696 			tp->tp_m = NULL;
3697 		}
3698 	}
3699 }
3700 
3701 static uint16_t
3702 bwn_dma_base(int type, int controller_idx)
3703 {
3704 	static const uint16_t map64[] = {
3705 		BWN_DMA64_BASE0,
3706 		BWN_DMA64_BASE1,
3707 		BWN_DMA64_BASE2,
3708 		BWN_DMA64_BASE3,
3709 		BWN_DMA64_BASE4,
3710 		BWN_DMA64_BASE5,
3711 	};
3712 	static const uint16_t map32[] = {
3713 		BWN_DMA32_BASE0,
3714 		BWN_DMA32_BASE1,
3715 		BWN_DMA32_BASE2,
3716 		BWN_DMA32_BASE3,
3717 		BWN_DMA32_BASE4,
3718 		BWN_DMA32_BASE5,
3719 	};
3720 
3721 	if (type == BWN_DMA_64BIT) {
3722 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3723 		    ("%s:%d: fail", __func__, __LINE__));
3724 		return (map64[controller_idx]);
3725 	}
3726 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3727 	    ("%s:%d: fail", __func__, __LINE__));
3728 	return (map32[controller_idx]);
3729 }
3730 
3731 static void
3732 bwn_dma_init(struct bwn_mac *mac)
3733 {
3734 	struct bwn_dma *dma = &mac->mac_method.dma;
3735 
3736 	/* setup TX DMA channels. */
3737 	bwn_dma_setup(dma->wme[WME_AC_BK]);
3738 	bwn_dma_setup(dma->wme[WME_AC_BE]);
3739 	bwn_dma_setup(dma->wme[WME_AC_VI]);
3740 	bwn_dma_setup(dma->wme[WME_AC_VO]);
3741 	bwn_dma_setup(dma->mcast);
3742 	/* setup RX DMA channel. */
3743 	bwn_dma_setup(dma->rx);
3744 }
3745 
3746 static struct bwn_dma_ring *
3747 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3748     int for_tx, int type)
3749 {
3750 	struct bwn_dma *dma = &mac->mac_method.dma;
3751 	struct bwn_dma_ring *dr;
3752 	struct bwn_dmadesc_generic *desc;
3753 	struct bwn_dmadesc_meta *mt;
3754 	struct bwn_softc *sc = mac->mac_sc;
3755 	int error, i;
3756 
3757 	dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3758 	if (dr == NULL)
3759 		goto out;
3760 	dr->dr_numslots = BWN_RXRING_SLOTS;
3761 	if (for_tx)
3762 		dr->dr_numslots = BWN_TXRING_SLOTS;
3763 
3764 	dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3765 	    M_DEVBUF, M_NOWAIT | M_ZERO);
3766 	if (dr->dr_meta == NULL)
3767 		goto fail0;
3768 
3769 	dr->dr_type = type;
3770 	dr->dr_mac = mac;
3771 	dr->dr_base = bwn_dma_base(type, controller_index);
3772 	dr->dr_index = controller_index;
3773 	if (type == BWN_DMA_64BIT) {
3774 		dr->getdesc = bwn_dma_64_getdesc;
3775 		dr->setdesc = bwn_dma_64_setdesc;
3776 		dr->start_transfer = bwn_dma_64_start_transfer;
3777 		dr->suspend = bwn_dma_64_suspend;
3778 		dr->resume = bwn_dma_64_resume;
3779 		dr->get_curslot = bwn_dma_64_get_curslot;
3780 		dr->set_curslot = bwn_dma_64_set_curslot;
3781 	} else {
3782 		dr->getdesc = bwn_dma_32_getdesc;
3783 		dr->setdesc = bwn_dma_32_setdesc;
3784 		dr->start_transfer = bwn_dma_32_start_transfer;
3785 		dr->suspend = bwn_dma_32_suspend;
3786 		dr->resume = bwn_dma_32_resume;
3787 		dr->get_curslot = bwn_dma_32_get_curslot;
3788 		dr->set_curslot = bwn_dma_32_set_curslot;
3789 	}
3790 	if (for_tx) {
3791 		dr->dr_tx = 1;
3792 		dr->dr_curslot = -1;
3793 	} else {
3794 		if (dr->dr_index == 0) {
3795 			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3796 			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3797 		} else
3798 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3799 	}
3800 
3801 	error = bwn_dma_allocringmemory(dr);
3802 	if (error)
3803 		goto fail2;
3804 
3805 	if (for_tx) {
3806 		/*
3807 		 * Assumption: BWN_TXRING_SLOTS can be divided by
3808 		 * BWN_TX_SLOTS_PER_FRAME
3809 		 */
3810 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3811 		    ("%s:%d: fail", __func__, __LINE__));
3812 
3813 		dr->dr_txhdr_cache =
3814 		    malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3815 			BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3816 		KASSERT(dr->dr_txhdr_cache != NULL,
3817 		    ("%s:%d: fail", __func__, __LINE__));
3818 
3819 		/*
3820 		 * Create TX ring DMA stuffs
3821 		 */
3822 		error = bus_dma_tag_create(dma->parent_dtag,
3823 				    BWN_ALIGN, 0,
3824 				    BUS_SPACE_MAXADDR,
3825 				    BUS_SPACE_MAXADDR,
3826 				    NULL, NULL,
3827 				    BWN_HDRSIZE(mac),
3828 				    1,
3829 				    BUS_SPACE_MAXSIZE_32BIT,
3830 				    0,
3831 				    NULL, NULL,
3832 				    &dr->dr_txring_dtag);
3833 		if (error) {
3834 			device_printf(sc->sc_dev,
3835 			    "can't create TX ring DMA tag: TODO frees\n");
3836 			goto fail1;
3837 		}
3838 
3839 		for (i = 0; i < dr->dr_numslots; i += 2) {
3840 			dr->getdesc(dr, i, &desc, &mt);
3841 
3842 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3843 			mt->mt_m = NULL;
3844 			mt->mt_ni = NULL;
3845 			mt->mt_islast = 0;
3846 			error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3847 			    &mt->mt_dmap);
3848 			if (error) {
3849 				device_printf(sc->sc_dev,
3850 				     "can't create RX buf DMA map\n");
3851 				goto fail1;
3852 			}
3853 
3854 			dr->getdesc(dr, i + 1, &desc, &mt);
3855 
3856 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3857 			mt->mt_m = NULL;
3858 			mt->mt_ni = NULL;
3859 			mt->mt_islast = 1;
3860 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
3861 			    &mt->mt_dmap);
3862 			if (error) {
3863 				device_printf(sc->sc_dev,
3864 				     "can't create RX buf DMA map\n");
3865 				goto fail1;
3866 			}
3867 		}
3868 	} else {
3869 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3870 		    &dr->dr_spare_dmap);
3871 		if (error) {
3872 			device_printf(sc->sc_dev,
3873 			    "can't create RX buf DMA map\n");
3874 			goto out;		/* XXX wrong! */
3875 		}
3876 
3877 		for (i = 0; i < dr->dr_numslots; i++) {
3878 			dr->getdesc(dr, i, &desc, &mt);
3879 
3880 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3881 			    &mt->mt_dmap);
3882 			if (error) {
3883 				device_printf(sc->sc_dev,
3884 				    "can't create RX buf DMA map\n");
3885 				goto out;	/* XXX wrong! */
3886 			}
3887 			error = bwn_dma_newbuf(dr, desc, mt, 1);
3888 			if (error) {
3889 				device_printf(sc->sc_dev,
3890 				    "failed to allocate RX buf\n");
3891 				goto out;	/* XXX wrong! */
3892 			}
3893 		}
3894 
3895 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3896 		    BUS_DMASYNC_PREWRITE);
3897 
3898 		dr->dr_usedslot = dr->dr_numslots;
3899 	}
3900 
3901       out:
3902 	return (dr);
3903 
3904 fail2:
3905 	free(dr->dr_txhdr_cache, M_DEVBUF);
3906 fail1:
3907 	free(dr->dr_meta, M_DEVBUF);
3908 fail0:
3909 	free(dr, M_DEVBUF);
3910 	return (NULL);
3911 }
3912 
3913 static void
3914 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3915 {
3916 
3917 	if (dr == NULL)
3918 		return;
3919 
3920 	bwn_dma_free_descbufs(*dr);
3921 	bwn_dma_free_ringmemory(*dr);
3922 
3923 	free((*dr)->dr_txhdr_cache, M_DEVBUF);
3924 	free((*dr)->dr_meta, M_DEVBUF);
3925 	free(*dr, M_DEVBUF);
3926 
3927 	*dr = NULL;
3928 }
3929 
3930 static void
3931 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3932     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3933 {
3934 	struct bwn_dmadesc32 *desc;
3935 
3936 	*meta = &(dr->dr_meta[slot]);
3937 	desc = dr->dr_ring_descbase;
3938 	desc = &(desc[slot]);
3939 
3940 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3941 }
3942 
3943 static void
3944 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3945     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3946     int start, int end, int irq)
3947 {
3948 	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3949 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
3950 	uint32_t addr, addrext, ctl;
3951 	int slot;
3952 
3953 	slot = (int)(&(desc->dma.dma32) - descbase);
3954 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3955 	    ("%s:%d: fail", __func__, __LINE__));
3956 
3957 	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3958 	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3959 	addr |= siba_dma_translation(sc->sc_dev);
3960 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3961 	if (slot == dr->dr_numslots - 1)
3962 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
3963 	if (start)
3964 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
3965 	if (end)
3966 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
3967 	if (irq)
3968 		ctl |= BWN_DMA32_DCTL_IRQ;
3969 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3970 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
3971 
3972 	desc->dma.dma32.control = htole32(ctl);
3973 	desc->dma.dma32.address = htole32(addr);
3974 }
3975 
3976 static void
3977 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3978 {
3979 
3980 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3981 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3982 }
3983 
3984 static void
3985 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3986 {
3987 
3988 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3989 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3990 }
3991 
3992 static void
3993 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3994 {
3995 
3996 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3997 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3998 }
3999 
4000 static int
4001 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4002 {
4003 	uint32_t val;
4004 
4005 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4006 	val &= BWN_DMA32_RXDPTR;
4007 
4008 	return (val / sizeof(struct bwn_dmadesc32));
4009 }
4010 
4011 static void
4012 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4013 {
4014 
4015 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4016 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4017 }
4018 
4019 static void
4020 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4021     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4022 {
4023 	struct bwn_dmadesc64 *desc;
4024 
4025 	*meta = &(dr->dr_meta[slot]);
4026 	desc = dr->dr_ring_descbase;
4027 	desc = &(desc[slot]);
4028 
4029 	*gdesc = (struct bwn_dmadesc_generic *)desc;
4030 }
4031 
4032 static void
4033 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4034     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4035     int start, int end, int irq)
4036 {
4037 	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4038 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
4039 	int slot;
4040 	uint32_t ctl0 = 0, ctl1 = 0;
4041 	uint32_t addrlo, addrhi;
4042 	uint32_t addrext;
4043 
4044 	slot = (int)(&(desc->dma.dma64) - descbase);
4045 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
4046 	    ("%s:%d: fail", __func__, __LINE__));
4047 
4048 	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4049 	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4050 	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4051 	    30;
4052 	addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4053 	if (slot == dr->dr_numslots - 1)
4054 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4055 	if (start)
4056 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4057 	if (end)
4058 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4059 	if (irq)
4060 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
4061 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4062 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4063 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
4064 
4065 	desc->dma.dma64.control0 = htole32(ctl0);
4066 	desc->dma.dma64.control1 = htole32(ctl1);
4067 	desc->dma.dma64.address_low = htole32(addrlo);
4068 	desc->dma.dma64.address_high = htole32(addrhi);
4069 }
4070 
4071 static void
4072 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4073 {
4074 
4075 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4076 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4077 }
4078 
4079 static void
4080 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4081 {
4082 
4083 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4084 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4085 }
4086 
4087 static void
4088 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4089 {
4090 
4091 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4092 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4093 }
4094 
4095 static int
4096 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4097 {
4098 	uint32_t val;
4099 
4100 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4101 	val &= BWN_DMA64_RXSTATDPTR;
4102 
4103 	return (val / sizeof(struct bwn_dmadesc64));
4104 }
4105 
4106 static void
4107 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4108 {
4109 
4110 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4111 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4112 }
4113 
4114 static int
4115 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4116 {
4117 	struct bwn_mac *mac = dr->dr_mac;
4118 	struct bwn_dma *dma = &mac->mac_method.dma;
4119 	struct bwn_softc *sc = mac->mac_sc;
4120 	int error;
4121 
4122 	error = bus_dma_tag_create(dma->parent_dtag,
4123 			    BWN_ALIGN, 0,
4124 			    BUS_SPACE_MAXADDR,
4125 			    BUS_SPACE_MAXADDR,
4126 			    NULL, NULL,
4127 			    BWN_DMA_RINGMEMSIZE,
4128 			    1,
4129 			    BUS_SPACE_MAXSIZE_32BIT,
4130 			    0,
4131 			    NULL, NULL,
4132 			    &dr->dr_ring_dtag);
4133 	if (error) {
4134 		device_printf(sc->sc_dev,
4135 		    "can't create TX ring DMA tag: TODO frees\n");
4136 		return (-1);
4137 	}
4138 
4139 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
4140 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4141 	    &dr->dr_ring_dmap);
4142 	if (error) {
4143 		device_printf(sc->sc_dev,
4144 		    "can't allocate DMA mem: TODO frees\n");
4145 		return (-1);
4146 	}
4147 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4148 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4149 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4150 	if (error) {
4151 		device_printf(sc->sc_dev,
4152 		    "can't load DMA mem: TODO free\n");
4153 		return (-1);
4154 	}
4155 
4156 	return (0);
4157 }
4158 
4159 static void
4160 bwn_dma_setup(struct bwn_dma_ring *dr)
4161 {
4162 	struct bwn_softc *sc = dr->dr_mac->mac_sc;
4163 	uint64_t ring64;
4164 	uint32_t addrext, ring32, value;
4165 	uint32_t trans = siba_dma_translation(sc->sc_dev);
4166 
4167 	if (dr->dr_tx) {
4168 		dr->dr_curslot = -1;
4169 
4170 		if (dr->dr_type == BWN_DMA_64BIT) {
4171 			ring64 = (uint64_t)(dr->dr_ring_dmabase);
4172 			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4173 			    >> 30;
4174 			value = BWN_DMA64_TXENABLE;
4175 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4176 			    & BWN_DMA64_TXADDREXT_MASK;
4177 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4178 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4179 			    (ring64 & 0xffffffff));
4180 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4181 			    ((ring64 >> 32) &
4182 			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4183 		} else {
4184 			ring32 = (uint32_t)(dr->dr_ring_dmabase);
4185 			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4186 			value = BWN_DMA32_TXENABLE;
4187 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4188 			    & BWN_DMA32_TXADDREXT_MASK;
4189 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4190 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4191 			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4192 		}
4193 		return;
4194 	}
4195 
4196 	/*
4197 	 * set for RX
4198 	 */
4199 	dr->dr_usedslot = dr->dr_numslots;
4200 
4201 	if (dr->dr_type == BWN_DMA_64BIT) {
4202 		ring64 = (uint64_t)(dr->dr_ring_dmabase);
4203 		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4204 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4205 		value |= BWN_DMA64_RXENABLE;
4206 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4207 		    & BWN_DMA64_RXADDREXT_MASK;
4208 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4209 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4210 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4211 		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4212 		    | (trans << 1));
4213 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4214 		    sizeof(struct bwn_dmadesc64));
4215 	} else {
4216 		ring32 = (uint32_t)(dr->dr_ring_dmabase);
4217 		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4218 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4219 		value |= BWN_DMA32_RXENABLE;
4220 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4221 		    & BWN_DMA32_RXADDREXT_MASK;
4222 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4223 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4224 		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4225 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4226 		    sizeof(struct bwn_dmadesc32));
4227 	}
4228 }
4229 
4230 static void
4231 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4232 {
4233 
4234 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4235 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4236 	    dr->dr_ring_dmap);
4237 }
4238 
4239 static void
4240 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4241 {
4242 
4243 	if (dr->dr_tx) {
4244 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4245 		if (dr->dr_type == BWN_DMA_64BIT) {
4246 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4247 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4248 		} else
4249 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4250 	} else {
4251 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4252 		if (dr->dr_type == BWN_DMA_64BIT) {
4253 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4254 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4255 		} else
4256 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4257 	}
4258 }
4259 
4260 static void
4261 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4262 {
4263 	struct bwn_dmadesc_generic *desc;
4264 	struct bwn_dmadesc_meta *meta;
4265 	struct bwn_mac *mac = dr->dr_mac;
4266 	struct bwn_dma *dma = &mac->mac_method.dma;
4267 	struct bwn_softc *sc = mac->mac_sc;
4268 	int i;
4269 
4270 	if (!dr->dr_usedslot)
4271 		return;
4272 	for (i = 0; i < dr->dr_numslots; i++) {
4273 		dr->getdesc(dr, i, &desc, &meta);
4274 
4275 		if (meta->mt_m == NULL) {
4276 			if (!dr->dr_tx)
4277 				device_printf(sc->sc_dev, "%s: not TX?\n",
4278 				    __func__);
4279 			continue;
4280 		}
4281 		if (dr->dr_tx) {
4282 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4283 				bus_dmamap_unload(dr->dr_txring_dtag,
4284 				    meta->mt_dmap);
4285 			else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4286 				bus_dmamap_unload(dma->txbuf_dtag,
4287 				    meta->mt_dmap);
4288 		} else
4289 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4290 		bwn_dma_free_descbuf(dr, meta);
4291 	}
4292 }
4293 
4294 static int
4295 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4296     int type)
4297 {
4298 	struct bwn_softc *sc = mac->mac_sc;
4299 	uint32_t value;
4300 	int i;
4301 	uint16_t offset;
4302 
4303 	for (i = 0; i < 10; i++) {
4304 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4305 		    BWN_DMA32_TXSTATUS;
4306 		value = BWN_READ_4(mac, base + offset);
4307 		if (type == BWN_DMA_64BIT) {
4308 			value &= BWN_DMA64_TXSTAT;
4309 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
4310 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4311 			    value == BWN_DMA64_TXSTAT_STOPPED)
4312 				break;
4313 		} else {
4314 			value &= BWN_DMA32_TXSTATE;
4315 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
4316 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4317 			    value == BWN_DMA32_TXSTAT_STOPPED)
4318 				break;
4319 		}
4320 		DELAY(1000);
4321 	}
4322 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4323 	BWN_WRITE_4(mac, base + offset, 0);
4324 	for (i = 0; i < 10; i++) {
4325 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4326 						   BWN_DMA32_TXSTATUS;
4327 		value = BWN_READ_4(mac, base + offset);
4328 		if (type == BWN_DMA_64BIT) {
4329 			value &= BWN_DMA64_TXSTAT;
4330 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
4331 				i = -1;
4332 				break;
4333 			}
4334 		} else {
4335 			value &= BWN_DMA32_TXSTATE;
4336 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
4337 				i = -1;
4338 				break;
4339 			}
4340 		}
4341 		DELAY(1000);
4342 	}
4343 	if (i != -1) {
4344 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4345 		return (ENODEV);
4346 	}
4347 	DELAY(1000);
4348 
4349 	return (0);
4350 }
4351 
4352 static int
4353 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4354     int type)
4355 {
4356 	struct bwn_softc *sc = mac->mac_sc;
4357 	uint32_t value;
4358 	int i;
4359 	uint16_t offset;
4360 
4361 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4362 	BWN_WRITE_4(mac, base + offset, 0);
4363 	for (i = 0; i < 10; i++) {
4364 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4365 		    BWN_DMA32_RXSTATUS;
4366 		value = BWN_READ_4(mac, base + offset);
4367 		if (type == BWN_DMA_64BIT) {
4368 			value &= BWN_DMA64_RXSTAT;
4369 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
4370 				i = -1;
4371 				break;
4372 			}
4373 		} else {
4374 			value &= BWN_DMA32_RXSTATE;
4375 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
4376 				i = -1;
4377 				break;
4378 			}
4379 		}
4380 		DELAY(1000);
4381 	}
4382 	if (i != -1) {
4383 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4384 		return (ENODEV);
4385 	}
4386 
4387 	return (0);
4388 }
4389 
4390 static void
4391 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4392     struct bwn_dmadesc_meta *meta)
4393 {
4394 
4395 	if (meta->mt_m != NULL) {
4396 		m_freem(meta->mt_m);
4397 		meta->mt_m = NULL;
4398 	}
4399 	if (meta->mt_ni != NULL) {
4400 		ieee80211_free_node(meta->mt_ni);
4401 		meta->mt_ni = NULL;
4402 	}
4403 }
4404 
4405 static void
4406 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4407 {
4408 	struct bwn_rxhdr4 *rxhdr;
4409 	unsigned char *frame;
4410 
4411 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
4412 	rxhdr->frame_len = 0;
4413 
4414 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4415 	    sizeof(struct bwn_plcp6) + 2,
4416 	    ("%s:%d: fail", __func__, __LINE__));
4417 	frame = mtod(m, char *) + dr->dr_frameoffset;
4418 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4419 }
4420 
4421 static uint8_t
4422 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4423 {
4424 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4425 
4426 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4427 	    == 0xff);
4428 }
4429 
4430 static void
4431 bwn_wme_init(struct bwn_mac *mac)
4432 {
4433 
4434 	bwn_wme_load(mac);
4435 
4436 	/* enable WME support. */
4437 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4438 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4439 	    BWN_IFSCTL_USE_EDCF);
4440 }
4441 
4442 static void
4443 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4444 {
4445 	struct bwn_softc *sc = mac->mac_sc;
4446 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4447 	uint16_t delay;	/* microsec */
4448 
4449 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4450 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4451 		delay = 500;
4452 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4453 		delay = max(delay, (uint16_t)2400);
4454 
4455 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4456 }
4457 
4458 static void
4459 bwn_bt_enable(struct bwn_mac *mac)
4460 {
4461 	struct bwn_softc *sc = mac->mac_sc;
4462 	uint64_t hf;
4463 
4464 	if (bwn_bluetooth == 0)
4465 		return;
4466 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4467 		return;
4468 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4469 		return;
4470 
4471 	hf = bwn_hf_read(mac);
4472 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4473 		hf |= BWN_HF_BT_COEXISTALT;
4474 	else
4475 		hf |= BWN_HF_BT_COEXIST;
4476 	bwn_hf_write(mac, hf);
4477 }
4478 
4479 static void
4480 bwn_set_macaddr(struct bwn_mac *mac)
4481 {
4482 
4483 	bwn_mac_write_bssid(mac);
4484 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4485 }
4486 
4487 static void
4488 bwn_clear_keys(struct bwn_mac *mac)
4489 {
4490 	int i;
4491 
4492 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
4493 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4494 		    ("%s:%d: fail", __func__, __LINE__));
4495 
4496 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4497 		    NULL, BWN_SEC_KEYSIZE, NULL);
4498 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4499 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4500 			    NULL, BWN_SEC_KEYSIZE, NULL);
4501 		}
4502 		mac->mac_key[i].keyconf = NULL;
4503 	}
4504 }
4505 
4506 static void
4507 bwn_crypt_init(struct bwn_mac *mac)
4508 {
4509 	struct bwn_softc *sc = mac->mac_sc;
4510 
4511 	mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4512 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4513 	    ("%s:%d: fail", __func__, __LINE__));
4514 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4515 	mac->mac_ktp *= 2;
4516 	if (siba_get_revid(sc->sc_dev) >= 5)
4517 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4518 	bwn_clear_keys(mac);
4519 }
4520 
4521 static void
4522 bwn_chip_exit(struct bwn_mac *mac)
4523 {
4524 	struct bwn_softc *sc = mac->mac_sc;
4525 
4526 	bwn_phy_exit(mac);
4527 	siba_gpio_set(sc->sc_dev, 0);
4528 }
4529 
4530 static int
4531 bwn_fw_fillinfo(struct bwn_mac *mac)
4532 {
4533 	int error;
4534 
4535 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4536 	if (error == 0)
4537 		return (0);
4538 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4539 	if (error == 0)
4540 		return (0);
4541 	return (error);
4542 }
4543 
4544 static int
4545 bwn_gpio_init(struct bwn_mac *mac)
4546 {
4547 	struct bwn_softc *sc = mac->mac_sc;
4548 	uint32_t mask = 0x1f, set = 0xf, value;
4549 
4550 	BWN_WRITE_4(mac, BWN_MACCTL,
4551 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4552 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
4553 	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4554 
4555 	if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4556 		mask |= 0x0060;
4557 		set |= 0x0060;
4558 	}
4559 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4560 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
4561 		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4562 		mask |= 0x0200;
4563 		set |= 0x0200;
4564 	}
4565 	if (siba_get_revid(sc->sc_dev) >= 2)
4566 		mask |= 0x0010;
4567 
4568 	value = siba_gpio_get(sc->sc_dev);
4569 	if (value == -1)
4570 		return (0);
4571 	siba_gpio_set(sc->sc_dev, (value & mask) | set);
4572 
4573 	return (0);
4574 }
4575 
4576 static int
4577 bwn_fw_loadinitvals(struct bwn_mac *mac)
4578 {
4579 #define	GETFWOFFSET(fwp, offset)				\
4580 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4581 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
4582 	const struct bwn_fwhdr *hdr;
4583 	struct bwn_fw *fw = &mac->mac_fw;
4584 	int error;
4585 
4586 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4587 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4588 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4589 	if (error)
4590 		return (error);
4591 	if (fw->initvals_band.fw) {
4592 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4593 		error = bwn_fwinitvals_write(mac,
4594 		    GETFWOFFSET(fw->initvals_band, hdr_len),
4595 		    be32toh(hdr->size),
4596 		    fw->initvals_band.fw->datasize - hdr_len);
4597 	}
4598 	return (error);
4599 #undef GETFWOFFSET
4600 }
4601 
4602 static int
4603 bwn_phy_init(struct bwn_mac *mac)
4604 {
4605 	struct bwn_softc *sc = mac->mac_sc;
4606 	int error;
4607 
4608 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4609 	mac->mac_phy.rf_onoff(mac, 1);
4610 	error = mac->mac_phy.init(mac);
4611 	if (error) {
4612 		device_printf(sc->sc_dev, "PHY init failed\n");
4613 		goto fail0;
4614 	}
4615 	error = bwn_switch_channel(mac,
4616 	    mac->mac_phy.get_default_chan(mac));
4617 	if (error) {
4618 		device_printf(sc->sc_dev,
4619 		    "failed to switch default channel\n");
4620 		goto fail1;
4621 	}
4622 	return (0);
4623 fail1:
4624 	if (mac->mac_phy.exit)
4625 		mac->mac_phy.exit(mac);
4626 fail0:
4627 	mac->mac_phy.rf_onoff(mac, 0);
4628 
4629 	return (error);
4630 }
4631 
4632 static void
4633 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4634 {
4635 	uint16_t ant;
4636 	uint16_t tmp;
4637 
4638 	ant = bwn_ant2phy(antenna);
4639 
4640 	/* For ACK/CTS */
4641 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4642 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4643 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4644 	/* For Probe Resposes */
4645 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4646 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4647 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4648 }
4649 
4650 static void
4651 bwn_set_opmode(struct bwn_mac *mac)
4652 {
4653 	struct bwn_softc *sc = mac->mac_sc;
4654 	struct ifnet *ifp = sc->sc_ifp;
4655 	struct ieee80211com *ic = ifp->if_l2com;
4656 	uint32_t ctl;
4657 	uint16_t cfp_pretbtt;
4658 
4659 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4660 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4661 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4662 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4663 	ctl |= BWN_MACCTL_STA;
4664 
4665 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4666 	    ic->ic_opmode == IEEE80211_M_MBSS)
4667 		ctl |= BWN_MACCTL_HOSTAP;
4668 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
4669 		ctl &= ~BWN_MACCTL_STA;
4670 	ctl |= sc->sc_filters;
4671 
4672 	if (siba_get_revid(sc->sc_dev) <= 4)
4673 		ctl |= BWN_MACCTL_PROMISC;
4674 
4675 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4676 
4677 	cfp_pretbtt = 2;
4678 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4679 		if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4680 		    siba_get_chiprev(sc->sc_dev) == 3)
4681 			cfp_pretbtt = 100;
4682 		else
4683 			cfp_pretbtt = 50;
4684 	}
4685 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4686 }
4687 
4688 static int
4689 bwn_dma_gettype(struct bwn_mac *mac)
4690 {
4691 	uint32_t tmp;
4692 	uint16_t base;
4693 
4694 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4695 	if (tmp & SIBA_TGSHIGH_DMA64)
4696 		return (BWN_DMA_64BIT);
4697 	base = bwn_dma_base(0, 0);
4698 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4699 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4700 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
4701 		return (BWN_DMA_32BIT);
4702 
4703 	return (BWN_DMA_30BIT);
4704 }
4705 
4706 static void
4707 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4708 {
4709 	if (!error) {
4710 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4711 		*((bus_addr_t *)arg) = seg->ds_addr;
4712 	}
4713 }
4714 
4715 static void
4716 bwn_phy_g_init_sub(struct bwn_mac *mac)
4717 {
4718 	struct bwn_phy *phy = &mac->mac_phy;
4719 	struct bwn_phy_g *pg = &phy->phy_g;
4720 	struct bwn_softc *sc = mac->mac_sc;
4721 	uint16_t i, tmp;
4722 
4723 	if (phy->rev == 1)
4724 		bwn_phy_init_b5(mac);
4725 	else
4726 		bwn_phy_init_b6(mac);
4727 
4728 	if (phy->rev >= 2 || phy->gmode)
4729 		bwn_phy_init_a(mac);
4730 
4731 	if (phy->rev >= 2) {
4732 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4733 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4734 	}
4735 	if (phy->rev == 2) {
4736 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4737 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4738 	}
4739 	if (phy->rev > 5) {
4740 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4741 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4742 	}
4743 	if (phy->gmode || phy->rev >= 2) {
4744 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4745 		tmp &= BWN_PHYVER_VERSION;
4746 		if (tmp == 3 || tmp == 5) {
4747 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4748 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4749 		}
4750 		if (tmp == 5) {
4751 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4752 			    0x1f00);
4753 		}
4754 	}
4755 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4756 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4757 	if (phy->rf_rev == 8) {
4758 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4759 		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4760 	}
4761 	if (BWN_HAS_LOOPBACK(phy))
4762 		bwn_loopback_calcgain(mac);
4763 
4764 	if (phy->rf_rev != 8) {
4765 		if (pg->pg_initval == 0xffff)
4766 			pg->pg_initval = bwn_rf_init_bcm2050(mac);
4767 		else
4768 			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4769 	}
4770 	bwn_lo_g_init(mac);
4771 	if (BWN_HAS_TXMAG(phy)) {
4772 		BWN_RF_WRITE(mac, 0x52,
4773 		    (BWN_RF_READ(mac, 0x52) & 0xff00)
4774 		    | pg->pg_loctl.tx_bias |
4775 		    pg->pg_loctl.tx_magn);
4776 	} else {
4777 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4778 	}
4779 	if (phy->rev >= 6) {
4780 		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4781 		    (pg->pg_loctl.tx_bias << 12));
4782 	}
4783 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4784 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4785 	else
4786 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4787 	if (phy->rev < 2)
4788 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4789 	else
4790 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4791 	if (phy->gmode || phy->rev >= 2) {
4792 		bwn_lo_g_adjust(mac);
4793 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4794 	}
4795 
4796 	if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4797 		for (i = 0; i < 64; i++) {
4798 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4799 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4800 			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4801 			    -32), 31));
4802 		}
4803 		bwn_nrssi_threshold(mac);
4804 	} else if (phy->gmode || phy->rev >= 2) {
4805 		if (pg->pg_nrssi[0] == -1000) {
4806 			KASSERT(pg->pg_nrssi[1] == -1000,
4807 			    ("%s:%d: fail", __func__, __LINE__));
4808 			bwn_nrssi_slope_11g(mac);
4809 		} else
4810 			bwn_nrssi_threshold(mac);
4811 	}
4812 	if (phy->rf_rev == 8)
4813 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4814 	bwn_phy_hwpctl_init(mac);
4815 	if ((siba_get_chipid(sc->sc_dev) == 0x4306
4816 	     && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4817 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4818 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4819 	}
4820 }
4821 
4822 static uint8_t
4823 bwn_has_hwpctl(struct bwn_mac *mac)
4824 {
4825 
4826 	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4827 		return (0);
4828 	return (mac->mac_phy.use_hwpctl(mac));
4829 }
4830 
4831 static void
4832 bwn_phy_init_b5(struct bwn_mac *mac)
4833 {
4834 	struct bwn_phy *phy = &mac->mac_phy;
4835 	struct bwn_phy_g *pg = &phy->phy_g;
4836 	struct bwn_softc *sc = mac->mac_sc;
4837 	uint16_t offset, value;
4838 	uint8_t old_channel;
4839 
4840 	if (phy->analog == 1)
4841 		BWN_RF_SET(mac, 0x007a, 0x0050);
4842 	if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4843 	    (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4844 		value = 0x2120;
4845 		for (offset = 0x00a8; offset < 0x00c7; offset++) {
4846 			BWN_PHY_WRITE(mac, offset, value);
4847 			value += 0x202;
4848 		}
4849 	}
4850 	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4851 	if (phy->rf_ver == 0x2050)
4852 		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4853 
4854 	if (phy->gmode || phy->rev >= 2) {
4855 		if (phy->rf_ver == 0x2050) {
4856 			BWN_RF_SET(mac, 0x007a, 0x0020);
4857 			BWN_RF_SET(mac, 0x0051, 0x0004);
4858 		}
4859 		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4860 
4861 		BWN_PHY_SET(mac, 0x0802, 0x0100);
4862 		BWN_PHY_SET(mac, 0x042b, 0x2000);
4863 
4864 		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4865 
4866 		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4867 		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4868 		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4869 	}
4870 
4871 	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4872 		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4873 
4874 	if (phy->analog == 1) {
4875 		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4876 		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4877 		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4878 		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4879 		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4880 	} else
4881 		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4882 	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4883 	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4884 
4885 	if (phy->analog == 1)
4886 		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4887 	else
4888 		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4889 
4890 	if (phy->analog == 0)
4891 		BWN_WRITE_2(mac, 0x03e4, 0x3000);
4892 
4893 	old_channel = phy->chan;
4894 	bwn_phy_g_switch_chan(mac, 7, 0);
4895 
4896 	if (phy->rf_ver != 0x2050) {
4897 		BWN_RF_WRITE(mac, 0x0075, 0x0080);
4898 		BWN_RF_WRITE(mac, 0x0079, 0x0081);
4899 	}
4900 
4901 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
4902 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
4903 
4904 	if (phy->rf_ver == 0x2050) {
4905 		BWN_RF_WRITE(mac, 0x0050, 0x0020);
4906 		BWN_RF_WRITE(mac, 0x005a, 0x0070);
4907 	}
4908 
4909 	BWN_RF_WRITE(mac, 0x005b, 0x007b);
4910 	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4911 	BWN_RF_SET(mac, 0x007a, 0x0007);
4912 
4913 	bwn_phy_g_switch_chan(mac, old_channel, 0);
4914 	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4915 	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4916 	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4917 
4918 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4919 	    pg->pg_txctl);
4920 
4921 	if (phy->rf_ver == 0x2050)
4922 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
4923 
4924 	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4925 }
4926 
4927 static void
4928 bwn_loopback_calcgain(struct bwn_mac *mac)
4929 {
4930 	struct bwn_phy *phy = &mac->mac_phy;
4931 	struct bwn_phy_g *pg = &phy->phy_g;
4932 	struct bwn_softc *sc = mac->mac_sc;
4933 	uint16_t backup_phy[16] = { 0 };
4934 	uint16_t backup_radio[3];
4935 	uint16_t backup_bband;
4936 	uint16_t i, j, loop_i_max;
4937 	uint16_t trsw_rx;
4938 	uint16_t loop1_outer_done, loop1_inner_done;
4939 
4940 	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4941 	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4942 	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4943 	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4944 	if (phy->rev != 1) {
4945 		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4946 		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4947 	}
4948 	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4949 	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4950 	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4951 	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4952 	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4953 	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4954 	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4955 	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4956 	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4957 	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4958 	backup_bband = pg->pg_bbatt.att;
4959 	backup_radio[0] = BWN_RF_READ(mac, 0x52);
4960 	backup_radio[1] = BWN_RF_READ(mac, 0x43);
4961 	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4962 
4963 	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4964 	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4965 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4966 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4967 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4968 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4969 	if (phy->rev != 1) {
4970 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4971 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4972 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4973 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4974 	}
4975 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4976 	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4977 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4978 	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4979 
4980 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4981 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4982 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4983 
4984 	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4985 	if (phy->rev != 1) {
4986 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4987 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4988 	}
4989 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4990 
4991 	if (phy->rf_rev == 8)
4992 		BWN_RF_WRITE(mac, 0x43, 0x000f);
4993 	else {
4994 		BWN_RF_WRITE(mac, 0x52, 0);
4995 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4996 	}
4997 	bwn_phy_g_set_bbatt(mac, 11);
4998 
4999 	if (phy->rev >= 3)
5000 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5001 	else
5002 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5003 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5004 
5005 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5006 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5007 
5008 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5009 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5010 
5011 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5012 		if (phy->rev >= 7) {
5013 			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5014 			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5015 		}
5016 	}
5017 	BWN_RF_MASK(mac, 0x7a, 0x00f7);
5018 
5019 	j = 0;
5020 	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5021 	for (i = 0; i < loop_i_max; i++) {
5022 		for (j = 0; j < 16; j++) {
5023 			BWN_RF_WRITE(mac, 0x43, i);
5024 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5025 			    (j << 8));
5026 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5027 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5028 			DELAY(20);
5029 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5030 				goto done0;
5031 		}
5032 	}
5033 done0:
5034 	loop1_outer_done = i;
5035 	loop1_inner_done = j;
5036 	if (j >= 8) {
5037 		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5038 		trsw_rx = 0x1b;
5039 		for (j = j - 8; j < 16; j++) {
5040 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5041 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5042 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5043 			DELAY(20);
5044 			trsw_rx -= 3;
5045 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5046 				goto done1;
5047 		}
5048 	} else
5049 		trsw_rx = 0x18;
5050 done1:
5051 
5052 	if (phy->rev != 1) {
5053 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5054 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5055 	}
5056 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5057 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5058 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5059 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5060 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5061 	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5062 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5063 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5064 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5065 
5066 	bwn_phy_g_set_bbatt(mac, backup_bband);
5067 
5068 	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5069 	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5070 	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5071 
5072 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5073 	DELAY(10);
5074 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5075 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5076 	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5077 	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5078 
5079 	pg->pg_max_lb_gain =
5080 	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5081 	pg->pg_trsw_rx_gain = trsw_rx * 2;
5082 }
5083 
5084 static uint16_t
5085 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5086 {
5087 	struct bwn_phy *phy = &mac->mac_phy;
5088 	uint32_t tmp1 = 0, tmp2 = 0;
5089 	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5090 	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5091 	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5092 	static const uint8_t rcc_table[] = {
5093 		0x02, 0x03, 0x01, 0x0f,
5094 		0x06, 0x07, 0x05, 0x0f,
5095 		0x0a, 0x0b, 0x09, 0x0f,
5096 		0x0e, 0x0f, 0x0d, 0x0f,
5097 	};
5098 
5099 	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5100 	    rfoverval = rfover = cck3 = 0;
5101 	radio0 = BWN_RF_READ(mac, 0x43);
5102 	radio1 = BWN_RF_READ(mac, 0x51);
5103 	radio2 = BWN_RF_READ(mac, 0x52);
5104 	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5105 	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5106 	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5107 	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5108 
5109 	if (phy->type == BWN_PHYTYPE_B) {
5110 		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5111 		reg0 = BWN_READ_2(mac, 0x3ec);
5112 
5113 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5114 		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5115 	} else if (phy->gmode || phy->rev >= 2) {
5116 		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5117 		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5118 		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5119 		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5120 		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5121 		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5122 
5123 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5124 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5125 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5126 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5127 		if (BWN_HAS_LOOPBACK(phy)) {
5128 			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5129 			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5130 			if (phy->rev >= 3)
5131 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5132 			else
5133 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5134 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5135 		}
5136 
5137 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5138 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5139 			BWN_LPD(0, 1, 1)));
5140 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5141 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5142 	}
5143 	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5144 
5145 	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5146 	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5147 	reg1 = BWN_READ_2(mac, 0x3e6);
5148 	reg2 = BWN_READ_2(mac, 0x3f4);
5149 
5150 	if (phy->analog == 0)
5151 		BWN_WRITE_2(mac, 0x03e6, 0x0122);
5152 	else {
5153 		if (phy->analog >= 2)
5154 			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5155 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5156 		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5157 	}
5158 
5159 	reg = BWN_RF_READ(mac, 0x60);
5160 	index = (reg & 0x001e) >> 1;
5161 	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5162 
5163 	if (phy->type == BWN_PHYTYPE_B)
5164 		BWN_RF_WRITE(mac, 0x78, 0x26);
5165 	if (phy->gmode || phy->rev >= 2) {
5166 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5167 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5168 			BWN_LPD(0, 1, 1)));
5169 	}
5170 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5171 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5172 	if (phy->gmode || phy->rev >= 2) {
5173 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5174 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5175 			BWN_LPD(0, 0, 1)));
5176 	}
5177 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5178 	BWN_RF_SET(mac, 0x51, 0x0004);
5179 	if (phy->rf_rev == 8)
5180 		BWN_RF_WRITE(mac, 0x43, 0x1f);
5181 	else {
5182 		BWN_RF_WRITE(mac, 0x52, 0);
5183 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5184 	}
5185 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5186 
5187 	for (i = 0; i < 16; i++) {
5188 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5189 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5190 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5191 		if (phy->gmode || phy->rev >= 2) {
5192 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5193 			    bwn_rf_2050_rfoverval(mac,
5194 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5195 		}
5196 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5197 		DELAY(10);
5198 		if (phy->gmode || phy->rev >= 2) {
5199 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5200 			    bwn_rf_2050_rfoverval(mac,
5201 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5202 		}
5203 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5204 		DELAY(10);
5205 		if (phy->gmode || phy->rev >= 2) {
5206 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5207 			    bwn_rf_2050_rfoverval(mac,
5208 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5209 		}
5210 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5211 		DELAY(20);
5212 		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5213 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5214 		if (phy->gmode || phy->rev >= 2) {
5215 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5216 			    bwn_rf_2050_rfoverval(mac,
5217 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5218 		}
5219 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5220 	}
5221 	DELAY(10);
5222 
5223 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5224 	tmp1++;
5225 	tmp1 >>= 9;
5226 
5227 	for (i = 0; i < 16; i++) {
5228 		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5229 		BWN_RF_WRITE(mac, 0x78, radio78);
5230 		DELAY(10);
5231 		for (j = 0; j < 16; j++) {
5232 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5233 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5234 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5235 			if (phy->gmode || phy->rev >= 2) {
5236 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5237 				    bwn_rf_2050_rfoverval(mac,
5238 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5239 			}
5240 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5241 			DELAY(10);
5242 			if (phy->gmode || phy->rev >= 2) {
5243 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5244 				    bwn_rf_2050_rfoverval(mac,
5245 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5246 			}
5247 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5248 			DELAY(10);
5249 			if (phy->gmode || phy->rev >= 2) {
5250 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5251 				    bwn_rf_2050_rfoverval(mac,
5252 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5253 			}
5254 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5255 			DELAY(10);
5256 			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5257 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5258 			if (phy->gmode || phy->rev >= 2) {
5259 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5260 				    bwn_rf_2050_rfoverval(mac,
5261 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5262 			}
5263 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5264 		}
5265 		tmp2++;
5266 		tmp2 >>= 8;
5267 		if (tmp1 < tmp2)
5268 			break;
5269 	}
5270 
5271 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5272 	BWN_RF_WRITE(mac, 0x51, radio1);
5273 	BWN_RF_WRITE(mac, 0x52, radio2);
5274 	BWN_RF_WRITE(mac, 0x43, radio0);
5275 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5276 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5277 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5278 	BWN_WRITE_2(mac, 0x3e6, reg1);
5279 	if (phy->analog != 0)
5280 		BWN_WRITE_2(mac, 0x3f4, reg2);
5281 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5282 	bwn_spu_workaround(mac, phy->chan);
5283 	if (phy->type == BWN_PHYTYPE_B) {
5284 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5285 		BWN_WRITE_2(mac, 0x3ec, reg0);
5286 	} else if (phy->gmode) {
5287 		BWN_WRITE_2(mac, BWN_PHY_RADIO,
5288 			    BWN_READ_2(mac, BWN_PHY_RADIO)
5289 			    & 0x7fff);
5290 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5291 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5292 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5293 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5294 			      analogoverval);
5295 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5296 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5297 		if (BWN_HAS_LOOPBACK(phy)) {
5298 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5299 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5300 		}
5301 	}
5302 
5303 	return ((i > 15) ? radio78 : rcc);
5304 }
5305 
5306 static void
5307 bwn_phy_init_b6(struct bwn_mac *mac)
5308 {
5309 	struct bwn_phy *phy = &mac->mac_phy;
5310 	struct bwn_phy_g *pg = &phy->phy_g;
5311 	struct bwn_softc *sc = mac->mac_sc;
5312 	uint16_t offset, val;
5313 	uint8_t old_channel;
5314 
5315 	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5316 	    ("%s:%d: fail", __func__, __LINE__));
5317 
5318 	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5319 	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5320 	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5321 		BWN_RF_WRITE(mac, 0x51, 0x37);
5322 		BWN_RF_WRITE(mac, 0x52, 0x70);
5323 		BWN_RF_WRITE(mac, 0x53, 0xb3);
5324 		BWN_RF_WRITE(mac, 0x54, 0x9b);
5325 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5326 		BWN_RF_WRITE(mac, 0x5b, 0x88);
5327 		BWN_RF_WRITE(mac, 0x5d, 0x88);
5328 		BWN_RF_WRITE(mac, 0x5e, 0x88);
5329 		BWN_RF_WRITE(mac, 0x7d, 0x88);
5330 		bwn_hf_write(mac,
5331 		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5332 	}
5333 	if (phy->rf_rev == 8) {
5334 		BWN_RF_WRITE(mac, 0x51, 0);
5335 		BWN_RF_WRITE(mac, 0x52, 0x40);
5336 		BWN_RF_WRITE(mac, 0x53, 0xb7);
5337 		BWN_RF_WRITE(mac, 0x54, 0x98);
5338 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5339 		BWN_RF_WRITE(mac, 0x5b, 0x6b);
5340 		BWN_RF_WRITE(mac, 0x5c, 0x0f);
5341 		if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5342 			BWN_RF_WRITE(mac, 0x5d, 0xfa);
5343 			BWN_RF_WRITE(mac, 0x5e, 0xd8);
5344 		} else {
5345 			BWN_RF_WRITE(mac, 0x5d, 0xf5);
5346 			BWN_RF_WRITE(mac, 0x5e, 0xb8);
5347 		}
5348 		BWN_RF_WRITE(mac, 0x0073, 0x0003);
5349 		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5350 		BWN_RF_WRITE(mac, 0x007c, 0x0001);
5351 		BWN_RF_WRITE(mac, 0x007e, 0x0008);
5352 	}
5353 	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5354 		BWN_PHY_WRITE(mac, offset, val);
5355 		val -= 0x0202;
5356 	}
5357 	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5358 		BWN_PHY_WRITE(mac, offset, val);
5359 		val -= 0x0202;
5360 	}
5361 	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5362 		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5363 		val += 0x0202;
5364 	}
5365 	if (phy->type == BWN_PHYTYPE_G) {
5366 		BWN_RF_SET(mac, 0x007a, 0x0020);
5367 		BWN_RF_SET(mac, 0x0051, 0x0004);
5368 		BWN_PHY_SET(mac, 0x0802, 0x0100);
5369 		BWN_PHY_SET(mac, 0x042b, 0x2000);
5370 		BWN_PHY_WRITE(mac, 0x5b, 0);
5371 		BWN_PHY_WRITE(mac, 0x5c, 0);
5372 	}
5373 
5374 	old_channel = phy->chan;
5375 	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5376 
5377 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
5378 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
5379 	DELAY(40);
5380 	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5381 		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5382 		BWN_RF_WRITE(mac, 0x50, 0x20);
5383 	}
5384 	if (phy->rf_rev <= 2) {
5385 		BWN_RF_WRITE(mac, 0x7c, 0x20);
5386 		BWN_RF_WRITE(mac, 0x5a, 0x70);
5387 		BWN_RF_WRITE(mac, 0x5b, 0x7b);
5388 		BWN_RF_WRITE(mac, 0x5c, 0xb0);
5389 	}
5390 	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5391 
5392 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5393 
5394 	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5395 	if (phy->rf_rev >= 6)
5396 		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5397 	else
5398 		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5399 	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5400 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5401 	    pg->pg_txctl);
5402 	if (phy->rf_rev <= 5)
5403 		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5404 	if (phy->rf_rev <= 2)
5405 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5406 
5407 	if (phy->analog == 4) {
5408 		BWN_WRITE_2(mac, 0x3e4, 9);
5409 		BWN_PHY_MASK(mac, 0x61, 0x0fff);
5410 	} else
5411 		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5412 	if (phy->type == BWN_PHYTYPE_B)
5413 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5414 	else if (phy->type == BWN_PHYTYPE_G)
5415 		BWN_WRITE_2(mac, 0x03e6, 0x0);
5416 }
5417 
5418 static void
5419 bwn_phy_init_a(struct bwn_mac *mac)
5420 {
5421 	struct bwn_phy *phy = &mac->mac_phy;
5422 	struct bwn_softc *sc = mac->mac_sc;
5423 
5424 	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5425 	    ("%s:%d: fail", __func__, __LINE__));
5426 
5427 	if (phy->rev >= 6) {
5428 		if (phy->type == BWN_PHYTYPE_A)
5429 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5430 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5431 			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5432 		else
5433 			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5434 	}
5435 
5436 	bwn_wa_init(mac);
5437 
5438 	if (phy->type == BWN_PHYTYPE_G &&
5439 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5440 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5441 }
5442 
5443 static void
5444 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5445 {
5446 	int i;
5447 
5448 	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5449 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5450 }
5451 
5452 static void
5453 bwn_wa_agc(struct bwn_mac *mac)
5454 {
5455 	struct bwn_phy *phy = &mac->mac_phy;
5456 
5457 	if (phy->rev == 1) {
5458 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5459 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5460 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5461 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5462 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5463 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5464 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5465 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5466 		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5467 	} else {
5468 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5469 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5470 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5471 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5472 	}
5473 
5474 	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5475 	    0x5700);
5476 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5477 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5478 	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5479 	BWN_RF_SET(mac, 0x7a, 0x0008);
5480 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5481 	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5482 	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5483 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5484 	if (phy->rev == 1)
5485 		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5486 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5487 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5488 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5489 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5490 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5491 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5492 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5493 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5494 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5495 	if (phy->rev == 1) {
5496 		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5497 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5498 	} else {
5499 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5500 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5501 		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5502 		if (phy->rev >= 6) {
5503 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5504 			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5505 			    (uint16_t)~0xf000, 0x3000);
5506 		}
5507 	}
5508 	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5509 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5510 	if (phy->rev == 1) {
5511 		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5512 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5513 		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5514 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5515 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5516 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5517 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5518 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5519 	} else {
5520 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5521 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5522 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5523 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5524 	}
5525 	if (phy->rev >= 6) {
5526 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5527 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5528 	}
5529 	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5530 }
5531 
5532 static void
5533 bwn_wa_grev1(struct bwn_mac *mac)
5534 {
5535 	struct bwn_phy *phy = &mac->mac_phy;
5536 	int i;
5537 	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5538 	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5539 	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5540 
5541 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5542 
5543 	/* init CRSTHRES and ANTDWELL */
5544 	if (phy->rev == 1) {
5545 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5546 	} else if (phy->rev == 2) {
5547 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5548 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5549 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5550 	} else {
5551 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5552 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5553 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5554 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5555 	}
5556 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5557 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5558 	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5559 
5560 	/* XXX support PHY-A??? */
5561 	for (i = 0; i < N(bwn_tab_finefreqg); i++)
5562 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5563 		    bwn_tab_finefreqg[i]);
5564 
5565 	/* XXX support PHY-A??? */
5566 	if (phy->rev == 1)
5567 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5568 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5569 			    bwn_tab_noise_g1[i]);
5570 	else
5571 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5572 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5573 			    bwn_tab_noise_g2[i]);
5574 
5575 
5576 	for (i = 0; i < N(bwn_tab_rotor); i++)
5577 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5578 		    bwn_tab_rotor[i]);
5579 
5580 	/* XXX support PHY-A??? */
5581 	if (phy->rev >= 6) {
5582 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5583 		    BWN_PHY_ENCORE_EN)
5584 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5585 		else
5586 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5587 	} else
5588 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5589 
5590 	for (i = 0; i < N(bwn_tab_retard); i++)
5591 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5592 		    bwn_tab_retard[i]);
5593 
5594 	if (phy->rev == 1) {
5595 		for (i = 0; i < 16; i++)
5596 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5597 			    i, 0x0020);
5598 	} else {
5599 		for (i = 0; i < 32; i++)
5600 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5601 	}
5602 
5603 	bwn_wa_agc(mac);
5604 }
5605 
5606 static void
5607 bwn_wa_grev26789(struct bwn_mac *mac)
5608 {
5609 	struct bwn_phy *phy = &mac->mac_phy;
5610 	int i;
5611 	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5612 	uint16_t ofdmrev;
5613 
5614 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5615 
5616 	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5617 
5618 	/* init CRSTHRES and ANTDWELL */
5619 	if (phy->rev == 1)
5620 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5621 	else if (phy->rev == 2) {
5622 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5623 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5624 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5625 	} else {
5626 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5627 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5628 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5629 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5630 	}
5631 
5632 	for (i = 0; i < 64; i++)
5633 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5634 
5635 	/* XXX support PHY-A??? */
5636 	if (phy->rev == 1)
5637 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5638 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5639 			    bwn_tab_noise_g1[i]);
5640 	else
5641 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5642 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5643 			    bwn_tab_noise_g2[i]);
5644 
5645 	/* XXX support PHY-A??? */
5646 	if (phy->rev >= 6) {
5647 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5648 		    BWN_PHY_ENCORE_EN)
5649 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5650 		else
5651 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5652 	} else
5653 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5654 
5655 	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5656 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5657 		    bwn_tab_sigmasqr2[i]);
5658 
5659 	if (phy->rev == 1) {
5660 		for (i = 0; i < 16; i++)
5661 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5662 			    0x0020);
5663 	} else {
5664 		for (i = 0; i < 32; i++)
5665 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5666 	}
5667 
5668 	bwn_wa_agc(mac);
5669 
5670 	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5671 	if (ofdmrev > 2) {
5672 		if (phy->type == BWN_PHYTYPE_A)
5673 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5674 		else
5675 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5676 	} else {
5677 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5678 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5679 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5680 	}
5681 
5682 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5683 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5684 }
5685 
5686 static void
5687 bwn_wa_init(struct bwn_mac *mac)
5688 {
5689 	struct bwn_phy *phy = &mac->mac_phy;
5690 	struct bwn_softc *sc = mac->mac_sc;
5691 
5692 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5693 
5694 	switch (phy->rev) {
5695 	case 1:
5696 		bwn_wa_grev1(mac);
5697 		break;
5698 	case 2:
5699 	case 6:
5700 	case 7:
5701 	case 8:
5702 	case 9:
5703 		bwn_wa_grev26789(mac);
5704 		break;
5705 	default:
5706 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5707 	}
5708 
5709 	if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5710 	    siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5711 	    siba_get_pci_revid(sc->sc_dev) != 0x17) {
5712 		if (phy->rev < 2) {
5713 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5714 			    0x0002);
5715 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5716 			    0x0001);
5717 		} else {
5718 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5719 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5720 			if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5721 			     BWN_BFL_EXTLNA) &&
5722 			    (phy->rev >= 7)) {
5723 				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5724 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5725 				    0x0020, 0x0001);
5726 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5727 				    0x0021, 0x0001);
5728 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5729 				    0x0022, 0x0001);
5730 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5731 				    0x0023, 0x0000);
5732 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5733 				    0x0000, 0x0000);
5734 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5735 				    0x0003, 0x0002);
5736 			}
5737 		}
5738 	}
5739 	if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5740 		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5741 		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5742 	}
5743 
5744 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5745 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5746 }
5747 
5748 static void
5749 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5750     uint16_t value)
5751 {
5752 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5753 	uint16_t addr;
5754 
5755 	addr = table + offset;
5756 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5757 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5758 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5759 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5760 	}
5761 	pg->pg_ofdmtab_addr = addr;
5762 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5763 }
5764 
5765 static void
5766 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5767     uint32_t value)
5768 {
5769 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5770 	uint16_t addr;
5771 
5772 	addr = table + offset;
5773 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5774 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5775 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5776 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5777 	}
5778 	pg->pg_ofdmtab_addr = addr;
5779 
5780 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5781 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5782 }
5783 
5784 static void
5785 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5786     uint16_t value)
5787 {
5788 
5789 	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5790 	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5791 }
5792 
5793 static void
5794 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5795 {
5796 	struct bwn_phy *phy = &mac->mac_phy;
5797 	struct bwn_softc *sc = mac->mac_sc;
5798 	unsigned int i, max_loop;
5799 	uint16_t value;
5800 	uint32_t buffer[5] = {
5801 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5802 	};
5803 
5804 	if (ofdm) {
5805 		max_loop = 0x1e;
5806 		buffer[0] = 0x000201cc;
5807 	} else {
5808 		max_loop = 0xfa;
5809 		buffer[0] = 0x000b846e;
5810 	}
5811 
5812 	BWN_ASSERT_LOCKED(mac->mac_sc);
5813 
5814 	for (i = 0; i < 5; i++)
5815 		bwn_ram_write(mac, i * 4, buffer[i]);
5816 
5817 	BWN_WRITE_2(mac, 0x0568, 0x0000);
5818 	BWN_WRITE_2(mac, 0x07c0,
5819 	    (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5820 	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5821 	BWN_WRITE_2(mac, 0x050c, value);
5822 	if (phy->type == BWN_PHYTYPE_LP)
5823 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
5824 	BWN_WRITE_2(mac, 0x0508, 0x0000);
5825 	BWN_WRITE_2(mac, 0x050a, 0x0000);
5826 	BWN_WRITE_2(mac, 0x054c, 0x0000);
5827 	BWN_WRITE_2(mac, 0x056a, 0x0014);
5828 	BWN_WRITE_2(mac, 0x0568, 0x0826);
5829 	BWN_WRITE_2(mac, 0x0500, 0x0000);
5830 	if (phy->type == BWN_PHYTYPE_LP)
5831 		BWN_WRITE_2(mac, 0x0502, 0x0050);
5832 	else
5833 		BWN_WRITE_2(mac, 0x0502, 0x0030);
5834 
5835 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5836 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
5837 	for (i = 0x00; i < max_loop; i++) {
5838 		value = BWN_READ_2(mac, 0x050e);
5839 		if (value & 0x0080)
5840 			break;
5841 		DELAY(10);
5842 	}
5843 	for (i = 0x00; i < 0x0a; i++) {
5844 		value = BWN_READ_2(mac, 0x050e);
5845 		if (value & 0x0400)
5846 			break;
5847 		DELAY(10);
5848 	}
5849 	for (i = 0x00; i < 0x19; i++) {
5850 		value = BWN_READ_2(mac, 0x0690);
5851 		if (!(value & 0x0100))
5852 			break;
5853 		DELAY(10);
5854 	}
5855 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5856 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
5857 }
5858 
5859 static void
5860 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5861 {
5862 	uint32_t macctl;
5863 
5864 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5865 
5866 	macctl = BWN_READ_4(mac, BWN_MACCTL);
5867 	if (macctl & BWN_MACCTL_BIGENDIAN)
5868 		printf("TODO: need swap\n");
5869 
5870 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5871 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5872 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5873 }
5874 
5875 static void
5876 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5877 {
5878 	uint16_t value;
5879 
5880 	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5881 	    ("%s:%d: fail", __func__, __LINE__));
5882 
5883 	value = (uint8_t) (ctl->q);
5884 	value |= ((uint8_t) (ctl->i)) << 8;
5885 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5886 }
5887 
5888 static uint16_t
5889 bwn_lo_calcfeed(struct bwn_mac *mac,
5890     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5891 {
5892 	struct bwn_phy *phy = &mac->mac_phy;
5893 	struct bwn_softc *sc = mac->mac_sc;
5894 	uint16_t rfover;
5895 	uint16_t feedthrough;
5896 
5897 	if (phy->gmode) {
5898 		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5899 		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5900 
5901 		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5902 		    ("%s:%d: fail", __func__, __LINE__));
5903 		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5904 		    ("%s:%d: fail", __func__, __LINE__));
5905 
5906 		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5907 
5908 		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5909 		if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5910 		    phy->rev > 6)
5911 			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5912 
5913 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5914 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5915 		DELAY(10);
5916 		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5917 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5918 		DELAY(10);
5919 		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5920 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5921 		DELAY(10);
5922 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5923 	} else {
5924 		pga |= BWN_PHY_PGACTL_UNKNOWN;
5925 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5926 		DELAY(10);
5927 		pga |= BWN_PHY_PGACTL_LOWBANDW;
5928 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5929 		DELAY(10);
5930 		pga |= BWN_PHY_PGACTL_LPF;
5931 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5932 	}
5933 	DELAY(21);
5934 	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5935 
5936 	return (feedthrough);
5937 }
5938 
5939 static uint16_t
5940 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5941     uint16_t *value, uint16_t *pad_mix_gain)
5942 {
5943 	struct bwn_phy *phy = &mac->mac_phy;
5944 	uint16_t reg, v, padmix;
5945 
5946 	if (phy->type == BWN_PHYTYPE_B) {
5947 		v = 0x30;
5948 		if (phy->rf_rev <= 5) {
5949 			reg = 0x43;
5950 			padmix = 0;
5951 		} else {
5952 			reg = 0x52;
5953 			padmix = 5;
5954 		}
5955 	} else {
5956 		if (phy->rev >= 2 && phy->rf_rev == 8) {
5957 			reg = 0x43;
5958 			v = 0x10;
5959 			padmix = 2;
5960 		} else {
5961 			reg = 0x52;
5962 			v = 0x30;
5963 			padmix = 5;
5964 		}
5965 	}
5966 	if (value)
5967 		*value = v;
5968 	if (pad_mix_gain)
5969 		*pad_mix_gain = padmix;
5970 
5971 	return (reg);
5972 }
5973 
5974 static void
5975 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5976 {
5977 	struct bwn_phy *phy = &mac->mac_phy;
5978 	struct bwn_phy_g *pg = &phy->phy_g;
5979 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5980 	uint16_t reg, mask;
5981 	uint16_t trsw_rx, pga;
5982 	uint16_t rf_pctl_reg;
5983 
5984 	static const uint8_t tx_bias_values[] = {
5985 		0x09, 0x08, 0x0a, 0x01, 0x00,
5986 		0x02, 0x05, 0x04, 0x06,
5987 	};
5988 	static const uint8_t tx_magn_values[] = {
5989 		0x70, 0x40,
5990 	};
5991 
5992 	if (!BWN_HAS_LOOPBACK(phy)) {
5993 		rf_pctl_reg = 6;
5994 		trsw_rx = 2;
5995 		pga = 0;
5996 	} else {
5997 		int lb_gain;
5998 
5999 		trsw_rx = 0;
6000 		lb_gain = pg->pg_max_lb_gain / 2;
6001 		if (lb_gain > 10) {
6002 			rf_pctl_reg = 0;
6003 			pga = abs(10 - lb_gain) / 6;
6004 			pga = MIN(MAX(pga, 0), 15);
6005 		} else {
6006 			int cmp_val;
6007 			int tmp;
6008 
6009 			pga = 0;
6010 			cmp_val = 0x24;
6011 			if ((phy->rev >= 2) &&
6012 			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6013 				cmp_val = 0x3c;
6014 			tmp = lb_gain;
6015 			if ((10 - lb_gain) < cmp_val)
6016 				tmp = (10 - lb_gain);
6017 			if (tmp < 0)
6018 				tmp += 6;
6019 			else
6020 				tmp += 3;
6021 			cmp_val /= 4;
6022 			tmp /= 4;
6023 			if (tmp >= cmp_val)
6024 				rf_pctl_reg = cmp_val;
6025 			else
6026 				rf_pctl_reg = tmp;
6027 		}
6028 	}
6029 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6030 	bwn_phy_g_set_bbatt(mac, 2);
6031 
6032 	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6033 	mask = ~mask;
6034 	BWN_RF_MASK(mac, reg, mask);
6035 
6036 	if (BWN_HAS_TXMAG(phy)) {
6037 		int i, j;
6038 		int feedthrough;
6039 		int min_feedth = 0xffff;
6040 		uint8_t tx_magn, tx_bias;
6041 
6042 		for (i = 0; i < N(tx_magn_values); i++) {
6043 			tx_magn = tx_magn_values[i];
6044 			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6045 			for (j = 0; j < N(tx_bias_values); j++) {
6046 				tx_bias = tx_bias_values[j];
6047 				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6048 				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6049 				    trsw_rx);
6050 				if (feedthrough < min_feedth) {
6051 					lo->tx_bias = tx_bias;
6052 					lo->tx_magn = tx_magn;
6053 					min_feedth = feedthrough;
6054 				}
6055 				if (lo->tx_bias == 0)
6056 					break;
6057 			}
6058 			BWN_RF_WRITE(mac, 0x52,
6059 					  (BWN_RF_READ(mac, 0x52)
6060 					   & 0xff00) | lo->tx_bias | lo->
6061 					  tx_magn);
6062 		}
6063 	} else {
6064 		lo->tx_magn = 0;
6065 		lo->tx_bias = 0;
6066 		BWN_RF_MASK(mac, 0x52, 0xfff0);
6067 	}
6068 
6069 	BWN_GETTIME(lo->txctl_measured_time);
6070 }
6071 
6072 static void
6073 bwn_lo_get_powervector(struct bwn_mac *mac)
6074 {
6075 	struct bwn_phy *phy = &mac->mac_phy;
6076 	struct bwn_phy_g *pg = &phy->phy_g;
6077 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6078 	int i;
6079 	uint64_t tmp;
6080 	uint64_t power_vector = 0;
6081 
6082 	for (i = 0; i < 8; i += 2) {
6083 		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6084 		power_vector |= (tmp << (i * 8));
6085 		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6086 	}
6087 	if (power_vector)
6088 		lo->power_vector = power_vector;
6089 
6090 	BWN_GETTIME(lo->pwr_vec_read_time);
6091 }
6092 
6093 static void
6094 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6095     int use_trsw_rx)
6096 {
6097 	struct bwn_phy *phy = &mac->mac_phy;
6098 	struct bwn_phy_g *pg = &phy->phy_g;
6099 	uint16_t tmp;
6100 
6101 	if (max_rx_gain < 0)
6102 		max_rx_gain = 0;
6103 
6104 	if (BWN_HAS_LOOPBACK(phy)) {
6105 		int trsw_rx = 0;
6106 		int trsw_rx_gain;
6107 
6108 		if (use_trsw_rx) {
6109 			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6110 			if (max_rx_gain >= trsw_rx_gain) {
6111 				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6112 				trsw_rx = 0x20;
6113 			}
6114 		} else
6115 			trsw_rx_gain = max_rx_gain;
6116 		if (trsw_rx_gain < 9) {
6117 			pg->pg_lna_lod_gain = 0;
6118 		} else {
6119 			pg->pg_lna_lod_gain = 1;
6120 			trsw_rx_gain -= 8;
6121 		}
6122 		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6123 		pg->pg_pga_gain = trsw_rx_gain / 3;
6124 		if (pg->pg_pga_gain >= 5) {
6125 			pg->pg_pga_gain -= 5;
6126 			pg->pg_lna_gain = 2;
6127 		} else
6128 			pg->pg_lna_gain = 0;
6129 	} else {
6130 		pg->pg_lna_gain = 0;
6131 		pg->pg_trsw_rx_gain = 0x20;
6132 		if (max_rx_gain >= 0x14) {
6133 			pg->pg_lna_lod_gain = 1;
6134 			pg->pg_pga_gain = 2;
6135 		} else if (max_rx_gain >= 0x12) {
6136 			pg->pg_lna_lod_gain = 1;
6137 			pg->pg_pga_gain = 1;
6138 		} else if (max_rx_gain >= 0xf) {
6139 			pg->pg_lna_lod_gain = 1;
6140 			pg->pg_pga_gain = 0;
6141 		} else {
6142 			pg->pg_lna_lod_gain = 0;
6143 			pg->pg_pga_gain = 0;
6144 		}
6145 	}
6146 
6147 	tmp = BWN_RF_READ(mac, 0x7a);
6148 	if (pg->pg_lna_lod_gain == 0)
6149 		tmp &= ~0x0008;
6150 	else
6151 		tmp |= 0x0008;
6152 	BWN_RF_WRITE(mac, 0x7a, tmp);
6153 }
6154 
6155 static void
6156 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6157 {
6158 	struct bwn_phy *phy = &mac->mac_phy;
6159 	struct bwn_phy_g *pg = &phy->phy_g;
6160 	struct bwn_softc *sc = mac->mac_sc;
6161 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6162 	struct timespec ts;
6163 	uint16_t tmp;
6164 
6165 	if (bwn_has_hwpctl(mac)) {
6166 		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6167 		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6168 		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6169 		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6170 		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6171 
6172 		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6173 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6174 		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6175 		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6176 	}
6177 	if (phy->type == BWN_PHYTYPE_B &&
6178 	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6179 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6180 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6181 	}
6182 	if (phy->rev >= 2) {
6183 		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6184 		sav->phy_analogoverval =
6185 		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6186 		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6187 		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6188 		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6189 		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6190 		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6191 
6192 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6193 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6194 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6195 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6196 		if (phy->type == BWN_PHYTYPE_G) {
6197 			if ((phy->rev >= 7) &&
6198 			    (siba_sprom_get_bf_lo(sc->sc_dev) &
6199 			     BWN_BFL_EXTLNA)) {
6200 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6201 			} else {
6202 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6203 			}
6204 		} else {
6205 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6206 		}
6207 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6208 	}
6209 	sav->reg0 = BWN_READ_2(mac, 0x3f4);
6210 	sav->reg1 = BWN_READ_2(mac, 0x3e2);
6211 	sav->rf0 = BWN_RF_READ(mac, 0x43);
6212 	sav->rf1 = BWN_RF_READ(mac, 0x7a);
6213 	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6214 	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6215 	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6216 	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6217 
6218 	if (!BWN_HAS_TXMAG(phy)) {
6219 		sav->rf2 = BWN_RF_READ(mac, 0x52);
6220 		sav->rf2 &= 0x00f0;
6221 	}
6222 	if (phy->type == BWN_PHYTYPE_B) {
6223 		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6224 		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6225 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6226 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6227 	} else {
6228 		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6229 			    | 0x8000);
6230 	}
6231 	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6232 		    & 0xf000);
6233 
6234 	tmp =
6235 	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6236 	BWN_PHY_WRITE(mac, tmp, 0x007f);
6237 
6238 	tmp = sav->phy_syncctl;
6239 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6240 	tmp = sav->rf1;
6241 	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6242 
6243 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6244 	if (phy->type == BWN_PHYTYPE_G ||
6245 	    (phy->type == BWN_PHYTYPE_B &&
6246 	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6247 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6248 	} else
6249 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6250 	if (phy->rev >= 2)
6251 		bwn_dummy_transmission(mac, 0, 1);
6252 	bwn_phy_g_switch_chan(mac, 6, 0);
6253 	BWN_RF_READ(mac, 0x51);
6254 	if (phy->type == BWN_PHYTYPE_G)
6255 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6256 
6257 	nanouptime(&ts);
6258 	if (time_before(lo->txctl_measured_time,
6259 	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6260 		bwn_lo_measure_txctl_values(mac);
6261 
6262 	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6263 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6264 	else {
6265 		if (phy->type == BWN_PHYTYPE_B)
6266 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6267 		else
6268 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6269 	}
6270 }
6271 
6272 static void
6273 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6274 {
6275 	struct bwn_phy *phy = &mac->mac_phy;
6276 	struct bwn_phy_g *pg = &phy->phy_g;
6277 	uint16_t tmp;
6278 
6279 	if (phy->rev >= 2) {
6280 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6281 		tmp = (pg->pg_pga_gain << 8);
6282 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6283 		DELAY(5);
6284 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6285 		DELAY(2);
6286 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6287 	} else {
6288 		tmp = (pg->pg_pga_gain | 0xefa0);
6289 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6290 	}
6291 	if (phy->type == BWN_PHYTYPE_G) {
6292 		if (phy->rev >= 3)
6293 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6294 		else
6295 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6296 		if (phy->rev >= 2)
6297 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6298 		else
6299 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6300 	}
6301 	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6302 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6303 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6304 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6305 	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6306 	BWN_RF_WRITE(mac, 0x43, sav->rf0);
6307 	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6308 	if (!BWN_HAS_TXMAG(phy)) {
6309 		tmp = sav->rf2;
6310 		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6311 	}
6312 	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6313 	if (phy->type == BWN_PHYTYPE_B &&
6314 	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6315 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6316 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6317 	}
6318 	if (phy->rev >= 2) {
6319 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6320 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6321 			      sav->phy_analogoverval);
6322 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6323 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6324 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6325 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6326 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6327 	}
6328 	if (bwn_has_hwpctl(mac)) {
6329 		tmp = (sav->phy_lomask & 0xbfff);
6330 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6331 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6332 		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6333 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6334 		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6335 	}
6336 	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6337 }
6338 
6339 static int
6340 bwn_lo_probe_loctl(struct bwn_mac *mac,
6341     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6342 {
6343 	struct bwn_phy *phy = &mac->mac_phy;
6344 	struct bwn_phy_g *pg = &phy->phy_g;
6345 	struct bwn_loctl orig, test;
6346 	struct bwn_loctl prev = { -100, -100 };
6347 	static const struct bwn_loctl modifiers[] = {
6348 		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6349 		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6350 	};
6351 	int begin, end, lower = 0, i;
6352 	uint16_t feedth;
6353 
6354 	if (d->curstate == 0) {
6355 		begin = 1;
6356 		end = 8;
6357 	} else if (d->curstate % 2 == 0) {
6358 		begin = d->curstate - 1;
6359 		end = d->curstate + 1;
6360 	} else {
6361 		begin = d->curstate - 2;
6362 		end = d->curstate + 2;
6363 	}
6364 	if (begin < 1)
6365 		begin += 8;
6366 	if (end > 8)
6367 		end -= 8;
6368 
6369 	memcpy(&orig, probe, sizeof(struct bwn_loctl));
6370 	i = begin;
6371 	d->curstate = i;
6372 	while (1) {
6373 		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6374 		memcpy(&test, &orig, sizeof(struct bwn_loctl));
6375 		test.i += modifiers[i - 1].i * d->multipler;
6376 		test.q += modifiers[i - 1].q * d->multipler;
6377 		if ((test.i != prev.i || test.q != prev.q) &&
6378 		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6379 			bwn_lo_write(mac, &test);
6380 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6381 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6382 			if (feedth < d->feedth) {
6383 				memcpy(probe, &test,
6384 				    sizeof(struct bwn_loctl));
6385 				lower = 1;
6386 				d->feedth = feedth;
6387 				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6388 					break;
6389 			}
6390 		}
6391 		memcpy(&prev, &test, sizeof(prev));
6392 		if (i == end)
6393 			break;
6394 		if (i == 8)
6395 			i = 1;
6396 		else
6397 			i++;
6398 		d->curstate = i;
6399 	}
6400 
6401 	return (lower);
6402 }
6403 
6404 static void
6405 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6406 {
6407 	struct bwn_phy *phy = &mac->mac_phy;
6408 	struct bwn_phy_g *pg = &phy->phy_g;
6409 	struct bwn_lo_g_sm d;
6410 	struct bwn_loctl probe;
6411 	int lower, repeat, cnt = 0;
6412 	uint16_t feedth;
6413 
6414 	d.nmeasure = 0;
6415 	d.multipler = 1;
6416 	if (BWN_HAS_LOOPBACK(phy))
6417 		d.multipler = 3;
6418 
6419 	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6420 	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6421 
6422 	do {
6423 		bwn_lo_write(mac, &d.loctl);
6424 		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6425 		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6426 		if (feedth < 0x258) {
6427 			if (feedth >= 0x12c)
6428 				*rxgain += 6;
6429 			else
6430 				*rxgain += 3;
6431 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6432 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6433 		}
6434 		d.feedth = feedth;
6435 		d.curstate = 0;
6436 		do {
6437 			KASSERT(d.curstate >= 0 && d.curstate <= 8,
6438 			    ("%s:%d: fail", __func__, __LINE__));
6439 			memcpy(&probe, &d.loctl,
6440 			       sizeof(struct bwn_loctl));
6441 			lower = bwn_lo_probe_loctl(mac, &probe, &d);
6442 			if (!lower)
6443 				break;
6444 			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6445 				break;
6446 			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6447 			d.nmeasure++;
6448 		} while (d.nmeasure < 24);
6449 		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6450 
6451 		if (BWN_HAS_LOOPBACK(phy)) {
6452 			if (d.feedth > 0x1194)
6453 				*rxgain -= 6;
6454 			else if (d.feedth < 0x5dc)
6455 				*rxgain += 3;
6456 			if (cnt == 0) {
6457 				if (d.feedth <= 0x5dc) {
6458 					d.multipler = 1;
6459 					cnt++;
6460 				} else
6461 					d.multipler = 2;
6462 			} else if (cnt == 2)
6463 				d.multipler = 1;
6464 		}
6465 		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6466 	} while (++cnt < repeat);
6467 }
6468 
6469 static struct bwn_lo_calib *
6470 bwn_lo_calibset(struct bwn_mac *mac,
6471     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6472 {
6473 	struct bwn_phy *phy = &mac->mac_phy;
6474 	struct bwn_phy_g *pg = &phy->phy_g;
6475 	struct bwn_loctl loctl = { 0, 0 };
6476 	struct bwn_lo_calib *cal;
6477 	struct bwn_lo_g_value sval = { 0 };
6478 	int rxgain;
6479 	uint16_t pad, reg, value;
6480 
6481 	sval.old_channel = phy->chan;
6482 	bwn_mac_suspend(mac);
6483 	bwn_lo_save(mac, &sval);
6484 
6485 	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6486 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6487 	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6488 
6489 	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6490 	if (rfatt->padmix)
6491 		rxgain -= pad;
6492 	if (BWN_HAS_LOOPBACK(phy))
6493 		rxgain += pg->pg_max_lb_gain;
6494 	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6495 	bwn_phy_g_set_bbatt(mac, bbatt->att);
6496 	bwn_lo_probe_sm(mac, &loctl, &rxgain);
6497 
6498 	bwn_lo_restore(mac, &sval);
6499 	bwn_mac_enable(mac);
6500 
6501 	cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6502 	if (!cal) {
6503 		device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6504 		return (NULL);
6505 	}
6506 	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6507 	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6508 	memcpy(&cal->ctl, &loctl, sizeof(loctl));
6509 
6510 	BWN_GETTIME(cal->calib_time);
6511 
6512 	return (cal);
6513 }
6514 
6515 static struct bwn_lo_calib *
6516 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6517     const struct bwn_rfatt *rfatt)
6518 {
6519 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6520 	struct bwn_lo_calib *c;
6521 
6522 	TAILQ_FOREACH(c, &lo->calib_list, list) {
6523 		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6524 			continue;
6525 		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6526 			continue;
6527 		return (c);
6528 	}
6529 
6530 	c = bwn_lo_calibset(mac, bbatt, rfatt);
6531 	if (!c)
6532 		return (NULL);
6533 	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6534 
6535 	return (c);
6536 }
6537 
6538 static void
6539 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6540 {
6541 	struct bwn_phy *phy = &mac->mac_phy;
6542 	struct bwn_phy_g *pg = &phy->phy_g;
6543 	struct bwn_softc *sc = mac->mac_sc;
6544 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6545 	const struct bwn_rfatt *rfatt;
6546 	const struct bwn_bbatt *bbatt;
6547 	uint64_t pvector;
6548 	int i;
6549 	int rf_offset, bb_offset;
6550 	uint8_t changed = 0;
6551 
6552 	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6553 	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6554 	    ("%s:%d: fail", __func__, __LINE__));
6555 
6556 	pvector = lo->power_vector;
6557 	if (!update && !pvector)
6558 		return;
6559 
6560 	bwn_mac_suspend(mac);
6561 
6562 	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6563 		struct bwn_lo_calib *cal;
6564 		int idx;
6565 		uint16_t val;
6566 
6567 		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6568 			continue;
6569 		bb_offset = i / lo->rfatt.len;
6570 		rf_offset = i % lo->rfatt.len;
6571 		bbatt = &(lo->bbatt.array[bb_offset]);
6572 		rfatt = &(lo->rfatt.array[rf_offset]);
6573 
6574 		cal = bwn_lo_calibset(mac, bbatt, rfatt);
6575 		if (!cal) {
6576 			device_printf(sc->sc_dev, "LO: Could not "
6577 			    "calibrate DC table entry\n");
6578 			continue;
6579 		}
6580 		val = (uint8_t)(cal->ctl.q);
6581 		val |= ((uint8_t)(cal->ctl.i)) << 4;
6582 		free(cal, M_DEVBUF);
6583 
6584 		idx = i / 2;
6585 		if (i % 2)
6586 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6587 			    | ((val & 0x00ff) << 8);
6588 		else
6589 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6590 			    | (val & 0x00ff);
6591 		changed = 1;
6592 	}
6593 	if (changed) {
6594 		for (i = 0; i < BWN_DC_LT_SIZE; i++)
6595 			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6596 	}
6597 	bwn_mac_enable(mac);
6598 }
6599 
6600 static void
6601 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6602 {
6603 
6604 	if (!rf->padmix)
6605 		return;
6606 	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6607 		rf->att = 4;
6608 }
6609 
6610 static void
6611 bwn_lo_g_adjust(struct bwn_mac *mac)
6612 {
6613 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6614 	struct bwn_lo_calib *cal;
6615 	struct bwn_rfatt rf;
6616 
6617 	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6618 	bwn_lo_fixup_rfatt(&rf);
6619 
6620 	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6621 	if (!cal)
6622 		return;
6623 	bwn_lo_write(mac, &cal->ctl);
6624 }
6625 
6626 static void
6627 bwn_lo_g_init(struct bwn_mac *mac)
6628 {
6629 
6630 	if (!bwn_has_hwpctl(mac))
6631 		return;
6632 
6633 	bwn_lo_get_powervector(mac);
6634 	bwn_phy_g_dc_lookup_init(mac, 1);
6635 }
6636 
6637 static void
6638 bwn_mac_suspend(struct bwn_mac *mac)
6639 {
6640 	struct bwn_softc *sc = mac->mac_sc;
6641 	int i;
6642 	uint32_t tmp;
6643 
6644 	KASSERT(mac->mac_suspended >= 0,
6645 	    ("%s:%d: fail", __func__, __LINE__));
6646 
6647 	if (mac->mac_suspended == 0) {
6648 		bwn_psctl(mac, BWN_PS_AWAKE);
6649 		BWN_WRITE_4(mac, BWN_MACCTL,
6650 			    BWN_READ_4(mac, BWN_MACCTL)
6651 			    & ~BWN_MACCTL_ON);
6652 		BWN_READ_4(mac, BWN_MACCTL);
6653 		for (i = 35; i; i--) {
6654 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6655 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6656 				goto out;
6657 			DELAY(10);
6658 		}
6659 		for (i = 40; i; i--) {
6660 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6661 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6662 				goto out;
6663 			DELAY(1000);
6664 		}
6665 		device_printf(sc->sc_dev, "MAC suspend failed\n");
6666 	}
6667 out:
6668 	mac->mac_suspended++;
6669 }
6670 
6671 static void
6672 bwn_mac_enable(struct bwn_mac *mac)
6673 {
6674 	struct bwn_softc *sc = mac->mac_sc;
6675 	uint16_t state;
6676 
6677 	state = bwn_shm_read_2(mac, BWN_SHARED,
6678 	    BWN_SHARED_UCODESTAT);
6679 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6680 	    state != BWN_SHARED_UCODESTAT_SLEEP)
6681 		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6682 
6683 	mac->mac_suspended--;
6684 	KASSERT(mac->mac_suspended >= 0,
6685 	    ("%s:%d: fail", __func__, __LINE__));
6686 	if (mac->mac_suspended == 0) {
6687 		BWN_WRITE_4(mac, BWN_MACCTL,
6688 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6689 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6690 		BWN_READ_4(mac, BWN_MACCTL);
6691 		BWN_READ_4(mac, BWN_INTR_REASON);
6692 		bwn_psctl(mac, 0);
6693 	}
6694 }
6695 
6696 static void
6697 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6698 {
6699 	struct bwn_softc *sc = mac->mac_sc;
6700 	int i;
6701 	uint16_t ucstat;
6702 
6703 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6704 	    ("%s:%d: fail", __func__, __LINE__));
6705 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6706 	    ("%s:%d: fail", __func__, __LINE__));
6707 
6708 	/* XXX forcibly awake and hwps-off */
6709 
6710 	BWN_WRITE_4(mac, BWN_MACCTL,
6711 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6712 	    ~BWN_MACCTL_HWPS);
6713 	BWN_READ_4(mac, BWN_MACCTL);
6714 	if (siba_get_revid(sc->sc_dev) >= 5) {
6715 		for (i = 0; i < 100; i++) {
6716 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6717 			    BWN_SHARED_UCODESTAT);
6718 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6719 				break;
6720 			DELAY(10);
6721 		}
6722 	}
6723 }
6724 
6725 static int16_t
6726 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6727 {
6728 
6729 	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6730 	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6731 }
6732 
6733 static void
6734 bwn_nrssi_threshold(struct bwn_mac *mac)
6735 {
6736 	struct bwn_phy *phy = &mac->mac_phy;
6737 	struct bwn_phy_g *pg = &phy->phy_g;
6738 	struct bwn_softc *sc = mac->mac_sc;
6739 	int32_t a, b;
6740 	int16_t tmp16;
6741 	uint16_t tmpu16;
6742 
6743 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6744 
6745 	if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6746 		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6747 			a = 0x13;
6748 			b = 0x12;
6749 		} else {
6750 			a = 0xe;
6751 			b = 0x11;
6752 		}
6753 
6754 		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6755 		a += (pg->pg_nrssi[0] << 6);
6756 		a += (a < 32) ? 31 : 32;
6757 		a = a >> 6;
6758 		a = MIN(MAX(a, -31), 31);
6759 
6760 		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6761 		b += (pg->pg_nrssi[0] << 6);
6762 		if (b < 32)
6763 			b += 31;
6764 		else
6765 			b += 32;
6766 		b = b >> 6;
6767 		b = MIN(MAX(b, -31), 31);
6768 
6769 		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6770 		tmpu16 |= ((uint32_t)b & 0x0000003f);
6771 		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6772 		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6773 		return;
6774 	}
6775 
6776 	tmp16 = bwn_nrssi_read(mac, 0x20);
6777 	if (tmp16 >= 0x20)
6778 		tmp16 -= 0x40;
6779 	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6780 }
6781 
6782 static void
6783 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6784 {
6785 #define	SAVE_RF_MAX		3
6786 #define	SAVE_PHY_COMM_MAX	4
6787 #define	SAVE_PHY3_MAX		8
6788 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6789 		{ 0x7a, 0x52, 0x43 };
6790 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6791 		{ 0x15, 0x5a, 0x59, 0x58 };
6792 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6793 		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6794 		0x0801, 0x0060, 0x0014, 0x0478
6795 	};
6796 	struct bwn_phy *phy = &mac->mac_phy;
6797 	struct bwn_phy_g *pg = &phy->phy_g;
6798 	int32_t i, tmp32, phy3_idx = 0;
6799 	uint16_t delta, tmp;
6800 	uint16_t save_rf[SAVE_RF_MAX];
6801 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6802 	uint16_t save_phy3[SAVE_PHY3_MAX];
6803 	uint16_t ant_div, phy0, chan_ex;
6804 	int16_t nrssi0, nrssi1;
6805 
6806 	KASSERT(phy->type == BWN_PHYTYPE_G,
6807 	    ("%s:%d: fail", __func__, __LINE__));
6808 
6809 	if (phy->rf_rev >= 9)
6810 		return;
6811 	if (phy->rf_rev == 8)
6812 		bwn_nrssi_offset(mac);
6813 
6814 	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6815 	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6816 
6817 	/*
6818 	 * Save RF/PHY registers for later restoration
6819 	 */
6820 	ant_div = BWN_READ_2(mac, 0x03e2);
6821 	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6822 	for (i = 0; i < SAVE_RF_MAX; ++i)
6823 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6824 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6825 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6826 
6827 	phy0 = BWN_READ_2(mac, BWN_PHY0);
6828 	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6829 	if (phy->rev >= 3) {
6830 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
6831 			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6832 		BWN_PHY_WRITE(mac, 0x002e, 0);
6833 		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6834 		switch (phy->rev) {
6835 		case 4:
6836 		case 6:
6837 		case 7:
6838 			BWN_PHY_SET(mac, 0x0478, 0x0100);
6839 			BWN_PHY_SET(mac, 0x0801, 0x0040);
6840 			break;
6841 		case 3:
6842 		case 5:
6843 			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6844 			break;
6845 		}
6846 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6847 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6848 	}
6849 	/*
6850 	 * Calculate nrssi0
6851 	 */
6852 	BWN_RF_SET(mac, 0x007a, 0x0070);
6853 	bwn_set_all_gains(mac, 0, 8, 0);
6854 	BWN_RF_MASK(mac, 0x007a, 0x00f7);
6855 	if (phy->rev >= 2) {
6856 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6857 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6858 	}
6859 	BWN_RF_SET(mac, 0x007a, 0x0080);
6860 	DELAY(20);
6861 
6862 	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6863 	if (nrssi0 >= 0x0020)
6864 		nrssi0 -= 0x0040;
6865 
6866 	/*
6867 	 * Calculate nrssi1
6868 	 */
6869 	BWN_RF_MASK(mac, 0x007a, 0x007f);
6870 	if (phy->rev >= 2)
6871 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6872 
6873 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6874 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6875 	BWN_RF_SET(mac, 0x007a, 0x000f);
6876 	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6877 	if (phy->rev >= 2) {
6878 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6879 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6880 	}
6881 
6882 	bwn_set_all_gains(mac, 3, 0, 1);
6883 	if (phy->rf_rev == 8) {
6884 		BWN_RF_WRITE(mac, 0x0043, 0x001f);
6885 	} else {
6886 		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6887 		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6888 		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6889 		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6890 	}
6891 	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6892 	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6893 	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6894 	DELAY(20);
6895 	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6896 
6897 	/*
6898 	 * Install calculated narrow RSSI values
6899 	 */
6900 	if (nrssi1 >= 0x0020)
6901 		nrssi1 -= 0x0040;
6902 	if (nrssi0 == nrssi1)
6903 		pg->pg_nrssi_slope = 0x00010000;
6904 	else
6905 		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6906 	if (nrssi0 >= -4) {
6907 		pg->pg_nrssi[0] = nrssi1;
6908 		pg->pg_nrssi[1] = nrssi0;
6909 	}
6910 
6911 	/*
6912 	 * Restore saved RF/PHY registers
6913 	 */
6914 	if (phy->rev >= 3) {
6915 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6916 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6917 			    save_phy3[phy3_idx]);
6918 		}
6919 	}
6920 	if (phy->rev >= 2) {
6921 		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6922 		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6923 	}
6924 
6925 	for (i = 0; i < SAVE_RF_MAX; ++i)
6926 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6927 
6928 	BWN_WRITE_2(mac, 0x03e2, ant_div);
6929 	BWN_WRITE_2(mac, 0x03e6, phy0);
6930 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6931 
6932 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6933 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6934 
6935 	bwn_spu_workaround(mac, phy->chan);
6936 	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6937 	bwn_set_original_gains(mac);
6938 	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6939 	if (phy->rev >= 3) {
6940 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6941 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6942 			    save_phy3[phy3_idx]);
6943 		}
6944 	}
6945 
6946 	delta = 0x1f - pg->pg_nrssi[0];
6947 	for (i = 0; i < 64; i++) {
6948 		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6949 		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6950 		pg->pg_nrssi_lt[i] = tmp32;
6951 	}
6952 
6953 	bwn_nrssi_threshold(mac);
6954 #undef SAVE_RF_MAX
6955 #undef SAVE_PHY_COMM_MAX
6956 #undef SAVE_PHY3_MAX
6957 }
6958 
6959 static void
6960 bwn_nrssi_offset(struct bwn_mac *mac)
6961 {
6962 #define	SAVE_RF_MAX		2
6963 #define	SAVE_PHY_COMM_MAX	10
6964 #define	SAVE_PHY6_MAX		8
6965 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6966 		{ 0x7a, 0x43 };
6967 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6968 		0x0001, 0x0811, 0x0812, 0x0814,
6969 		0x0815, 0x005a, 0x0059, 0x0058,
6970 		0x000a, 0x0003
6971 	};
6972 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6973 		0x002e, 0x002f, 0x080f, 0x0810,
6974 		0x0801, 0x0060, 0x0014, 0x0478
6975 	};
6976 	struct bwn_phy *phy = &mac->mac_phy;
6977 	int i, phy6_idx = 0;
6978 	uint16_t save_rf[SAVE_RF_MAX];
6979 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6980 	uint16_t save_phy6[SAVE_PHY6_MAX];
6981 	int16_t nrssi;
6982 	uint16_t saved = 0xffff;
6983 
6984 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6985 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6986 	for (i = 0; i < SAVE_RF_MAX; ++i)
6987 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6988 
6989 	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6990 	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6991 	BWN_PHY_SET(mac, 0x0811, 0x000c);
6992 	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6993 	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6994 	if (phy->rev >= 6) {
6995 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
6996 			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6997 
6998 		BWN_PHY_WRITE(mac, 0x002e, 0);
6999 		BWN_PHY_WRITE(mac, 0x002f, 0);
7000 		BWN_PHY_WRITE(mac, 0x080f, 0);
7001 		BWN_PHY_WRITE(mac, 0x0810, 0);
7002 		BWN_PHY_SET(mac, 0x0478, 0x0100);
7003 		BWN_PHY_SET(mac, 0x0801, 0x0040);
7004 		BWN_PHY_SET(mac, 0x0060, 0x0040);
7005 		BWN_PHY_SET(mac, 0x0014, 0x0200);
7006 	}
7007 	BWN_RF_SET(mac, 0x007a, 0x0070);
7008 	BWN_RF_SET(mac, 0x007a, 0x0080);
7009 	DELAY(30);
7010 
7011 	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7012 	if (nrssi >= 0x20)
7013 		nrssi -= 0x40;
7014 	if (nrssi == 31) {
7015 		for (i = 7; i >= 4; i--) {
7016 			BWN_RF_WRITE(mac, 0x007b, i);
7017 			DELAY(20);
7018 			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7019 			    0x003f);
7020 			if (nrssi >= 0x20)
7021 				nrssi -= 0x40;
7022 			if (nrssi < 31 && saved == 0xffff)
7023 				saved = i;
7024 		}
7025 		if (saved == 0xffff)
7026 			saved = 4;
7027 	} else {
7028 		BWN_RF_MASK(mac, 0x007a, 0x007f);
7029 		if (phy->rev != 1) {
7030 			BWN_PHY_SET(mac, 0x0814, 0x0001);
7031 			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7032 		}
7033 		BWN_PHY_SET(mac, 0x0811, 0x000c);
7034 		BWN_PHY_SET(mac, 0x0812, 0x000c);
7035 		BWN_PHY_SET(mac, 0x0811, 0x0030);
7036 		BWN_PHY_SET(mac, 0x0812, 0x0030);
7037 		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7038 		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7039 		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7040 		if (phy->rev == 0)
7041 			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7042 		else
7043 			BWN_PHY_SET(mac, 0x000a, 0x2000);
7044 		if (phy->rev != 1) {
7045 			BWN_PHY_SET(mac, 0x0814, 0x0004);
7046 			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7047 		}
7048 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7049 		BWN_RF_SET(mac, 0x007a, 0x000f);
7050 		bwn_set_all_gains(mac, 3, 0, 1);
7051 		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7052 		DELAY(30);
7053 		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7054 		if (nrssi >= 0x20)
7055 			nrssi -= 0x40;
7056 		if (nrssi == -32) {
7057 			for (i = 0; i < 4; i++) {
7058 				BWN_RF_WRITE(mac, 0x007b, i);
7059 				DELAY(20);
7060 				nrssi = (int16_t)((BWN_PHY_READ(mac,
7061 				    0x047f) >> 8) & 0x003f);
7062 				if (nrssi >= 0x20)
7063 					nrssi -= 0x40;
7064 				if (nrssi > -31 && saved == 0xffff)
7065 					saved = i;
7066 			}
7067 			if (saved == 0xffff)
7068 				saved = 3;
7069 		} else
7070 			saved = 0;
7071 	}
7072 	BWN_RF_WRITE(mac, 0x007b, saved);
7073 
7074 	/*
7075 	 * Restore saved RF/PHY registers
7076 	 */
7077 	if (phy->rev >= 6) {
7078 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7079 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7080 			    save_phy6[phy6_idx]);
7081 		}
7082 	}
7083 	if (phy->rev != 1) {
7084 		for (i = 3; i < 5; i++)
7085 			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7086 			    save_phy_comm[i]);
7087 	}
7088 	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7089 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7090 
7091 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7092 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7093 
7094 	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7095 	BWN_PHY_SET(mac, 0x0429, 0x8000);
7096 	bwn_set_original_gains(mac);
7097 	if (phy->rev >= 6) {
7098 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7099 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7100 			    save_phy6[phy6_idx]);
7101 		}
7102 	}
7103 
7104 	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7105 	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7106 	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7107 }
7108 
7109 static void
7110 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7111     int16_t third)
7112 {
7113 	struct bwn_phy *phy = &mac->mac_phy;
7114 	uint16_t i;
7115 	uint16_t start = 0x08, end = 0x18;
7116 	uint16_t tmp;
7117 	uint16_t table;
7118 
7119 	if (phy->rev <= 1) {
7120 		start = 0x10;
7121 		end = 0x20;
7122 	}
7123 
7124 	table = BWN_OFDMTAB_GAINX;
7125 	if (phy->rev <= 1)
7126 		table = BWN_OFDMTAB_GAINX_R1;
7127 	for (i = 0; i < 4; i++)
7128 		bwn_ofdmtab_write_2(mac, table, i, first);
7129 
7130 	for (i = start; i < end; i++)
7131 		bwn_ofdmtab_write_2(mac, table, i, second);
7132 
7133 	if (third != -1) {
7134 		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7135 		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7136 		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7137 		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7138 	}
7139 	bwn_dummy_transmission(mac, 0, 1);
7140 }
7141 
7142 static void
7143 bwn_set_original_gains(struct bwn_mac *mac)
7144 {
7145 	struct bwn_phy *phy = &mac->mac_phy;
7146 	uint16_t i, tmp;
7147 	uint16_t table;
7148 	uint16_t start = 0x0008, end = 0x0018;
7149 
7150 	if (phy->rev <= 1) {
7151 		start = 0x0010;
7152 		end = 0x0020;
7153 	}
7154 
7155 	table = BWN_OFDMTAB_GAINX;
7156 	if (phy->rev <= 1)
7157 		table = BWN_OFDMTAB_GAINX_R1;
7158 	for (i = 0; i < 4; i++) {
7159 		tmp = (i & 0xfffc);
7160 		tmp |= (i & 0x0001) << 1;
7161 		tmp |= (i & 0x0002) >> 1;
7162 
7163 		bwn_ofdmtab_write_2(mac, table, i, tmp);
7164 	}
7165 
7166 	for (i = start; i < end; i++)
7167 		bwn_ofdmtab_write_2(mac, table, i, i - start);
7168 
7169 	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7170 	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7171 	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7172 	bwn_dummy_transmission(mac, 0, 1);
7173 }
7174 
7175 static void
7176 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7177 {
7178 	struct bwn_phy *phy = &mac->mac_phy;
7179 	struct bwn_phy_g *pg = &phy->phy_g;
7180 	struct bwn_rfatt old_rfatt, rfatt;
7181 	struct bwn_bbatt old_bbatt, bbatt;
7182 	struct bwn_softc *sc = mac->mac_sc;
7183 	uint8_t old_txctl = 0;
7184 
7185 	KASSERT(phy->type == BWN_PHYTYPE_G,
7186 	    ("%s:%d: fail", __func__, __LINE__));
7187 
7188 	if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7189 	    (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7190 		return;
7191 
7192 	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7193 
7194 	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7195 
7196 	if (!phy->gmode)
7197 		return;
7198 	bwn_hwpctl_early_init(mac);
7199 	if (pg->pg_curtssi == 0) {
7200 		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7201 			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7202 		} else {
7203 			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7204 			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7205 			old_txctl = pg->pg_txctl;
7206 
7207 			bbatt.att = 11;
7208 			if (phy->rf_rev == 8) {
7209 				rfatt.att = 15;
7210 				rfatt.padmix = 1;
7211 			} else {
7212 				rfatt.att = 9;
7213 				rfatt.padmix = 0;
7214 			}
7215 			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7216 		}
7217 		bwn_dummy_transmission(mac, 0, 1);
7218 		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7219 		if (phy->rf_ver == 0x2050 && phy->analog == 0)
7220 			BWN_RF_MASK(mac, 0x0076, 0xff7b);
7221 		else
7222 			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7223 			    &old_rfatt, old_txctl);
7224 	}
7225 	bwn_hwpctl_init_gphy(mac);
7226 
7227 	/* clear TSSI */
7228 	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7229 	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7230 	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7231 	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7232 }
7233 
7234 static void
7235 bwn_hwpctl_early_init(struct bwn_mac *mac)
7236 {
7237 	struct bwn_phy *phy = &mac->mac_phy;
7238 
7239 	if (!bwn_has_hwpctl(mac)) {
7240 		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7241 		return;
7242 	}
7243 
7244 	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7245 	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7246 	BWN_PHY_SET(mac, 0x047c, 0x0002);
7247 	BWN_PHY_SET(mac, 0x047a, 0xf000);
7248 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7249 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7250 		BWN_PHY_SET(mac, 0x005d, 0x8000);
7251 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7252 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7253 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7254 	} else {
7255 		BWN_PHY_SET(mac, 0x0036, 0x0200);
7256 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7257 		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7258 		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7259 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7260 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7261 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7262 	}
7263 }
7264 
7265 static void
7266 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7267 {
7268 	struct bwn_phy *phy = &mac->mac_phy;
7269 	struct bwn_phy_g *pg = &phy->phy_g;
7270 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7271 	int i;
7272 	uint16_t nr_written = 0, tmp, value;
7273 	uint8_t rf, bb;
7274 
7275 	if (!bwn_has_hwpctl(mac)) {
7276 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7277 		return;
7278 	}
7279 
7280 	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7281 	    (pg->pg_idletssi - pg->pg_curtssi));
7282 	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7283 	    (pg->pg_idletssi - pg->pg_curtssi));
7284 
7285 	for (i = 0; i < 32; i++)
7286 		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7287 	for (i = 32; i < 64; i++)
7288 		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7289 	for (i = 0; i < 64; i += 2) {
7290 		value = (uint16_t) pg->pg_tssi2dbm[i];
7291 		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7292 		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7293 	}
7294 
7295 	for (rf = 0; rf < lo->rfatt.len; rf++) {
7296 		for (bb = 0; bb < lo->bbatt.len; bb++) {
7297 			if (nr_written >= 0x40)
7298 				return;
7299 			tmp = lo->bbatt.array[bb].att;
7300 			tmp <<= 8;
7301 			if (phy->rf_rev == 8)
7302 				tmp |= 0x50;
7303 			else
7304 				tmp |= 0x40;
7305 			tmp |= lo->rfatt.array[rf].att;
7306 			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7307 			nr_written++;
7308 		}
7309 	}
7310 
7311 	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7312 	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7313 
7314 	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7315 	BWN_PHY_SET(mac, 0x0478, 0x0800);
7316 	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7317 	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7318 
7319 	bwn_phy_g_dc_lookup_init(mac, 1);
7320 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7321 }
7322 
7323 static void
7324 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7325 {
7326 	struct bwn_softc *sc = mac->mac_sc;
7327 
7328 	if (spu != 0)
7329 		bwn_spu_workaround(mac, channel);
7330 
7331 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7332 
7333 	if (channel == 14) {
7334 		if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7335 			bwn_hf_write(mac,
7336 			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7337 		else
7338 			bwn_hf_write(mac,
7339 			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7340 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7341 		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7342 		return;
7343 	}
7344 
7345 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7346 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7347 }
7348 
7349 static uint16_t
7350 bwn_phy_g_chan2freq(uint8_t channel)
7351 {
7352 	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7353 
7354 	KASSERT(channel >= 1 && channel <= 14,
7355 	    ("%s:%d: fail", __func__, __LINE__));
7356 
7357 	return (bwn_phy_g_rf_channels[channel - 1]);
7358 }
7359 
7360 static void
7361 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7362     const struct bwn_rfatt *rfatt, uint8_t txctl)
7363 {
7364 	struct bwn_phy *phy = &mac->mac_phy;
7365 	struct bwn_phy_g *pg = &phy->phy_g;
7366 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7367 	uint16_t bb, rf;
7368 	uint16_t tx_bias, tx_magn;
7369 
7370 	bb = bbatt->att;
7371 	rf = rfatt->att;
7372 	tx_bias = lo->tx_bias;
7373 	tx_magn = lo->tx_magn;
7374 	if (tx_bias == 0xff)
7375 		tx_bias = 0;
7376 
7377 	pg->pg_txctl = txctl;
7378 	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7379 	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7380 	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7381 	bwn_phy_g_set_bbatt(mac, bb);
7382 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7383 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7384 		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7385 	else {
7386 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7387 		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7388 	}
7389 	if (BWN_HAS_TXMAG(phy))
7390 		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7391 	else
7392 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7393 	bwn_lo_g_adjust(mac);
7394 }
7395 
7396 static void
7397 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7398     uint16_t bbatt)
7399 {
7400 	struct bwn_phy *phy = &mac->mac_phy;
7401 
7402 	if (phy->analog == 0) {
7403 		BWN_WRITE_2(mac, BWN_PHY0,
7404 		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7405 		return;
7406 	}
7407 	if (phy->analog > 1) {
7408 		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7409 		return;
7410 	}
7411 	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7412 }
7413 
7414 static uint16_t
7415 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7416 {
7417 	struct bwn_phy *phy = &mac->mac_phy;
7418 	struct bwn_phy_g *pg = &phy->phy_g;
7419 	struct bwn_softc *sc = mac->mac_sc;
7420 	int max_lb_gain;
7421 	uint16_t extlna;
7422 	uint16_t i;
7423 
7424 	if (phy->gmode == 0)
7425 		return (0);
7426 
7427 	if (BWN_HAS_LOOPBACK(phy)) {
7428 		max_lb_gain = pg->pg_max_lb_gain;
7429 		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7430 		if (max_lb_gain >= 0x46) {
7431 			extlna = 0x3000;
7432 			max_lb_gain -= 0x46;
7433 		} else if (max_lb_gain >= 0x3a) {
7434 			extlna = 0x1000;
7435 			max_lb_gain -= 0x3a;
7436 		} else if (max_lb_gain >= 0x2e) {
7437 			extlna = 0x2000;
7438 			max_lb_gain -= 0x2e;
7439 		} else {
7440 			extlna = 0;
7441 			max_lb_gain -= 0x10;
7442 		}
7443 
7444 		for (i = 0; i < 16; i++) {
7445 			max_lb_gain -= (i * 6);
7446 			if (max_lb_gain < 6)
7447 				break;
7448 		}
7449 
7450 		if ((phy->rev < 7) ||
7451 		    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7452 			if (reg == BWN_PHY_RFOVER) {
7453 				return (0x1b3);
7454 			} else if (reg == BWN_PHY_RFOVERVAL) {
7455 				extlna |= (i << 8);
7456 				switch (lpd) {
7457 				case BWN_LPD(0, 1, 1):
7458 					return (0x0f92);
7459 				case BWN_LPD(0, 0, 1):
7460 				case BWN_LPD(1, 0, 1):
7461 					return (0x0092 | extlna);
7462 				case BWN_LPD(1, 0, 0):
7463 					return (0x0093 | extlna);
7464 				}
7465 				KASSERT(0 == 1,
7466 				    ("%s:%d: fail", __func__, __LINE__));
7467 			}
7468 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7469 		} else {
7470 			if (reg == BWN_PHY_RFOVER)
7471 				return (0x9b3);
7472 			if (reg == BWN_PHY_RFOVERVAL) {
7473 				if (extlna)
7474 					extlna |= 0x8000;
7475 				extlna |= (i << 8);
7476 				switch (lpd) {
7477 				case BWN_LPD(0, 1, 1):
7478 					return (0x8f92);
7479 				case BWN_LPD(0, 0, 1):
7480 					return (0x8092 | extlna);
7481 				case BWN_LPD(1, 0, 1):
7482 					return (0x2092 | extlna);
7483 				case BWN_LPD(1, 0, 0):
7484 					return (0x2093 | extlna);
7485 				}
7486 				KASSERT(0 == 1,
7487 				    ("%s:%d: fail", __func__, __LINE__));
7488 			}
7489 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7490 		}
7491 		return (0);
7492 	}
7493 
7494 	if ((phy->rev < 7) ||
7495 	    !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7496 		if (reg == BWN_PHY_RFOVER) {
7497 			return (0x1b3);
7498 		} else if (reg == BWN_PHY_RFOVERVAL) {
7499 			switch (lpd) {
7500 			case BWN_LPD(0, 1, 1):
7501 				return (0x0fb2);
7502 			case BWN_LPD(0, 0, 1):
7503 				return (0x00b2);
7504 			case BWN_LPD(1, 0, 1):
7505 				return (0x30b2);
7506 			case BWN_LPD(1, 0, 0):
7507 				return (0x30b3);
7508 			}
7509 			KASSERT(0 == 1,
7510 			    ("%s:%d: fail", __func__, __LINE__));
7511 		}
7512 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7513 	} else {
7514 		if (reg == BWN_PHY_RFOVER) {
7515 			return (0x9b3);
7516 		} else if (reg == BWN_PHY_RFOVERVAL) {
7517 			switch (lpd) {
7518 			case BWN_LPD(0, 1, 1):
7519 				return (0x8fb2);
7520 			case BWN_LPD(0, 0, 1):
7521 				return (0x80b2);
7522 			case BWN_LPD(1, 0, 1):
7523 				return (0x20b2);
7524 			case BWN_LPD(1, 0, 0):
7525 				return (0x20b3);
7526 			}
7527 			KASSERT(0 == 1,
7528 			    ("%s:%d: fail", __func__, __LINE__));
7529 		}
7530 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7531 	}
7532 	return (0);
7533 }
7534 
7535 static void
7536 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7537 {
7538 
7539 	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7540 		return;
7541 	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7542 	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7543 	DELAY(1000);
7544 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7545 }
7546 
7547 static int
7548 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7549 {
7550 	struct bwn_softc *sc = mac->mac_sc;
7551 	struct bwn_fw *fw = &mac->mac_fw;
7552 	const uint8_t rev = siba_get_revid(sc->sc_dev);
7553 	const char *filename;
7554 	uint32_t high;
7555 	int error;
7556 
7557 	/* microcode */
7558 	if (rev >= 5 && rev <= 10)
7559 		filename = "ucode5";
7560 	else if (rev >= 11 && rev <= 12)
7561 		filename = "ucode11";
7562 	else if (rev == 13)
7563 		filename = "ucode13";
7564 	else if (rev == 14)
7565 		filename = "ucode14";
7566 	else if (rev >= 15)
7567 		filename = "ucode15";
7568 	else {
7569 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7570 		bwn_release_firmware(mac);
7571 		return (EOPNOTSUPP);
7572 	}
7573 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
7574 	if (error) {
7575 		bwn_release_firmware(mac);
7576 		return (error);
7577 	}
7578 
7579 	/* PCM */
7580 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7581 	if (rev >= 5 && rev <= 10) {
7582 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7583 		if (error == ENOENT)
7584 			fw->no_pcmfile = 1;
7585 		else if (error) {
7586 			bwn_release_firmware(mac);
7587 			return (error);
7588 		}
7589 	} else if (rev < 11) {
7590 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7591 		return (EOPNOTSUPP);
7592 	}
7593 
7594 	/* initvals */
7595 	high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7596 	switch (mac->mac_phy.type) {
7597 	case BWN_PHYTYPE_A:
7598 		if (rev < 5 || rev > 10)
7599 			goto fail1;
7600 		if (high & BWN_TGSHIGH_HAVE_2GHZ)
7601 			filename = "a0g1initvals5";
7602 		else
7603 			filename = "a0g0initvals5";
7604 		break;
7605 	case BWN_PHYTYPE_G:
7606 		if (rev >= 5 && rev <= 10)
7607 			filename = "b0g0initvals5";
7608 		else if (rev >= 13)
7609 			filename = "b0g0initvals13";
7610 		else
7611 			goto fail1;
7612 		break;
7613 	case BWN_PHYTYPE_LP:
7614 		if (rev == 13)
7615 			filename = "lp0initvals13";
7616 		else if (rev == 14)
7617 			filename = "lp0initvals14";
7618 		else if (rev >= 15)
7619 			filename = "lp0initvals15";
7620 		else
7621 			goto fail1;
7622 		break;
7623 	case BWN_PHYTYPE_N:
7624 		if (rev >= 11 && rev <= 12)
7625 			filename = "n0initvals11";
7626 		else
7627 			goto fail1;
7628 		break;
7629 	default:
7630 		goto fail1;
7631 	}
7632 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
7633 	if (error) {
7634 		bwn_release_firmware(mac);
7635 		return (error);
7636 	}
7637 
7638 	/* bandswitch initvals */
7639 	switch (mac->mac_phy.type) {
7640 	case BWN_PHYTYPE_A:
7641 		if (rev >= 5 && rev <= 10) {
7642 			if (high & BWN_TGSHIGH_HAVE_2GHZ)
7643 				filename = "a0g1bsinitvals5";
7644 			else
7645 				filename = "a0g0bsinitvals5";
7646 		} else if (rev >= 11)
7647 			filename = NULL;
7648 		else
7649 			goto fail1;
7650 		break;
7651 	case BWN_PHYTYPE_G:
7652 		if (rev >= 5 && rev <= 10)
7653 			filename = "b0g0bsinitvals5";
7654 		else if (rev >= 11)
7655 			filename = NULL;
7656 		else
7657 			goto fail1;
7658 		break;
7659 	case BWN_PHYTYPE_LP:
7660 		if (rev == 13)
7661 			filename = "lp0bsinitvals13";
7662 		else if (rev == 14)
7663 			filename = "lp0bsinitvals14";
7664 		else if (rev >= 15)
7665 			filename = "lp0bsinitvals15";
7666 		else
7667 			goto fail1;
7668 		break;
7669 	case BWN_PHYTYPE_N:
7670 		if (rev >= 11 && rev <= 12)
7671 			filename = "n0bsinitvals11";
7672 		else
7673 			goto fail1;
7674 		break;
7675 	default:
7676 		goto fail1;
7677 	}
7678 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7679 	if (error) {
7680 		bwn_release_firmware(mac);
7681 		return (error);
7682 	}
7683 	return (0);
7684 fail1:
7685 	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7686 	bwn_release_firmware(mac);
7687 	return (EOPNOTSUPP);
7688 }
7689 
7690 static int
7691 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7692     const char *name, struct bwn_fwfile *bfw)
7693 {
7694 	const struct bwn_fwhdr *hdr;
7695 	struct bwn_softc *sc = mac->mac_sc;
7696 	const struct firmware *fw;
7697 	char namebuf[64];
7698 
7699 	if (name == NULL) {
7700 		bwn_do_release_fw(bfw);
7701 		return (0);
7702 	}
7703 	if (bfw->filename != NULL) {
7704 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7705 			return (0);
7706 		bwn_do_release_fw(bfw);
7707 	}
7708 
7709 	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7710 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7711 	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7712 	/* XXX Sleeping on "fwload" with the non-sleepable locks held */
7713 	fw = firmware_get(namebuf);
7714 	if (fw == NULL) {
7715 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7716 		    namebuf);
7717 		return (ENOENT);
7718 	}
7719 	if (fw->datasize < sizeof(struct bwn_fwhdr))
7720 		goto fail;
7721 	hdr = (const struct bwn_fwhdr *)(fw->data);
7722 	switch (hdr->type) {
7723 	case BWN_FWTYPE_UCODE:
7724 	case BWN_FWTYPE_PCM:
7725 		if (be32toh(hdr->size) !=
7726 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
7727 			goto fail;
7728 		/* FALLTHROUGH */
7729 	case BWN_FWTYPE_IV:
7730 		if (hdr->ver != 1)
7731 			goto fail;
7732 		break;
7733 	default:
7734 		goto fail;
7735 	}
7736 	bfw->filename = name;
7737 	bfw->fw = fw;
7738 	bfw->type = type;
7739 	return (0);
7740 fail:
7741 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7742 	if (fw != NULL)
7743 		firmware_put(fw, FIRMWARE_UNLOAD);
7744 	return (EPROTO);
7745 }
7746 
7747 static void
7748 bwn_release_firmware(struct bwn_mac *mac)
7749 {
7750 
7751 	bwn_do_release_fw(&mac->mac_fw.ucode);
7752 	bwn_do_release_fw(&mac->mac_fw.pcm);
7753 	bwn_do_release_fw(&mac->mac_fw.initvals);
7754 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
7755 }
7756 
7757 static void
7758 bwn_do_release_fw(struct bwn_fwfile *bfw)
7759 {
7760 
7761 	if (bfw->fw != NULL)
7762 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7763 	bfw->fw = NULL;
7764 	bfw->filename = NULL;
7765 }
7766 
7767 static int
7768 bwn_fw_loaducode(struct bwn_mac *mac)
7769 {
7770 #define	GETFWOFFSET(fwp, offset)	\
7771 	((const uint32_t *)((const char *)fwp.fw->data + offset))
7772 #define	GETFWSIZE(fwp, offset)	\
7773 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
7774 	struct bwn_softc *sc = mac->mac_sc;
7775 	const uint32_t *data;
7776 	unsigned int i;
7777 	uint32_t ctl;
7778 	uint16_t date, fwcaps, time;
7779 	int error = 0;
7780 
7781 	ctl = BWN_READ_4(mac, BWN_MACCTL);
7782 	ctl |= BWN_MACCTL_MCODE_JMP0;
7783 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7784 	    __LINE__));
7785 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7786 	for (i = 0; i < 64; i++)
7787 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7788 	for (i = 0; i < 4096; i += 2)
7789 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7790 
7791 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7792 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7793 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7794 	     i++) {
7795 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7796 		DELAY(10);
7797 	}
7798 
7799 	if (mac->mac_fw.pcm.fw) {
7800 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7801 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7802 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7803 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7804 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7805 		    sizeof(struct bwn_fwhdr)); i++) {
7806 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7807 			DELAY(10);
7808 		}
7809 	}
7810 
7811 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7812 	BWN_WRITE_4(mac, BWN_MACCTL,
7813 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7814 	    BWN_MACCTL_MCODE_RUN);
7815 
7816 	for (i = 0; i < 21; i++) {
7817 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7818 			break;
7819 		if (i >= 20) {
7820 			device_printf(sc->sc_dev, "ucode timeout\n");
7821 			error = ENXIO;
7822 			goto error;
7823 		}
7824 		DELAY(50000);
7825 	}
7826 	BWN_READ_4(mac, BWN_INTR_REASON);
7827 
7828 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7829 	if (mac->mac_fw.rev <= 0x128) {
7830 		device_printf(sc->sc_dev, "the firmware is too old\n");
7831 		error = EOPNOTSUPP;
7832 		goto error;
7833 	}
7834 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7835 	    BWN_SHARED_UCODE_PATCH);
7836 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7837 	mac->mac_fw.opensource = (date == 0xffff);
7838 	if (bwn_wme != 0)
7839 		mac->mac_flags |= BWN_MAC_FLAG_WME;
7840 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7841 
7842 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7843 	if (mac->mac_fw.opensource == 0) {
7844 		device_printf(sc->sc_dev,
7845 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
7846 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7847 		if (mac->mac_fw.no_pcmfile)
7848 			device_printf(sc->sc_dev,
7849 			    "no HW crypto acceleration due to pcm5\n");
7850 	} else {
7851 		mac->mac_fw.patch = time;
7852 		fwcaps = bwn_fwcaps_read(mac);
7853 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7854 			device_printf(sc->sc_dev,
7855 			    "disabling HW crypto acceleration\n");
7856 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7857 		}
7858 		if (!(fwcaps & BWN_FWCAPS_WME)) {
7859 			device_printf(sc->sc_dev, "disabling WME support\n");
7860 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7861 		}
7862 	}
7863 
7864 	if (BWN_ISOLDFMT(mac))
7865 		device_printf(sc->sc_dev, "using old firmware image\n");
7866 
7867 	return (0);
7868 
7869 error:
7870 	BWN_WRITE_4(mac, BWN_MACCTL,
7871 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7872 	    BWN_MACCTL_MCODE_JMP0);
7873 
7874 	return (error);
7875 #undef GETFWSIZE
7876 #undef GETFWOFFSET
7877 }
7878 
7879 /* OpenFirmware only */
7880 static uint16_t
7881 bwn_fwcaps_read(struct bwn_mac *mac)
7882 {
7883 
7884 	KASSERT(mac->mac_fw.opensource == 1,
7885 	    ("%s:%d: fail", __func__, __LINE__));
7886 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7887 }
7888 
7889 static int
7890 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7891     size_t count, size_t array_size)
7892 {
7893 #define	GET_NEXTIV16(iv)						\
7894 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7895 	    sizeof(uint16_t) + sizeof(uint16_t)))
7896 #define	GET_NEXTIV32(iv)						\
7897 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7898 	    sizeof(uint16_t) + sizeof(uint32_t)))
7899 	struct bwn_softc *sc = mac->mac_sc;
7900 	const struct bwn_fwinitvals *iv;
7901 	uint16_t offset;
7902 	size_t i;
7903 	uint8_t bit32;
7904 
7905 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7906 	    ("%s:%d: fail", __func__, __LINE__));
7907 	iv = ivals;
7908 	for (i = 0; i < count; i++) {
7909 		if (array_size < sizeof(iv->offset_size))
7910 			goto fail;
7911 		array_size -= sizeof(iv->offset_size);
7912 		offset = be16toh(iv->offset_size);
7913 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7914 		offset &= BWN_FWINITVALS_OFFSET_MASK;
7915 		if (offset >= 0x1000)
7916 			goto fail;
7917 		if (bit32) {
7918 			if (array_size < sizeof(iv->data.d32))
7919 				goto fail;
7920 			array_size -= sizeof(iv->data.d32);
7921 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7922 			iv = GET_NEXTIV32(iv);
7923 		} else {
7924 
7925 			if (array_size < sizeof(iv->data.d16))
7926 				goto fail;
7927 			array_size -= sizeof(iv->data.d16);
7928 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7929 
7930 			iv = GET_NEXTIV16(iv);
7931 		}
7932 	}
7933 	if (array_size != 0)
7934 		goto fail;
7935 	return (0);
7936 fail:
7937 	device_printf(sc->sc_dev, "initvals: invalid format\n");
7938 	return (EPROTO);
7939 #undef GET_NEXTIV16
7940 #undef GET_NEXTIV32
7941 }
7942 
7943 static int
7944 bwn_switch_channel(struct bwn_mac *mac, int chan)
7945 {
7946 	struct bwn_phy *phy = &(mac->mac_phy);
7947 	struct bwn_softc *sc = mac->mac_sc;
7948 	struct ifnet *ifp = sc->sc_ifp;
7949 	struct ieee80211com *ic = ifp->if_l2com;
7950 	uint16_t channelcookie, savedcookie;
7951 	int error;
7952 
7953 	if (chan == 0xffff)
7954 		chan = phy->get_default_chan(mac);
7955 
7956 	channelcookie = chan;
7957 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7958 		channelcookie |= 0x100;
7959 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7960 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7961 	error = phy->switch_channel(mac, chan);
7962 	if (error)
7963 		goto fail;
7964 
7965 	mac->mac_phy.chan = chan;
7966 	DELAY(8000);
7967 	return (0);
7968 fail:
7969 	device_printf(sc->sc_dev, "failed to switch channel\n");
7970 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7971 	return (error);
7972 }
7973 
7974 static uint16_t
7975 bwn_ant2phy(int antenna)
7976 {
7977 
7978 	switch (antenna) {
7979 	case BWN_ANT0:
7980 		return (BWN_TX_PHY_ANT0);
7981 	case BWN_ANT1:
7982 		return (BWN_TX_PHY_ANT1);
7983 	case BWN_ANT2:
7984 		return (BWN_TX_PHY_ANT2);
7985 	case BWN_ANT3:
7986 		return (BWN_TX_PHY_ANT3);
7987 	case BWN_ANTAUTO:
7988 		return (BWN_TX_PHY_ANT01AUTO);
7989 	}
7990 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7991 	return (0);
7992 }
7993 
7994 static void
7995 bwn_wme_load(struct bwn_mac *mac)
7996 {
7997 	struct bwn_softc *sc = mac->mac_sc;
7998 	int i;
7999 
8000 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8001 	    ("%s:%d: fail", __func__, __LINE__));
8002 
8003 	bwn_mac_suspend(mac);
8004 	for (i = 0; i < N(sc->sc_wmeParams); i++)
8005 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8006 		    bwn_wme_shm_offsets[i]);
8007 	bwn_mac_enable(mac);
8008 }
8009 
8010 static void
8011 bwn_wme_loadparams(struct bwn_mac *mac,
8012     const struct wmeParams *p, uint16_t shm_offset)
8013 {
8014 #define	SM(_v, _f)      (((_v) << _f##_S) & _f)
8015 	struct bwn_softc *sc = mac->mac_sc;
8016 	uint16_t params[BWN_NR_WMEPARAMS];
8017 	int slot, tmp;
8018 	unsigned int i;
8019 
8020 	slot = BWN_READ_2(mac, BWN_RNG) &
8021 	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8022 
8023 	memset(&params, 0, sizeof(params));
8024 
8025 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8026 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8027 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8028 
8029 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8030 	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8031 	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8032 	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8033 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8034 	params[BWN_WMEPARAM_BSLOTS] = slot;
8035 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8036 
8037 	for (i = 0; i < N(params); i++) {
8038 		if (i == BWN_WMEPARAM_STATUS) {
8039 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
8040 			    shm_offset + (i * 2));
8041 			tmp |= 0x100;
8042 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8043 			    tmp);
8044 		} else {
8045 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8046 			    params[i]);
8047 		}
8048 	}
8049 }
8050 
8051 static void
8052 bwn_mac_write_bssid(struct bwn_mac *mac)
8053 {
8054 	struct bwn_softc *sc = mac->mac_sc;
8055 	uint32_t tmp;
8056 	int i;
8057 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8058 
8059 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8060 	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8061 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8062 	    IEEE80211_ADDR_LEN);
8063 
8064 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8065 		tmp = (uint32_t) (mac_bssid[i + 0]);
8066 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8067 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8068 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8069 		bwn_ram_write(mac, 0x20 + i, tmp);
8070 	}
8071 }
8072 
8073 static void
8074 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8075     const uint8_t *macaddr)
8076 {
8077 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8078 	uint16_t data;
8079 
8080 	if (!mac)
8081 		macaddr = zero;
8082 
8083 	offset |= 0x0020;
8084 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8085 
8086 	data = macaddr[0];
8087 	data |= macaddr[1] << 8;
8088 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8089 	data = macaddr[2];
8090 	data |= macaddr[3] << 8;
8091 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8092 	data = macaddr[4];
8093 	data |= macaddr[5] << 8;
8094 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8095 }
8096 
8097 static void
8098 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8099     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8100 {
8101 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8102 	uint8_t per_sta_keys_start = 8;
8103 
8104 	if (BWN_SEC_NEWAPI(mac))
8105 		per_sta_keys_start = 4;
8106 
8107 	KASSERT(index < mac->mac_max_nr_keys,
8108 	    ("%s:%d: fail", __func__, __LINE__));
8109 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
8110 	    ("%s:%d: fail", __func__, __LINE__));
8111 
8112 	if (index >= per_sta_keys_start)
8113 		bwn_key_macwrite(mac, index, NULL);
8114 	if (key)
8115 		memcpy(buf, key, key_len);
8116 	bwn_key_write(mac, index, algorithm, buf);
8117 	if (index >= per_sta_keys_start)
8118 		bwn_key_macwrite(mac, index, mac_addr);
8119 
8120 	mac->mac_key[index].algorithm = algorithm;
8121 }
8122 
8123 static void
8124 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8125 {
8126 	struct bwn_softc *sc = mac->mac_sc;
8127 	uint32_t addrtmp[2] = { 0, 0 };
8128 	uint8_t start = 8;
8129 
8130 	if (BWN_SEC_NEWAPI(mac))
8131 		start = 4;
8132 
8133 	KASSERT(index >= start,
8134 	    ("%s:%d: fail", __func__, __LINE__));
8135 	index -= start;
8136 
8137 	if (addr) {
8138 		addrtmp[0] = addr[0];
8139 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8140 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8141 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8142 		addrtmp[1] = addr[4];
8143 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8144 	}
8145 
8146 	if (siba_get_revid(sc->sc_dev) >= 5) {
8147 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8148 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8149 	} else {
8150 		if (index >= 8) {
8151 			bwn_shm_write_4(mac, BWN_SHARED,
8152 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8153 			bwn_shm_write_2(mac, BWN_SHARED,
8154 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8155 		}
8156 	}
8157 }
8158 
8159 static void
8160 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8161     const uint8_t *key)
8162 {
8163 	unsigned int i;
8164 	uint32_t offset;
8165 	uint16_t kidx, value;
8166 
8167 	kidx = BWN_SEC_KEY2FW(mac, index);
8168 	bwn_shm_write_2(mac, BWN_SHARED,
8169 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8170 
8171 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8172 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8173 		value = key[i];
8174 		value |= (uint16_t)(key[i + 1]) << 8;
8175 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8176 	}
8177 }
8178 
8179 static void
8180 bwn_phy_exit(struct bwn_mac *mac)
8181 {
8182 
8183 	mac->mac_phy.rf_onoff(mac, 0);
8184 	if (mac->mac_phy.exit != NULL)
8185 		mac->mac_phy.exit(mac);
8186 }
8187 
8188 static void
8189 bwn_dma_free(struct bwn_mac *mac)
8190 {
8191 	struct bwn_dma *dma;
8192 
8193 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8194 		return;
8195 	dma = &mac->mac_method.dma;
8196 
8197 	bwn_dma_ringfree(&dma->rx);
8198 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8199 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8200 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8201 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8202 	bwn_dma_ringfree(&dma->mcast);
8203 }
8204 
8205 static void
8206 bwn_core_stop(struct bwn_mac *mac)
8207 {
8208 	struct bwn_softc *sc = mac->mac_sc;
8209 
8210 	BWN_ASSERT_LOCKED(sc);
8211 
8212 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8213 		return;
8214 
8215 	callout_stop(&sc->sc_rfswitch_ch);
8216 	callout_stop(&sc->sc_task_ch);
8217 	callout_stop(&sc->sc_watchdog_ch);
8218 	sc->sc_watchdog_timer = 0;
8219 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8220 	BWN_READ_4(mac, BWN_INTR_MASK);
8221 	bwn_mac_suspend(mac);
8222 
8223 	mac->mac_status = BWN_MAC_STATUS_INITED;
8224 }
8225 
8226 static int
8227 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8228 {
8229 	struct bwn_mac *up_dev = NULL;
8230 	struct bwn_mac *down_dev;
8231 	struct bwn_mac *mac;
8232 	int err, status;
8233 	uint8_t gmode;
8234 
8235 	BWN_ASSERT_LOCKED(sc);
8236 
8237 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8238 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8239 		    mac->mac_phy.supports_2ghz) {
8240 			up_dev = mac;
8241 			gmode = 1;
8242 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8243 		    mac->mac_phy.supports_5ghz) {
8244 			up_dev = mac;
8245 			gmode = 0;
8246 		} else {
8247 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8248 			return (EINVAL);
8249 		}
8250 		if (up_dev != NULL)
8251 			break;
8252 	}
8253 	if (up_dev == NULL) {
8254 		device_printf(sc->sc_dev, "Could not find a device\n");
8255 		return (ENODEV);
8256 	}
8257 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8258 		return (0);
8259 
8260 	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8261 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8262 
8263 	down_dev = sc->sc_curmac;;
8264 	status = down_dev->mac_status;
8265 	if (status >= BWN_MAC_STATUS_STARTED)
8266 		bwn_core_stop(down_dev);
8267 	if (status >= BWN_MAC_STATUS_INITED)
8268 		bwn_core_exit(down_dev);
8269 
8270 	if (down_dev != up_dev)
8271 		bwn_phy_reset(down_dev);
8272 
8273 	up_dev->mac_phy.gmode = gmode;
8274 	if (status >= BWN_MAC_STATUS_INITED) {
8275 		err = bwn_core_init(up_dev);
8276 		if (err) {
8277 			device_printf(sc->sc_dev,
8278 			    "fatal: failed to initialize for %s-GHz\n",
8279 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8280 			goto fail;
8281 		}
8282 	}
8283 	if (status >= BWN_MAC_STATUS_STARTED)
8284 		bwn_core_start(up_dev);
8285 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8286 	sc->sc_curmac = up_dev;
8287 
8288 	return (0);
8289 fail:
8290 	sc->sc_curmac = NULL;
8291 	return (err);
8292 }
8293 
8294 static void
8295 bwn_rf_turnon(struct bwn_mac *mac)
8296 {
8297 
8298 	bwn_mac_suspend(mac);
8299 	mac->mac_phy.rf_onoff(mac, 1);
8300 	mac->mac_phy.rf_on = 1;
8301 	bwn_mac_enable(mac);
8302 }
8303 
8304 static void
8305 bwn_rf_turnoff(struct bwn_mac *mac)
8306 {
8307 
8308 	bwn_mac_suspend(mac);
8309 	mac->mac_phy.rf_onoff(mac, 0);
8310 	mac->mac_phy.rf_on = 0;
8311 	bwn_mac_enable(mac);
8312 }
8313 
8314 static void
8315 bwn_phy_reset(struct bwn_mac *mac)
8316 {
8317 	struct bwn_softc *sc = mac->mac_sc;
8318 
8319 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8320 	    ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8321 	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8322 	DELAY(1000);
8323 	siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8324 	    (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8325 	    BWN_TGSLOW_PHYRESET);
8326 	DELAY(1000);
8327 }
8328 
8329 static int
8330 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8331 {
8332 	const struct ieee80211_txparam *tp;
8333 	struct bwn_vap *bvp = BWN_VAP(vap);
8334 	struct ieee80211com *ic= vap->iv_ic;
8335 	struct ifnet *ifp = ic->ic_ifp;
8336 	enum ieee80211_state ostate = vap->iv_state;
8337 	struct bwn_softc *sc = ifp->if_softc;
8338 	struct bwn_mac *mac = sc->sc_curmac;
8339 	int error;
8340 
8341 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8342 	    ieee80211_state_name[vap->iv_state],
8343 	    ieee80211_state_name[nstate]);
8344 
8345 	error = bvp->bv_newstate(vap, nstate, arg);
8346 	if (error != 0)
8347 		return (error);
8348 
8349 	BWN_LOCK(sc);
8350 
8351 	bwn_led_newstate(mac, nstate);
8352 
8353 	/*
8354 	 * Clear the BSSID when we stop a STA
8355 	 */
8356 	if (vap->iv_opmode == IEEE80211_M_STA) {
8357 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8358 			/*
8359 			 * Clear out the BSSID.  If we reassociate to
8360 			 * the same AP, this will reinialize things
8361 			 * correctly...
8362 			 */
8363 			if (ic->ic_opmode == IEEE80211_M_STA &&
8364 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8365 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8366 				bwn_set_macaddr(mac);
8367 			}
8368 		}
8369 	}
8370 
8371 	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8372 	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
8373 		/* XXX nothing to do? */
8374 	} else if (nstate == IEEE80211_S_RUN) {
8375 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8376 		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8377 		bwn_set_opmode(mac);
8378 		bwn_set_pretbtt(mac);
8379 		bwn_spu_setdelay(mac, 0);
8380 		bwn_set_macaddr(mac);
8381 
8382 		/* Initializes ratectl for a node. */
8383 		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
8384 		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
8385 			ieee80211_ratectl_node_init(vap->iv_bss);
8386 	}
8387 
8388 	BWN_UNLOCK(sc);
8389 
8390 	return (error);
8391 }
8392 
8393 static void
8394 bwn_set_pretbtt(struct bwn_mac *mac)
8395 {
8396 	struct bwn_softc *sc = mac->mac_sc;
8397 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8398 	uint16_t pretbtt;
8399 
8400 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8401 		pretbtt = 2;
8402 	else
8403 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8404 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8405 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8406 }
8407 
8408 static int
8409 bwn_intr(void *arg)
8410 {
8411 	struct bwn_mac *mac = arg;
8412 	struct bwn_softc *sc = mac->mac_sc;
8413 	uint32_t reason;
8414 
8415 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8416 	    (sc->sc_flags & BWN_FLAG_INVALID))
8417 		return (FILTER_STRAY);
8418 
8419 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
8420 	if (reason == 0xffffffff)	/* shared IRQ */
8421 		return (FILTER_STRAY);
8422 	reason &= mac->mac_intr_mask;
8423 	if (reason == 0)
8424 		return (FILTER_HANDLED);
8425 
8426 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8427 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8428 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8429 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8430 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8431 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8432 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8433 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8434 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8435 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8436 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8437 
8438 	/* Disable interrupts. */
8439 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8440 
8441 	mac->mac_reason_intr = reason;
8442 
8443 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8445 
8446 	taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8447 	return (FILTER_HANDLED);
8448 }
8449 
8450 static void
8451 bwn_intrtask(void *arg, int npending)
8452 {
8453 	struct bwn_mac *mac = arg;
8454 	struct bwn_softc *sc = mac->mac_sc;
8455 	struct ifnet *ifp = sc->sc_ifp;
8456 	uint32_t merged = 0;
8457 	int i, tx = 0, rx = 0;
8458 
8459 	BWN_LOCK(sc);
8460 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8461 	    (sc->sc_flags & BWN_FLAG_INVALID)) {
8462 		BWN_UNLOCK(sc);
8463 		return;
8464 	}
8465 
8466 	for (i = 0; i < N(mac->mac_reason); i++)
8467 		merged |= mac->mac_reason[i];
8468 
8469 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8470 		device_printf(sc->sc_dev, "MAC trans error\n");
8471 
8472 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8473 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8474 		mac->mac_phy.txerrors--;
8475 		if (mac->mac_phy.txerrors == 0) {
8476 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8477 			bwn_restart(mac, "PHY TX errors");
8478 		}
8479 	}
8480 
8481 	if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8482 		if (merged & BWN_DMAINTR_FATALMASK) {
8483 			device_printf(sc->sc_dev,
8484 			    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8485 			    mac->mac_reason[0], mac->mac_reason[1],
8486 			    mac->mac_reason[2], mac->mac_reason[3],
8487 			    mac->mac_reason[4], mac->mac_reason[5]);
8488 			bwn_restart(mac, "DMA error");
8489 			BWN_UNLOCK(sc);
8490 			return;
8491 		}
8492 		if (merged & BWN_DMAINTR_NONFATALMASK) {
8493 			device_printf(sc->sc_dev,
8494 			    "DMA error: %#x %#x %#x %#x %#x %#x\n",
8495 			    mac->mac_reason[0], mac->mac_reason[1],
8496 			    mac->mac_reason[2], mac->mac_reason[3],
8497 			    mac->mac_reason[4], mac->mac_reason[5]);
8498 		}
8499 	}
8500 
8501 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8502 		bwn_intr_ucode_debug(mac);
8503 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8504 		bwn_intr_tbtt_indication(mac);
8505 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8506 		bwn_intr_atim_end(mac);
8507 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
8508 		bwn_intr_beacon(mac);
8509 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
8510 		bwn_intr_pmq(mac);
8511 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8512 		bwn_intr_noise(mac);
8513 
8514 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8515 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8516 			bwn_dma_rx(mac->mac_method.dma.rx);
8517 			rx = 1;
8518 		}
8519 	} else
8520 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8521 
8522 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8523 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8524 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8525 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8526 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8527 
8528 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8529 		bwn_intr_txeof(mac);
8530 		tx = 1;
8531 	}
8532 
8533 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8534 
8535 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8536 		int evt = BWN_LED_EVENT_NONE;
8537 
8538 		if (tx && rx) {
8539 			if (sc->sc_rx_rate > sc->sc_tx_rate)
8540 				evt = BWN_LED_EVENT_RX;
8541 			else
8542 				evt = BWN_LED_EVENT_TX;
8543 		} else if (tx) {
8544 			evt = BWN_LED_EVENT_TX;
8545 		} else if (rx) {
8546 			evt = BWN_LED_EVENT_RX;
8547 		} else if (rx == 0) {
8548 			evt = BWN_LED_EVENT_POLL;
8549 		}
8550 
8551 		if (evt != BWN_LED_EVENT_NONE)
8552 			bwn_led_event(mac, evt);
8553        }
8554 
8555 	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8556 		if (!IFQ_IS_EMPTY(&ifp->if_snd))
8557 			bwn_start_locked(ifp);
8558 	}
8559 
8560 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8561 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8562 
8563 	BWN_UNLOCK(sc);
8564 }
8565 
8566 static void
8567 bwn_restart(struct bwn_mac *mac, const char *msg)
8568 {
8569 	struct bwn_softc *sc = mac->mac_sc;
8570 	struct ifnet *ifp = sc->sc_ifp;
8571 	struct ieee80211com *ic = ifp->if_l2com;
8572 
8573 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
8574 		return;
8575 
8576 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8577 	ieee80211_runtask(ic, &mac->mac_hwreset);
8578 }
8579 
8580 static void
8581 bwn_intr_ucode_debug(struct bwn_mac *mac)
8582 {
8583 	struct bwn_softc *sc = mac->mac_sc;
8584 	uint16_t reason;
8585 
8586 	if (mac->mac_fw.opensource == 0)
8587 		return;
8588 
8589 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8590 	switch (reason) {
8591 	case BWN_DEBUGINTR_PANIC:
8592 		bwn_handle_fwpanic(mac);
8593 		break;
8594 	case BWN_DEBUGINTR_DUMP_SHM:
8595 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8596 		break;
8597 	case BWN_DEBUGINTR_DUMP_REGS:
8598 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8599 		break;
8600 	case BWN_DEBUGINTR_MARKER:
8601 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8602 		break;
8603 	default:
8604 		device_printf(sc->sc_dev,
8605 		    "ucode debug unknown reason: %#x\n", reason);
8606 	}
8607 
8608 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8609 	    BWN_DEBUGINTR_ACK);
8610 }
8611 
8612 static void
8613 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8614 {
8615 	struct bwn_softc *sc = mac->mac_sc;
8616 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8617 
8618 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8619 		bwn_psctl(mac, 0);
8620 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8621 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8622 }
8623 
8624 static void
8625 bwn_intr_atim_end(struct bwn_mac *mac)
8626 {
8627 
8628 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8629 		BWN_WRITE_4(mac, BWN_MACCMD,
8630 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8631 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8632 	}
8633 }
8634 
8635 static void
8636 bwn_intr_beacon(struct bwn_mac *mac)
8637 {
8638 	struct bwn_softc *sc = mac->mac_sc;
8639 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8640 	uint32_t cmd, beacon0, beacon1;
8641 
8642 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8643 	    ic->ic_opmode == IEEE80211_M_MBSS)
8644 		return;
8645 
8646 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8647 
8648 	cmd = BWN_READ_4(mac, BWN_MACCMD);
8649 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8650 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8651 
8652 	if (beacon0 && beacon1) {
8653 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8654 		mac->mac_intr_mask |= BWN_INTR_BEACON;
8655 		return;
8656 	}
8657 
8658 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8659 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8660 		bwn_load_beacon0(mac);
8661 		bwn_load_beacon1(mac);
8662 		cmd = BWN_READ_4(mac, BWN_MACCMD);
8663 		cmd |= BWN_MACCMD_BEACON0_VALID;
8664 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8665 	} else {
8666 		if (!beacon0) {
8667 			bwn_load_beacon0(mac);
8668 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8669 			cmd |= BWN_MACCMD_BEACON0_VALID;
8670 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8671 		} else if (!beacon1) {
8672 			bwn_load_beacon1(mac);
8673 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8674 			cmd |= BWN_MACCMD_BEACON1_VALID;
8675 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8676 		}
8677 	}
8678 }
8679 
8680 static void
8681 bwn_intr_pmq(struct bwn_mac *mac)
8682 {
8683 	uint32_t tmp;
8684 
8685 	while (1) {
8686 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8687 		if (!(tmp & 0x00000008))
8688 			break;
8689 	}
8690 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8691 }
8692 
8693 static void
8694 bwn_intr_noise(struct bwn_mac *mac)
8695 {
8696 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8697 	uint16_t tmp;
8698 	uint8_t noise[4];
8699 	uint8_t i, j;
8700 	int32_t average;
8701 
8702 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
8703 		return;
8704 
8705 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8706 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8707 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8708 	    noise[3] == 0x7f)
8709 		goto new;
8710 
8711 	KASSERT(mac->mac_noise.noi_nsamples < 8,
8712 	    ("%s:%d: fail", __func__, __LINE__));
8713 	i = mac->mac_noise.noi_nsamples;
8714 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8715 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8716 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8717 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8718 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8719 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8720 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8721 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8722 	mac->mac_noise.noi_nsamples++;
8723 	if (mac->mac_noise.noi_nsamples == 8) {
8724 		average = 0;
8725 		for (i = 0; i < 8; i++) {
8726 			for (j = 0; j < 4; j++)
8727 				average += mac->mac_noise.noi_samples[i][j];
8728 		}
8729 		average = (((average / 32) * 125) + 64) / 128;
8730 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8731 		if (tmp >= 8)
8732 			average += 2;
8733 		else
8734 			average -= 25;
8735 		average -= (tmp == 8) ? 72 : 48;
8736 
8737 		mac->mac_stats.link_noise = average;
8738 		mac->mac_noise.noi_running = 0;
8739 		return;
8740 	}
8741 new:
8742 	bwn_noise_gensample(mac);
8743 }
8744 
8745 static int
8746 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8747 {
8748 	struct bwn_mac *mac = prq->prq_mac;
8749 	struct bwn_softc *sc = mac->mac_sc;
8750 	unsigned int i;
8751 
8752 	BWN_ASSERT_LOCKED(sc);
8753 
8754 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8755 		return (0);
8756 
8757 	for (i = 0; i < 5000; i++) {
8758 		if (bwn_pio_rxeof(prq) == 0)
8759 			break;
8760 	}
8761 	if (i >= 5000)
8762 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8763 	return ((i > 0) ? 1 : 0);
8764 }
8765 
8766 static void
8767 bwn_dma_rx(struct bwn_dma_ring *dr)
8768 {
8769 	int slot, curslot;
8770 
8771 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8772 	curslot = dr->get_curslot(dr);
8773 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8774 	    ("%s:%d: fail", __func__, __LINE__));
8775 
8776 	slot = dr->dr_curslot;
8777 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8778 		bwn_dma_rxeof(dr, &slot);
8779 
8780 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8781 	    BUS_DMASYNC_PREWRITE);
8782 
8783 	dr->set_curslot(dr, slot);
8784 	dr->dr_curslot = slot;
8785 }
8786 
8787 static void
8788 bwn_intr_txeof(struct bwn_mac *mac)
8789 {
8790 	struct bwn_txstatus stat;
8791 	uint32_t stat0, stat1;
8792 	uint16_t tmp;
8793 
8794 	BWN_ASSERT_LOCKED(mac->mac_sc);
8795 
8796 	while (1) {
8797 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8798 		if (!(stat0 & 0x00000001))
8799 			break;
8800 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8801 
8802 		stat.cookie = (stat0 >> 16);
8803 		stat.seq = (stat1 & 0x0000ffff);
8804 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8805 		tmp = (stat0 & 0x0000ffff);
8806 		stat.framecnt = ((tmp & 0xf000) >> 12);
8807 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
8808 		stat.sreason = ((tmp & 0x001c) >> 2);
8809 		stat.pm = (tmp & 0x0080) ? 1 : 0;
8810 		stat.im = (tmp & 0x0040) ? 1 : 0;
8811 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8812 		stat.ack = (tmp & 0x0002) ? 1 : 0;
8813 
8814 		bwn_handle_txeof(mac, &stat);
8815 	}
8816 }
8817 
8818 static void
8819 bwn_hwreset(void *arg, int npending)
8820 {
8821 	struct bwn_mac *mac = arg;
8822 	struct bwn_softc *sc = mac->mac_sc;
8823 	int error = 0;
8824 	int prev_status;
8825 
8826 	BWN_LOCK(sc);
8827 
8828 	prev_status = mac->mac_status;
8829 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8830 		bwn_core_stop(mac);
8831 	if (prev_status >= BWN_MAC_STATUS_INITED)
8832 		bwn_core_exit(mac);
8833 
8834 	if (prev_status >= BWN_MAC_STATUS_INITED) {
8835 		error = bwn_core_init(mac);
8836 		if (error)
8837 			goto out;
8838 	}
8839 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8840 		bwn_core_start(mac);
8841 out:
8842 	if (error) {
8843 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8844 		sc->sc_curmac = NULL;
8845 	}
8846 	BWN_UNLOCK(sc);
8847 }
8848 
8849 static void
8850 bwn_handle_fwpanic(struct bwn_mac *mac)
8851 {
8852 	struct bwn_softc *sc = mac->mac_sc;
8853 	uint16_t reason;
8854 
8855 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8856 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8857 
8858 	if (reason == BWN_FWPANIC_RESTART)
8859 		bwn_restart(mac, "ucode panic");
8860 }
8861 
8862 static void
8863 bwn_load_beacon0(struct bwn_mac *mac)
8864 {
8865 
8866 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8867 }
8868 
8869 static void
8870 bwn_load_beacon1(struct bwn_mac *mac)
8871 {
8872 
8873 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8874 }
8875 
8876 static uint32_t
8877 bwn_jssi_read(struct bwn_mac *mac)
8878 {
8879 	uint32_t val = 0;
8880 
8881 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8882 	val <<= 16;
8883 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8884 
8885 	return (val);
8886 }
8887 
8888 static void
8889 bwn_noise_gensample(struct bwn_mac *mac)
8890 {
8891 	uint32_t jssi = 0x7f7f7f7f;
8892 
8893 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8894 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8895 	BWN_WRITE_4(mac, BWN_MACCMD,
8896 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8897 }
8898 
8899 static int
8900 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8901 {
8902 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8903 
8904 	return (dr->dr_numslots - dr->dr_usedslot);
8905 }
8906 
8907 static int
8908 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8909 {
8910 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8911 
8912 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8913 	    ("%s:%d: fail", __func__, __LINE__));
8914 	if (slot == dr->dr_numslots - 1)
8915 		return (0);
8916 	return (slot + 1);
8917 }
8918 
8919 static void
8920 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8921 {
8922 	struct bwn_mac *mac = dr->dr_mac;
8923 	struct bwn_softc *sc = mac->mac_sc;
8924 	struct bwn_dma *dma = &mac->mac_method.dma;
8925 	struct bwn_dmadesc_generic *desc;
8926 	struct bwn_dmadesc_meta *meta;
8927 	struct bwn_rxhdr4 *rxhdr;
8928 	struct ifnet *ifp = sc->sc_ifp;
8929 	struct mbuf *m;
8930 	uint32_t macstat;
8931 	int32_t tmp;
8932 	int cnt = 0;
8933 	uint16_t len;
8934 
8935 	dr->getdesc(dr, *slot, &desc, &meta);
8936 
8937 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8938 	m = meta->mt_m;
8939 
8940 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8941 		ifp->if_ierrors++;
8942 		return;
8943 	}
8944 
8945 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
8946 	len = le16toh(rxhdr->frame_len);
8947 	if (len <= 0) {
8948 		ifp->if_ierrors++;
8949 		return;
8950 	}
8951 	if (bwn_dma_check_redzone(dr, m)) {
8952 		device_printf(sc->sc_dev, "redzone error.\n");
8953 		bwn_dma_set_redzone(dr, m);
8954 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8955 		    BUS_DMASYNC_PREWRITE);
8956 		return;
8957 	}
8958 	if (len > dr->dr_rx_bufsize) {
8959 		tmp = len;
8960 		while (1) {
8961 			dr->getdesc(dr, *slot, &desc, &meta);
8962 			bwn_dma_set_redzone(dr, meta->mt_m);
8963 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8964 			    BUS_DMASYNC_PREWRITE);
8965 			*slot = bwn_dma_nextslot(dr, *slot);
8966 			cnt++;
8967 			tmp -= dr->dr_rx_bufsize;
8968 			if (tmp <= 0)
8969 				break;
8970 		}
8971 		device_printf(sc->sc_dev, "too small buffer "
8972 		       "(len %u buffer %u dropped %d)\n",
8973 		       len, dr->dr_rx_bufsize, cnt);
8974 		return;
8975 	}
8976 	macstat = le32toh(rxhdr->mac_status);
8977 	if (macstat & BWN_RX_MAC_FCSERR) {
8978 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8979 			device_printf(sc->sc_dev, "RX drop\n");
8980 			return;
8981 		}
8982 	}
8983 
8984 	m->m_pkthdr.rcvif = ifp;
8985 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8986 	m_adj(m, dr->dr_frameoffset);
8987 
8988 	bwn_rxeof(dr->dr_mac, m, rxhdr);
8989 }
8990 
8991 static void
8992 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8993 {
8994 	struct bwn_dma_ring *dr;
8995 	struct bwn_dmadesc_generic *desc;
8996 	struct bwn_dmadesc_meta *meta;
8997 	struct bwn_pio_txqueue *tq;
8998 	struct bwn_pio_txpkt *tp = NULL;
8999 	struct bwn_softc *sc = mac->mac_sc;
9000 	struct bwn_stats *stats = &mac->mac_stats;
9001 	struct ieee80211_node *ni;
9002 	struct ieee80211vap *vap;
9003 	int retrycnt = 0, slot;
9004 
9005 	BWN_ASSERT_LOCKED(mac->mac_sc);
9006 
9007 	if (status->im)
9008 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9009 	if (status->ampdu)
9010 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9011 	if (status->rtscnt) {
9012 		if (status->rtscnt == 0xf)
9013 			stats->rtsfail++;
9014 		else
9015 			stats->rts++;
9016 	}
9017 
9018 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9019 		if (status->ack) {
9020 			dr = bwn_dma_parse_cookie(mac, status,
9021 			    status->cookie, &slot);
9022 			if (dr == NULL) {
9023 				device_printf(sc->sc_dev,
9024 				    "failed to parse cookie\n");
9025 				return;
9026 			}
9027 			while (1) {
9028 				dr->getdesc(dr, slot, &desc, &meta);
9029 				if (meta->mt_islast) {
9030 					ni = meta->mt_ni;
9031 					vap = ni->ni_vap;
9032 					ieee80211_ratectl_tx_complete(vap, ni,
9033 					    status->ack ?
9034 					      IEEE80211_RATECTL_TX_SUCCESS :
9035 					      IEEE80211_RATECTL_TX_FAILURE,
9036 					    &retrycnt, 0);
9037 					break;
9038 				}
9039 				slot = bwn_dma_nextslot(dr, slot);
9040 			}
9041 		}
9042 		bwn_dma_handle_txeof(mac, status);
9043 	} else {
9044 		if (status->ack) {
9045 			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9046 			if (tq == NULL) {
9047 				device_printf(sc->sc_dev,
9048 				    "failed to parse cookie\n");
9049 				return;
9050 			}
9051 			ni = tp->tp_ni;
9052 			vap = ni->ni_vap;
9053 			ieee80211_ratectl_tx_complete(vap, ni,
9054 			    status->ack ?
9055 			      IEEE80211_RATECTL_TX_SUCCESS :
9056 			      IEEE80211_RATECTL_TX_FAILURE,
9057 			    &retrycnt, 0);
9058 		}
9059 		bwn_pio_handle_txeof(mac, status);
9060 	}
9061 
9062 	bwn_phy_txpower_check(mac, 0);
9063 }
9064 
9065 static uint8_t
9066 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9067 {
9068 	struct bwn_mac *mac = prq->prq_mac;
9069 	struct bwn_softc *sc = mac->mac_sc;
9070 	struct bwn_rxhdr4 rxhdr;
9071 	struct ifnet *ifp = sc->sc_ifp;
9072 	struct mbuf *m;
9073 	uint32_t ctl32, macstat, v32;
9074 	unsigned int i, padding;
9075 	uint16_t ctl16, len, v16;
9076 	unsigned char *mp;
9077 	char *data;
9078 
9079 	memset(&rxhdr, 0, sizeof(rxhdr));
9080 
9081 	if (prq->prq_rev >= 8) {
9082 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9083 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9084 			return (0);
9085 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9086 		    BWN_PIO8_RXCTL_FRAMEREADY);
9087 		for (i = 0; i < 10; i++) {
9088 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9089 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9090 				goto ready;
9091 			DELAY(10);
9092 		}
9093 	} else {
9094 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9095 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9096 			return (0);
9097 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9098 		    BWN_PIO_RXCTL_FRAMEREADY);
9099 		for (i = 0; i < 10; i++) {
9100 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9101 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9102 				goto ready;
9103 			DELAY(10);
9104 		}
9105 	}
9106 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9107 	return (1);
9108 ready:
9109 	if (prq->prq_rev >= 8)
9110 		siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9111 		    prq->prq_base + BWN_PIO8_RXDATA);
9112 	else
9113 		siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9114 		    prq->prq_base + BWN_PIO_RXDATA);
9115 	len = le16toh(rxhdr.frame_len);
9116 	if (len > 0x700) {
9117 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9118 		goto error;
9119 	}
9120 	if (len == 0) {
9121 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9122 		goto error;
9123 	}
9124 
9125 	macstat = le32toh(rxhdr.mac_status);
9126 	if (macstat & BWN_RX_MAC_FCSERR) {
9127 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9128 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
9129 			goto error;
9130 		}
9131 	}
9132 
9133 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9134 	KASSERT(len + padding <= MCLBYTES, ("too big..\n"));
9135 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9136 	if (m == NULL) {
9137 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
9138 		goto error;
9139 	}
9140 	mp = mtod(m, unsigned char *);
9141 	if (prq->prq_rev >= 8) {
9142 		siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3),
9143 		    prq->prq_base + BWN_PIO8_RXDATA);
9144 		if (len & 3) {
9145 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9146 			data = &(mp[len + padding - 1]);
9147 			switch (len & 3) {
9148 			case 3:
9149 				*data = (v32 >> 16);
9150 				data--;
9151 			case 2:
9152 				*data = (v32 >> 8);
9153 				data--;
9154 			case 1:
9155 				*data = v32;
9156 			}
9157 		}
9158 	} else {
9159 		siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1),
9160 		    prq->prq_base + BWN_PIO_RXDATA);
9161 		if (len & 1) {
9162 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9163 			mp[len + padding - 1] = v16;
9164 		}
9165 	}
9166 
9167 	m->m_pkthdr.rcvif = ifp;
9168 	m->m_len = m->m_pkthdr.len = len + padding;
9169 
9170 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
9171 
9172 	return (1);
9173 error:
9174 	if (prq->prq_rev >= 8)
9175 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9176 		    BWN_PIO8_RXCTL_DATAREADY);
9177 	else
9178 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9179 	return (1);
9180 }
9181 
9182 static int
9183 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9184     struct bwn_dmadesc_meta *meta, int init)
9185 {
9186 	struct bwn_mac *mac = dr->dr_mac;
9187 	struct bwn_dma *dma = &mac->mac_method.dma;
9188 	struct bwn_rxhdr4 *hdr;
9189 	bus_dmamap_t map;
9190 	bus_addr_t paddr;
9191 	struct mbuf *m;
9192 	int error;
9193 
9194 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9195 	if (m == NULL) {
9196 		error = ENOBUFS;
9197 
9198 		/*
9199 		 * If the NIC is up and running, we need to:
9200 		 * - Clear RX buffer's header.
9201 		 * - Restore RX descriptor settings.
9202 		 */
9203 		if (init)
9204 			return (error);
9205 		else
9206 			goto back;
9207 	}
9208 	m->m_len = m->m_pkthdr.len = MCLBYTES;
9209 
9210 	bwn_dma_set_redzone(dr, m);
9211 
9212 	/*
9213 	 * Try to load RX buf into temporary DMA map
9214 	 */
9215 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9216 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9217 	if (error) {
9218 		m_freem(m);
9219 
9220 		/*
9221 		 * See the comment above
9222 		 */
9223 		if (init)
9224 			return (error);
9225 		else
9226 			goto back;
9227 	}
9228 
9229 	if (!init)
9230 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9231 	meta->mt_m = m;
9232 	meta->mt_paddr = paddr;
9233 
9234 	/*
9235 	 * Swap RX buf's DMA map with the loaded temporary one
9236 	 */
9237 	map = meta->mt_dmap;
9238 	meta->mt_dmap = dr->dr_spare_dmap;
9239 	dr->dr_spare_dmap = map;
9240 
9241 back:
9242 	/*
9243 	 * Clear RX buf header
9244 	 */
9245 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9246 	bzero(hdr, sizeof(*hdr));
9247 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9248 	    BUS_DMASYNC_PREWRITE);
9249 
9250 	/*
9251 	 * Setup RX buf descriptor
9252 	 */
9253 	dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9254 	    sizeof(*hdr), 0, 0, 0);
9255 	return (error);
9256 }
9257 
9258 static void
9259 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9260 		 bus_size_t mapsz __unused, int error)
9261 {
9262 
9263 	if (!error) {
9264 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9265 		*((bus_addr_t *)arg) = seg->ds_addr;
9266 	}
9267 }
9268 
9269 static int
9270 bwn_hwrate2ieeerate(int rate)
9271 {
9272 
9273 	switch (rate) {
9274 	case BWN_CCK_RATE_1MB:
9275 		return (2);
9276 	case BWN_CCK_RATE_2MB:
9277 		return (4);
9278 	case BWN_CCK_RATE_5MB:
9279 		return (11);
9280 	case BWN_CCK_RATE_11MB:
9281 		return (22);
9282 	case BWN_OFDM_RATE_6MB:
9283 		return (12);
9284 	case BWN_OFDM_RATE_9MB:
9285 		return (18);
9286 	case BWN_OFDM_RATE_12MB:
9287 		return (24);
9288 	case BWN_OFDM_RATE_18MB:
9289 		return (36);
9290 	case BWN_OFDM_RATE_24MB:
9291 		return (48);
9292 	case BWN_OFDM_RATE_36MB:
9293 		return (72);
9294 	case BWN_OFDM_RATE_48MB:
9295 		return (96);
9296 	case BWN_OFDM_RATE_54MB:
9297 		return (108);
9298 	default:
9299 		printf("Ooops\n");
9300 		return (0);
9301 	}
9302 }
9303 
9304 static void
9305 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9306 {
9307 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9308 	struct bwn_plcp6 *plcp;
9309 	struct bwn_softc *sc = mac->mac_sc;
9310 	struct ieee80211_frame_min *wh;
9311 	struct ieee80211_node *ni;
9312 	struct ifnet *ifp = sc->sc_ifp;
9313 	struct ieee80211com *ic = ifp->if_l2com;
9314 	uint32_t macstat;
9315 	int padding, rate, rssi = 0, noise = 0, type;
9316 	uint16_t phytype, phystat0, phystat3, chanstat;
9317 	unsigned char *mp = mtod(m, unsigned char *);
9318 	static int rx_mac_dec_rpt = 0;
9319 
9320 	BWN_ASSERT_LOCKED(sc);
9321 
9322 	phystat0 = le16toh(rxhdr->phy_status0);
9323 	phystat3 = le16toh(rxhdr->phy_status3);
9324 	macstat = le32toh(rxhdr->mac_status);
9325 	chanstat = le16toh(rxhdr->channel);
9326 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9327 
9328 	if (macstat & BWN_RX_MAC_FCSERR)
9329 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9330 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9331 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9332 	if (macstat & BWN_RX_MAC_DECERR)
9333 		goto drop;
9334 
9335 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9336 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9337 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9338 		    m->m_pkthdr.len);
9339 		goto drop;
9340 	}
9341 	plcp = (struct bwn_plcp6 *)(mp + padding);
9342 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
9343 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9344 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9345 		    m->m_pkthdr.len);
9346 		goto drop;
9347 	}
9348 	wh = mtod(m, struct ieee80211_frame_min *);
9349 
9350 	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9351 		device_printf(sc->sc_dev,
9352 		    "RX decryption attempted (old %d keyidx %#x)\n",
9353 		    BWN_ISOLDFMT(mac),
9354 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9355 
9356 	/* XXX calculating RSSI & noise & antenna */
9357 
9358 	if (phystat0 & BWN_RX_PHYST0_OFDM)
9359 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
9360 		    phytype == BWN_PHYTYPE_A);
9361 	else
9362 		rate = bwn_plcp_get_cckrate(mac, plcp);
9363 	if (rate == -1) {
9364 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9365 			goto drop;
9366 	}
9367 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9368 
9369 	/* RX radio tap */
9370 	if (ieee80211_radiotap_active(ic))
9371 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9372 	m_adj(m, -IEEE80211_CRC_LEN);
9373 
9374 	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
9375 	noise = mac->mac_stats.link_noise;
9376 
9377 	ifp->if_ipackets++;
9378 
9379 	BWN_UNLOCK(sc);
9380 
9381 	ni = ieee80211_find_rxnode(ic, wh);
9382 	if (ni != NULL) {
9383 		type = ieee80211_input(ni, m, rssi, noise);
9384 		ieee80211_free_node(ni);
9385 	} else
9386 		type = ieee80211_input_all(ic, m, rssi, noise);
9387 
9388 	BWN_LOCK(sc);
9389 	return;
9390 drop:
9391 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9392 }
9393 
9394 static void
9395 bwn_dma_handle_txeof(struct bwn_mac *mac,
9396     const struct bwn_txstatus *status)
9397 {
9398 	struct bwn_dma *dma = &mac->mac_method.dma;
9399 	struct bwn_dma_ring *dr;
9400 	struct bwn_dmadesc_generic *desc;
9401 	struct bwn_dmadesc_meta *meta;
9402 	struct bwn_softc *sc = mac->mac_sc;
9403 	struct ieee80211_node *ni;
9404 	struct ifnet *ifp = sc->sc_ifp;
9405 	struct mbuf *m;
9406 	int slot;
9407 
9408 	BWN_ASSERT_LOCKED(sc);
9409 
9410 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9411 	if (dr == NULL) {
9412 		device_printf(sc->sc_dev, "failed to parse cookie\n");
9413 		return;
9414 	}
9415 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9416 
9417 	while (1) {
9418 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
9419 		    ("%s:%d: fail", __func__, __LINE__));
9420 		dr->getdesc(dr, slot, &desc, &meta);
9421 
9422 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9423 			bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9424 		else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9425 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9426 
9427 		if (meta->mt_islast) {
9428 			KASSERT(meta->mt_m != NULL,
9429 			    ("%s:%d: fail", __func__, __LINE__));
9430 
9431 			ni = meta->mt_ni;
9432 			m = meta->mt_m;
9433 			if (ni != NULL) {
9434 				/*
9435 				 * Do any tx complete callback. Note this must
9436 				 * be done before releasing the node reference.
9437 				 */
9438 				if (m->m_flags & M_TXCB)
9439 					ieee80211_process_callback(ni, m, 0);
9440 				ieee80211_free_node(ni);
9441 				meta->mt_ni = NULL;
9442 			}
9443 			m_freem(m);
9444 			meta->mt_m = NULL;
9445 		} else {
9446 			KASSERT(meta->mt_m == NULL,
9447 			    ("%s:%d: fail", __func__, __LINE__));
9448 		}
9449 
9450 		dr->dr_usedslot--;
9451 		if (meta->mt_islast) {
9452 			ifp->if_opackets++;
9453 			break;
9454 		}
9455 		slot = bwn_dma_nextslot(dr, slot);
9456 	}
9457 	sc->sc_watchdog_timer = 0;
9458 	if (dr->dr_stop) {
9459 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9460 		    ("%s:%d: fail", __func__, __LINE__));
9461 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9462 		dr->dr_stop = 0;
9463 	}
9464 }
9465 
9466 static void
9467 bwn_pio_handle_txeof(struct bwn_mac *mac,
9468     const struct bwn_txstatus *status)
9469 {
9470 	struct bwn_pio_txqueue *tq;
9471 	struct bwn_pio_txpkt *tp = NULL;
9472 	struct bwn_softc *sc = mac->mac_sc;
9473 	struct ifnet *ifp = sc->sc_ifp;
9474 
9475 	BWN_ASSERT_LOCKED(sc);
9476 
9477 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9478 	if (tq == NULL)
9479 		return;
9480 
9481 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9482 	tq->tq_free++;
9483 
9484 	if (tp->tp_ni != NULL) {
9485 		/*
9486 		 * Do any tx complete callback.  Note this must
9487 		 * be done before releasing the node reference.
9488 		 */
9489 		if (tp->tp_m->m_flags & M_TXCB)
9490 			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9491 		ieee80211_free_node(tp->tp_ni);
9492 		tp->tp_ni = NULL;
9493 	}
9494 	m_freem(tp->tp_m);
9495 	tp->tp_m = NULL;
9496 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9497 
9498 	ifp->if_opackets++;
9499 
9500 	sc->sc_watchdog_timer = 0;
9501 	if (tq->tq_stop) {
9502 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9503 		tq->tq_stop = 0;
9504 	}
9505 }
9506 
9507 static void
9508 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9509 {
9510 	struct bwn_softc *sc = mac->mac_sc;
9511 	struct bwn_phy *phy = &mac->mac_phy;
9512 	struct ifnet *ifp = sc->sc_ifp;
9513 	struct ieee80211com *ic = ifp->if_l2com;
9514 	unsigned long now;
9515 	int result;
9516 
9517 	BWN_GETTIME(now);
9518 
9519 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9520 		return;
9521 	phy->nexttime = now + 2 * 1000;
9522 
9523 	if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9524 	    siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9525 		return;
9526 
9527 	if (phy->recalc_txpwr != NULL) {
9528 		result = phy->recalc_txpwr(mac,
9529 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9530 		if (result == BWN_TXPWR_RES_DONE)
9531 			return;
9532 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9533 		    ("%s: fail", __func__));
9534 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9535 
9536 		ieee80211_runtask(ic, &mac->mac_txpower);
9537 	}
9538 }
9539 
9540 static uint16_t
9541 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9542 {
9543 
9544 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9545 }
9546 
9547 static uint32_t
9548 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9549 {
9550 
9551 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9552 }
9553 
9554 static void
9555 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9556 {
9557 
9558 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9559 }
9560 
9561 static void
9562 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9563 {
9564 
9565 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9566 }
9567 
9568 static int
9569 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9570 {
9571 
9572 	switch (rate) {
9573 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9574 	case 12:
9575 		return (BWN_OFDM_RATE_6MB);
9576 	case 18:
9577 		return (BWN_OFDM_RATE_9MB);
9578 	case 24:
9579 		return (BWN_OFDM_RATE_12MB);
9580 	case 36:
9581 		return (BWN_OFDM_RATE_18MB);
9582 	case 48:
9583 		return (BWN_OFDM_RATE_24MB);
9584 	case 72:
9585 		return (BWN_OFDM_RATE_36MB);
9586 	case 96:
9587 		return (BWN_OFDM_RATE_48MB);
9588 	case 108:
9589 		return (BWN_OFDM_RATE_54MB);
9590 	/* CCK rates (NB: not IEEE std, device-specific) */
9591 	case 2:
9592 		return (BWN_CCK_RATE_1MB);
9593 	case 4:
9594 		return (BWN_CCK_RATE_2MB);
9595 	case 11:
9596 		return (BWN_CCK_RATE_5MB);
9597 	case 22:
9598 		return (BWN_CCK_RATE_11MB);
9599 	}
9600 
9601 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9602 	return (BWN_CCK_RATE_1MB);
9603 }
9604 
9605 static int
9606 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9607     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9608 {
9609 	const struct bwn_phy *phy = &mac->mac_phy;
9610 	struct bwn_softc *sc = mac->mac_sc;
9611 	struct ieee80211_frame *wh;
9612 	struct ieee80211_frame *protwh;
9613 	struct ieee80211_frame_cts *cts;
9614 	struct ieee80211_frame_rts *rts;
9615 	const struct ieee80211_txparam *tp;
9616 	struct ieee80211vap *vap = ni->ni_vap;
9617 	struct ifnet *ifp = sc->sc_ifp;
9618 	struct ieee80211com *ic = ifp->if_l2com;
9619 	struct mbuf *mprot;
9620 	unsigned int len;
9621 	uint32_t macctl = 0;
9622 	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9623 	uint16_t phyctl = 0;
9624 	uint8_t rate, rate_fb;
9625 
9626 	wh = mtod(m, struct ieee80211_frame *);
9627 	memset(txhdr, 0, sizeof(*txhdr));
9628 
9629 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9630 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9631 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9632 
9633 	/*
9634 	 * Find TX rate
9635 	 */
9636 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9637 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9638 		rate = rate_fb = tp->mgmtrate;
9639 	else if (ismcast)
9640 		rate = rate_fb = tp->mcastrate;
9641 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9642 		rate = rate_fb = tp->ucastrate;
9643 	else {
9644 		rix = ieee80211_ratectl_rate(ni, NULL, 0);
9645 		rate = ni->ni_txrate;
9646 
9647 		if (rix > 0)
9648 			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9649 			    IEEE80211_RATE_VAL;
9650 		else
9651 			rate_fb = rate;
9652 	}
9653 
9654 	sc->sc_tx_rate = rate;
9655 
9656 	rate = bwn_ieeerate2hwrate(sc, rate);
9657 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9658 
9659 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9660 	    bwn_plcp_getcck(rate);
9661 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9662 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9663 
9664 	if ((rate_fb == rate) ||
9665 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9666 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
9667 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9668 	else
9669 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9670 		    m->m_pkthdr.len, rate, isshort);
9671 
9672 	/* XXX TX encryption */
9673 	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9674 	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9675 	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9676 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9677 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9678 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9679 
9680 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9681 	    BWN_TX_EFT_FB_CCK;
9682 	txhdr->chan = phy->chan;
9683 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9684 	    BWN_TX_PHY_ENC_CCK;
9685 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9686 	     rate == BWN_CCK_RATE_11MB))
9687 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
9688 
9689 	/* XXX TX antenna selection */
9690 
9691 	switch (bwn_antenna_sanitize(mac, 0)) {
9692 	case 0:
9693 		phyctl |= BWN_TX_PHY_ANT01AUTO;
9694 		break;
9695 	case 1:
9696 		phyctl |= BWN_TX_PHY_ANT0;
9697 		break;
9698 	case 2:
9699 		phyctl |= BWN_TX_PHY_ANT1;
9700 		break;
9701 	case 3:
9702 		phyctl |= BWN_TX_PHY_ANT2;
9703 		break;
9704 	case 4:
9705 		phyctl |= BWN_TX_PHY_ANT3;
9706 		break;
9707 	default:
9708 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9709 	}
9710 
9711 	if (!ismcast)
9712 		macctl |= BWN_TX_MAC_ACK;
9713 
9714 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9715 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9716 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9717 		macctl |= BWN_TX_MAC_LONGFRAME;
9718 
9719 	if (ic->ic_flags & IEEE80211_F_USEPROT) {
9720 		/* XXX RTS rate is always 1MB??? */
9721 		rts_rate = BWN_CCK_RATE_1MB;
9722 		rts_rate_fb = bwn_get_fbrate(rts_rate);
9723 
9724 		protdur = ieee80211_compute_duration(ic->ic_rt,
9725 		    m->m_pkthdr.len, rate, isshort) +
9726 		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9727 
9728 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9729 			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9730 			    (txhdr->body.old.rts_frame) :
9731 			    (txhdr->body.new.rts_frame));
9732 			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9733 			    protdur);
9734 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9735 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9736 			    mprot->m_pkthdr.len);
9737 			m_freem(mprot);
9738 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9739 			len = sizeof(struct ieee80211_frame_cts);
9740 		} else {
9741 			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9742 			    (txhdr->body.old.rts_frame) :
9743 			    (txhdr->body.new.rts_frame));
9744 			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9745 			    isshort);
9746 			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9747 			    wh->i_addr2, protdur);
9748 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9749 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9750 			    mprot->m_pkthdr.len);
9751 			m_freem(mprot);
9752 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
9753 			len = sizeof(struct ieee80211_frame_rts);
9754 		}
9755 		len += IEEE80211_CRC_LEN;
9756 		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9757 		    &txhdr->body.old.rts_plcp :
9758 		    &txhdr->body.new.rts_plcp), len, rts_rate);
9759 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9760 		    rts_rate_fb);
9761 
9762 		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9763 		    (&txhdr->body.old.rts_frame) :
9764 		    (&txhdr->body.new.rts_frame));
9765 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9766 
9767 		if (BWN_ISOFDMRATE(rts_rate)) {
9768 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9769 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9770 		} else {
9771 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9772 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9773 		}
9774 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9775 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9776 	}
9777 
9778 	if (BWN_ISOLDFMT(mac))
9779 		txhdr->body.old.cookie = htole16(cookie);
9780 	else
9781 		txhdr->body.new.cookie = htole16(cookie);
9782 
9783 	txhdr->macctl = htole32(macctl);
9784 	txhdr->phyctl = htole16(phyctl);
9785 
9786 	/*
9787 	 * TX radio tap
9788 	 */
9789 	if (ieee80211_radiotap_active_vap(vap)) {
9790 		sc->sc_tx_th.wt_flags = 0;
9791 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9792 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9793 		if (isshort &&
9794 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9795 		     rate == BWN_CCK_RATE_11MB))
9796 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9797 		sc->sc_tx_th.wt_rate = rate;
9798 
9799 		ieee80211_radiotap_tx(vap, m);
9800 	}
9801 
9802 	return (0);
9803 }
9804 
9805 static void
9806 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9807     const uint8_t rate)
9808 {
9809 	uint32_t d, plen;
9810 	uint8_t *raw = plcp->o.raw;
9811 
9812 	if (BWN_ISOFDMRATE(rate)) {
9813 		d = bwn_plcp_getofdm(rate);
9814 		KASSERT(!(octets & 0xf000),
9815 		    ("%s:%d: fail", __func__, __LINE__));
9816 		d |= (octets << 5);
9817 		plcp->o.data = htole32(d);
9818 	} else {
9819 		plen = octets * 16 / rate;
9820 		if ((octets * 16 % rate) > 0) {
9821 			plen++;
9822 			if ((rate == BWN_CCK_RATE_11MB)
9823 			    && ((octets * 8 % 11) < 4)) {
9824 				raw[1] = 0x84;
9825 			} else
9826 				raw[1] = 0x04;
9827 		} else
9828 			raw[1] = 0x04;
9829 		plcp->o.data |= htole32(plen << 16);
9830 		raw[0] = bwn_plcp_getcck(rate);
9831 	}
9832 }
9833 
9834 static uint8_t
9835 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9836 {
9837 	struct bwn_softc *sc = mac->mac_sc;
9838 	uint8_t mask;
9839 
9840 	if (n == 0)
9841 		return (0);
9842 	if (mac->mac_phy.gmode)
9843 		mask = siba_sprom_get_ant_bg(sc->sc_dev);
9844 	else
9845 		mask = siba_sprom_get_ant_a(sc->sc_dev);
9846 	if (!(mask & (1 << (n - 1))))
9847 		return (0);
9848 	return (n);
9849 }
9850 
9851 static uint8_t
9852 bwn_get_fbrate(uint8_t bitrate)
9853 {
9854 	switch (bitrate) {
9855 	case BWN_CCK_RATE_1MB:
9856 		return (BWN_CCK_RATE_1MB);
9857 	case BWN_CCK_RATE_2MB:
9858 		return (BWN_CCK_RATE_1MB);
9859 	case BWN_CCK_RATE_5MB:
9860 		return (BWN_CCK_RATE_2MB);
9861 	case BWN_CCK_RATE_11MB:
9862 		return (BWN_CCK_RATE_5MB);
9863 	case BWN_OFDM_RATE_6MB:
9864 		return (BWN_CCK_RATE_5MB);
9865 	case BWN_OFDM_RATE_9MB:
9866 		return (BWN_OFDM_RATE_6MB);
9867 	case BWN_OFDM_RATE_12MB:
9868 		return (BWN_OFDM_RATE_9MB);
9869 	case BWN_OFDM_RATE_18MB:
9870 		return (BWN_OFDM_RATE_12MB);
9871 	case BWN_OFDM_RATE_24MB:
9872 		return (BWN_OFDM_RATE_18MB);
9873 	case BWN_OFDM_RATE_36MB:
9874 		return (BWN_OFDM_RATE_24MB);
9875 	case BWN_OFDM_RATE_48MB:
9876 		return (BWN_OFDM_RATE_36MB);
9877 	case BWN_OFDM_RATE_54MB:
9878 		return (BWN_OFDM_RATE_48MB);
9879 	}
9880 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9881 	return (0);
9882 }
9883 
9884 static uint32_t
9885 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9886     uint32_t ctl, const void *_data, int len)
9887 {
9888 	struct bwn_softc *sc = mac->mac_sc;
9889 	uint32_t value = 0;
9890 	const uint8_t *data = _data;
9891 
9892 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9893 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9894 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9895 
9896 	siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9897 	    tq->tq_base + BWN_PIO8_TXDATA);
9898 	if (len & 3) {
9899 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9900 		    BWN_PIO8_TXCTL_24_31);
9901 		data = &(data[len - 1]);
9902 		switch (len & 3) {
9903 		case 3:
9904 			ctl |= BWN_PIO8_TXCTL_16_23;
9905 			value |= (uint32_t)(*data) << 16;
9906 			data--;
9907 		case 2:
9908 			ctl |= BWN_PIO8_TXCTL_8_15;
9909 			value |= (uint32_t)(*data) << 8;
9910 			data--;
9911 		case 1:
9912 			value |= (uint32_t)(*data);
9913 		}
9914 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9915 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9916 	}
9917 
9918 	return (ctl);
9919 }
9920 
9921 static void
9922 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9923     uint16_t offset, uint32_t value)
9924 {
9925 
9926 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
9927 }
9928 
9929 static uint16_t
9930 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9931     uint16_t ctl, const void *_data, int len)
9932 {
9933 	struct bwn_softc *sc = mac->mac_sc;
9934 	const uint8_t *data = _data;
9935 
9936 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9937 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9938 
9939 	siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9940 	    tq->tq_base + BWN_PIO_TXDATA);
9941 	if (len & 1) {
9942 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9943 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9944 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9945 	}
9946 
9947 	return (ctl);
9948 }
9949 
9950 static uint16_t
9951 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9952     uint16_t ctl, struct mbuf *m0)
9953 {
9954 	int i, j = 0;
9955 	uint16_t data = 0;
9956 	const uint8_t *buf;
9957 	struct mbuf *m = m0;
9958 
9959 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9960 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9961 
9962 	for (; m != NULL; m = m->m_next) {
9963 		buf = mtod(m, const uint8_t *);
9964 		for (i = 0; i < m->m_len; i++) {
9965 			if (!((j++) % 2))
9966 				data |= buf[i];
9967 			else {
9968 				data |= (buf[i] << 8);
9969 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9970 				data = 0;
9971 			}
9972 		}
9973 	}
9974 	if (m0->m_pkthdr.len % 2) {
9975 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9976 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9977 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9978 	}
9979 
9980 	return (ctl);
9981 }
9982 
9983 static void
9984 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9985 {
9986 
9987 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
9988 		return;
9989 	BWN_WRITE_2(mac, 0x684, 510 + time);
9990 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9991 }
9992 
9993 static struct bwn_dma_ring *
9994 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9995 {
9996 
9997 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9998 		return (mac->mac_method.dma.wme[WME_AC_BE]);
9999 
10000 	switch (prio) {
10001 	case 3:
10002 		return (mac->mac_method.dma.wme[WME_AC_VO]);
10003 	case 2:
10004 		return (mac->mac_method.dma.wme[WME_AC_VI]);
10005 	case 0:
10006 		return (mac->mac_method.dma.wme[WME_AC_BE]);
10007 	case 1:
10008 		return (mac->mac_method.dma.wme[WME_AC_BK]);
10009 	}
10010 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10011 	return (NULL);
10012 }
10013 
10014 static int
10015 bwn_dma_getslot(struct bwn_dma_ring *dr)
10016 {
10017 	int slot;
10018 
10019 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10020 
10021 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10022 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10023 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10024 
10025 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10026 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10027 	dr->dr_curslot = slot;
10028 	dr->dr_usedslot++;
10029 
10030 	return (slot);
10031 }
10032 
10033 static int
10034 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10035 {
10036 	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10037 	unsigned int a, b, c, d;
10038 	unsigned int avg;
10039 	uint32_t tmp;
10040 
10041 	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10042 	a = tmp & 0xff;
10043 	b = (tmp >> 8) & 0xff;
10044 	c = (tmp >> 16) & 0xff;
10045 	d = (tmp >> 24) & 0xff;
10046 	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10047 	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10048 		return (ENOENT);
10049 	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10050 	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10051 	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10052 
10053 	if (ofdm) {
10054 		a = (a + 32) & 0x3f;
10055 		b = (b + 32) & 0x3f;
10056 		c = (c + 32) & 0x3f;
10057 		d = (d + 32) & 0x3f;
10058 	}
10059 
10060 	avg = (a + b + c + d + 2) / 4;
10061 	if (ofdm) {
10062 		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10063 		    & BWN_HF_4DB_CCK_POWERBOOST)
10064 			avg = (avg >= 13) ? (avg - 13) : 0;
10065 	}
10066 	return (avg);
10067 }
10068 
10069 static void
10070 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10071 {
10072 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10073 	int rfatt = *rfattp;
10074 	int bbatt = *bbattp;
10075 
10076 	while (1) {
10077 		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10078 			break;
10079 		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10080 			break;
10081 		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10082 			break;
10083 		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10084 			break;
10085 		if (bbatt > lo->bbatt.max) {
10086 			bbatt -= 4;
10087 			rfatt += 1;
10088 			continue;
10089 		}
10090 		if (bbatt < lo->bbatt.min) {
10091 			bbatt += 4;
10092 			rfatt -= 1;
10093 			continue;
10094 		}
10095 		if (rfatt > lo->rfatt.max) {
10096 			rfatt -= 1;
10097 			bbatt += 4;
10098 			continue;
10099 		}
10100 		if (rfatt < lo->rfatt.min) {
10101 			rfatt += 1;
10102 			bbatt -= 4;
10103 			continue;
10104 		}
10105 		break;
10106 	}
10107 
10108 	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10109 	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10110 }
10111 
10112 static void
10113 bwn_phy_lock(struct bwn_mac *mac)
10114 {
10115 	struct bwn_softc *sc = mac->mac_sc;
10116 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10117 
10118 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10119 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10120 
10121 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10122 		bwn_psctl(mac, BWN_PS_AWAKE);
10123 }
10124 
10125 static void
10126 bwn_phy_unlock(struct bwn_mac *mac)
10127 {
10128 	struct bwn_softc *sc = mac->mac_sc;
10129 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10130 
10131 	KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10132 	    ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10133 
10134 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10135 		bwn_psctl(mac, 0);
10136 }
10137 
10138 static void
10139 bwn_rf_lock(struct bwn_mac *mac)
10140 {
10141 
10142 	BWN_WRITE_4(mac, BWN_MACCTL,
10143 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10144 	BWN_READ_4(mac, BWN_MACCTL);
10145 	DELAY(10);
10146 }
10147 
10148 static void
10149 bwn_rf_unlock(struct bwn_mac *mac)
10150 {
10151 
10152 	BWN_READ_2(mac, BWN_PHYVER);
10153 	BWN_WRITE_4(mac, BWN_MACCTL,
10154 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10155 }
10156 
10157 static struct bwn_pio_txqueue *
10158 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10159     struct bwn_pio_txpkt **pack)
10160 {
10161 	struct bwn_pio *pio = &mac->mac_method.pio;
10162 	struct bwn_pio_txqueue *tq = NULL;
10163 	unsigned int index;
10164 
10165 	switch (cookie & 0xf000) {
10166 	case 0x1000:
10167 		tq = &pio->wme[WME_AC_BK];
10168 		break;
10169 	case 0x2000:
10170 		tq = &pio->wme[WME_AC_BE];
10171 		break;
10172 	case 0x3000:
10173 		tq = &pio->wme[WME_AC_VI];
10174 		break;
10175 	case 0x4000:
10176 		tq = &pio->wme[WME_AC_VO];
10177 		break;
10178 	case 0x5000:
10179 		tq = &pio->mcast;
10180 		break;
10181 	}
10182 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10183 	if (tq == NULL)
10184 		return (NULL);
10185 	index = (cookie & 0x0fff);
10186 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10187 	if (index >= N(tq->tq_pkts))
10188 		return (NULL);
10189 	*pack = &tq->tq_pkts[index];
10190 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10191 	return (tq);
10192 }
10193 
10194 static void
10195 bwn_txpwr(void *arg, int npending)
10196 {
10197 	struct bwn_mac *mac = arg;
10198 	struct bwn_softc *sc = mac->mac_sc;
10199 
10200 	BWN_LOCK(sc);
10201 	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10202 	    mac->mac_phy.set_txpwr != NULL)
10203 		mac->mac_phy.set_txpwr(mac);
10204 	BWN_UNLOCK(sc);
10205 }
10206 
10207 static void
10208 bwn_task_15s(struct bwn_mac *mac)
10209 {
10210 	uint16_t reg;
10211 
10212 	if (mac->mac_fw.opensource) {
10213 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10214 		if (reg) {
10215 			bwn_restart(mac, "fw watchdog");
10216 			return;
10217 		}
10218 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10219 	}
10220 	if (mac->mac_phy.task_15s)
10221 		mac->mac_phy.task_15s(mac);
10222 
10223 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10224 }
10225 
10226 static void
10227 bwn_task_30s(struct bwn_mac *mac)
10228 {
10229 
10230 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10231 		return;
10232 	mac->mac_noise.noi_running = 1;
10233 	mac->mac_noise.noi_nsamples = 0;
10234 
10235 	bwn_noise_gensample(mac);
10236 }
10237 
10238 static void
10239 bwn_task_60s(struct bwn_mac *mac)
10240 {
10241 
10242 	if (mac->mac_phy.task_60s)
10243 		mac->mac_phy.task_60s(mac);
10244 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10245 }
10246 
10247 static void
10248 bwn_tasks(void *arg)
10249 {
10250 	struct bwn_mac *mac = arg;
10251 	struct bwn_softc *sc = mac->mac_sc;
10252 
10253 	BWN_ASSERT_LOCKED(sc);
10254 	if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10255 		return;
10256 
10257 	if (mac->mac_task_state % 4 == 0)
10258 		bwn_task_60s(mac);
10259 	if (mac->mac_task_state % 2 == 0)
10260 		bwn_task_30s(mac);
10261 	bwn_task_15s(mac);
10262 
10263 	mac->mac_task_state++;
10264 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10265 }
10266 
10267 static int
10268 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10269 {
10270 	struct bwn_softc *sc = mac->mac_sc;
10271 
10272 	KASSERT(a == 0, ("not support APHY\n"));
10273 
10274 	switch (plcp->o.raw[0] & 0xf) {
10275 	case 0xb:
10276 		return (BWN_OFDM_RATE_6MB);
10277 	case 0xf:
10278 		return (BWN_OFDM_RATE_9MB);
10279 	case 0xa:
10280 		return (BWN_OFDM_RATE_12MB);
10281 	case 0xe:
10282 		return (BWN_OFDM_RATE_18MB);
10283 	case 0x9:
10284 		return (BWN_OFDM_RATE_24MB);
10285 	case 0xd:
10286 		return (BWN_OFDM_RATE_36MB);
10287 	case 0x8:
10288 		return (BWN_OFDM_RATE_48MB);
10289 	case 0xc:
10290 		return (BWN_OFDM_RATE_54MB);
10291 	}
10292 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10293 	    plcp->o.raw[0] & 0xf);
10294 	return (-1);
10295 }
10296 
10297 static int
10298 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10299 {
10300 	struct bwn_softc *sc = mac->mac_sc;
10301 
10302 	switch (plcp->o.raw[0]) {
10303 	case 0x0a:
10304 		return (BWN_CCK_RATE_1MB);
10305 	case 0x14:
10306 		return (BWN_CCK_RATE_2MB);
10307 	case 0x37:
10308 		return (BWN_CCK_RATE_5MB);
10309 	case 0x6e:
10310 		return (BWN_CCK_RATE_11MB);
10311 	}
10312 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10313 	return (-1);
10314 }
10315 
10316 static void
10317 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10318     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10319     int rssi, int noise)
10320 {
10321 	struct bwn_softc *sc = mac->mac_sc;
10322 	const struct ieee80211_frame_min *wh;
10323 	uint64_t tsf;
10324 	uint16_t low_mactime_now;
10325 
10326 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10327 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10328 
10329 	wh = mtod(m, const struct ieee80211_frame_min *);
10330 	if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10331 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10332 
10333 	bwn_tsf_read(mac, &tsf);
10334 	low_mactime_now = tsf;
10335 	tsf = tsf & ~0xffffULL;
10336 	tsf += le16toh(rxhdr->mac_time);
10337 	if (low_mactime_now < le16toh(rxhdr->mac_time))
10338 		tsf -= 0x10000;
10339 
10340 	sc->sc_rx_th.wr_tsf = tsf;
10341 	sc->sc_rx_th.wr_rate = rate;
10342 	sc->sc_rx_th.wr_antsignal = rssi;
10343 	sc->sc_rx_th.wr_antnoise = noise;
10344 }
10345 
10346 static void
10347 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10348 {
10349 	uint32_t low, high;
10350 
10351 	KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10352 	    ("%s:%d: fail", __func__, __LINE__));
10353 
10354 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10355 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10356 	*tsf = high;
10357 	*tsf <<= 32;
10358 	*tsf |= low;
10359 }
10360 
10361 static int
10362 bwn_dma_attach(struct bwn_mac *mac)
10363 {
10364 	struct bwn_dma *dma = &mac->mac_method.dma;
10365 	struct bwn_softc *sc = mac->mac_sc;
10366 	bus_addr_t lowaddr = 0;
10367 	int error;
10368 
10369 	if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10370 		return (0);
10371 
10372 	KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10373 
10374 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
10375 
10376 	dma->dmatype = bwn_dma_gettype(mac);
10377 	if (dma->dmatype == BWN_DMA_30BIT)
10378 		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10379 	else if (dma->dmatype == BWN_DMA_32BIT)
10380 		lowaddr = BUS_SPACE_MAXADDR_32BIT;
10381 	else
10382 		lowaddr = BUS_SPACE_MAXADDR;
10383 
10384 	/*
10385 	 * Create top level DMA tag
10386 	 */
10387 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
10388 			       BWN_ALIGN, 0,		/* alignment, bounds */
10389 			       lowaddr,			/* lowaddr */
10390 			       BUS_SPACE_MAXADDR,	/* highaddr */
10391 			       NULL, NULL,		/* filter, filterarg */
10392 			       MAXBSIZE,		/* maxsize */
10393 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
10394 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
10395 			       0,			/* flags */
10396 			       NULL, NULL,		/* lockfunc, lockarg */
10397 			       &dma->parent_dtag);
10398 	if (error) {
10399 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10400 		return (error);
10401 	}
10402 
10403 	/*
10404 	 * Create TX/RX mbuf DMA tag
10405 	 */
10406 	error = bus_dma_tag_create(dma->parent_dtag,
10407 				1,
10408 				0,
10409 				BUS_SPACE_MAXADDR,
10410 				BUS_SPACE_MAXADDR,
10411 				NULL, NULL,
10412 				MCLBYTES,
10413 				1,
10414 				BUS_SPACE_MAXSIZE_32BIT,
10415 				0,
10416 				NULL, NULL,
10417 				&dma->rxbuf_dtag);
10418 	if (error) {
10419 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10420 		goto fail0;
10421 	}
10422 	error = bus_dma_tag_create(dma->parent_dtag,
10423 				1,
10424 				0,
10425 				BUS_SPACE_MAXADDR,
10426 				BUS_SPACE_MAXADDR,
10427 				NULL, NULL,
10428 				MCLBYTES,
10429 				1,
10430 				BUS_SPACE_MAXSIZE_32BIT,
10431 				0,
10432 				NULL, NULL,
10433 				&dma->txbuf_dtag);
10434 	if (error) {
10435 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10436 		goto fail1;
10437 	}
10438 
10439 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10440 	if (!dma->wme[WME_AC_BK])
10441 		goto fail2;
10442 
10443 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10444 	if (!dma->wme[WME_AC_BE])
10445 		goto fail3;
10446 
10447 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10448 	if (!dma->wme[WME_AC_VI])
10449 		goto fail4;
10450 
10451 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10452 	if (!dma->wme[WME_AC_VO])
10453 		goto fail5;
10454 
10455 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10456 	if (!dma->mcast)
10457 		goto fail6;
10458 	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10459 	if (!dma->rx)
10460 		goto fail7;
10461 
10462 	return (error);
10463 
10464 fail7:	bwn_dma_ringfree(&dma->mcast);
10465 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10466 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10467 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10468 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10469 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
10470 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
10471 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
10472 	return (error);
10473 }
10474 
10475 static struct bwn_dma_ring *
10476 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10477     uint16_t cookie, int *slot)
10478 {
10479 	struct bwn_dma *dma = &mac->mac_method.dma;
10480 	struct bwn_dma_ring *dr;
10481 	struct bwn_softc *sc = mac->mac_sc;
10482 
10483 	BWN_ASSERT_LOCKED(mac->mac_sc);
10484 
10485 	switch (cookie & 0xf000) {
10486 	case 0x1000:
10487 		dr = dma->wme[WME_AC_BK];
10488 		break;
10489 	case 0x2000:
10490 		dr = dma->wme[WME_AC_BE];
10491 		break;
10492 	case 0x3000:
10493 		dr = dma->wme[WME_AC_VI];
10494 		break;
10495 	case 0x4000:
10496 		dr = dma->wme[WME_AC_VO];
10497 		break;
10498 	case 0x5000:
10499 		dr = dma->mcast;
10500 		break;
10501 	default:
10502 		dr = NULL;
10503 		KASSERT(0 == 1,
10504 		    ("invalid cookie value %d", cookie & 0xf000));
10505 	}
10506 	*slot = (cookie & 0x0fff);
10507 	if (*slot < 0 || *slot >= dr->dr_numslots) {
10508 		/*
10509 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10510 		 * that it occurs events which have same H/W sequence numbers.
10511 		 * When it's occurred just prints a WARNING msgs and ignores.
10512 		 */
10513 		KASSERT(status->seq == dma->lastseq,
10514 		    ("%s:%d: fail", __func__, __LINE__));
10515 		device_printf(sc->sc_dev,
10516 		    "out of slot ranges (0 < %d < %d)\n", *slot,
10517 		    dr->dr_numslots);
10518 		return (NULL);
10519 	}
10520 	dma->lastseq = status->seq;
10521 	return (dr);
10522 }
10523 
10524 static void
10525 bwn_dma_stop(struct bwn_mac *mac)
10526 {
10527 	struct bwn_dma *dma;
10528 
10529 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10530 		return;
10531 	dma = &mac->mac_method.dma;
10532 
10533 	bwn_dma_ringstop(&dma->rx);
10534 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10535 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10536 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10537 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10538 	bwn_dma_ringstop(&dma->mcast);
10539 }
10540 
10541 static void
10542 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10543 {
10544 
10545 	if (dr == NULL)
10546 		return;
10547 
10548 	bwn_dma_cleanup(*dr);
10549 }
10550 
10551 static void
10552 bwn_pio_stop(struct bwn_mac *mac)
10553 {
10554 	struct bwn_pio *pio;
10555 
10556 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10557 		return;
10558 	pio = &mac->mac_method.pio;
10559 
10560 	bwn_destroy_queue_tx(&pio->mcast);
10561 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10562 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10563 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10564 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10565 }
10566 
10567 static void
10568 bwn_led_attach(struct bwn_mac *mac)
10569 {
10570 	struct bwn_softc *sc = mac->mac_sc;
10571 	const uint8_t *led_act = NULL;
10572 	uint16_t val[BWN_LED_MAX];
10573 	int i;
10574 
10575 	sc->sc_led_idle = (2350 * hz) / 1000;
10576 	sc->sc_led_blink = 1;
10577 
10578 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10579 		if (siba_get_pci_subvendor(sc->sc_dev) ==
10580 		    bwn_vendor_led_act[i].vid) {
10581 			led_act = bwn_vendor_led_act[i].led_act;
10582 			break;
10583 		}
10584 	}
10585 	if (led_act == NULL)
10586 		led_act = bwn_default_led_act;
10587 
10588 	val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10589 	val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10590 	val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10591 	val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10592 
10593 	for (i = 0; i < BWN_LED_MAX; ++i) {
10594 		struct bwn_led *led = &sc->sc_leds[i];
10595 
10596 		if (val[i] == 0xff) {
10597 			led->led_act = led_act[i];
10598 		} else {
10599 			if (val[i] & BWN_LED_ACT_LOW)
10600 				led->led_flags |= BWN_LED_F_ACTLOW;
10601 			led->led_act = val[i] & BWN_LED_ACT_MASK;
10602 		}
10603 		led->led_mask = (1 << i);
10604 
10605 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10606 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
10607 		    led->led_act == BWN_LED_ACT_BLINK) {
10608 			led->led_flags |= BWN_LED_F_BLINK;
10609 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10610 				led->led_flags |= BWN_LED_F_POLLABLE;
10611 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10612 				led->led_flags |= BWN_LED_F_SLOW;
10613 
10614 			if (sc->sc_blink_led == NULL) {
10615 				sc->sc_blink_led = led;
10616 				if (led->led_flags & BWN_LED_F_SLOW)
10617 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
10618 			}
10619 		}
10620 
10621 		DPRINTF(sc, BWN_DEBUG_LED,
10622 		    "%dth led, act %d, lowact %d\n", i,
10623 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10624 	}
10625 	callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10626 }
10627 
10628 static __inline uint16_t
10629 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10630 {
10631 
10632 	if (led->led_flags & BWN_LED_F_ACTLOW)
10633 		on = !on;
10634 	if (on)
10635 		val |= led->led_mask;
10636 	else
10637 		val &= ~led->led_mask;
10638 	return val;
10639 }
10640 
10641 static void
10642 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10643 {
10644 	struct bwn_softc *sc = mac->mac_sc;
10645 	struct ifnet *ifp = sc->sc_ifp;
10646 	struct ieee80211com *ic = ifp->if_l2com;
10647 	uint16_t val;
10648 	int i;
10649 
10650 	if (nstate == IEEE80211_S_INIT) {
10651 		callout_stop(&sc->sc_led_blink_ch);
10652 		sc->sc_led_blinking = 0;
10653 	}
10654 
10655 	if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10656 		return;
10657 
10658 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10659 	for (i = 0; i < BWN_LED_MAX; ++i) {
10660 		struct bwn_led *led = &sc->sc_leds[i];
10661 		int on;
10662 
10663 		if (led->led_act == BWN_LED_ACT_UNKN ||
10664 		    led->led_act == BWN_LED_ACT_NULL)
10665 			continue;
10666 
10667 		if ((led->led_flags & BWN_LED_F_BLINK) &&
10668 		    nstate != IEEE80211_S_INIT)
10669 			continue;
10670 
10671 		switch (led->led_act) {
10672 		case BWN_LED_ACT_ON:    /* Always on */
10673 			on = 1;
10674 			break;
10675 		case BWN_LED_ACT_OFF:   /* Always off */
10676 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10677 			on = 0;
10678 			break;
10679 		default:
10680 			on = 1;
10681 			switch (nstate) {
10682 			case IEEE80211_S_INIT:
10683 				on = 0;
10684 				break;
10685 			case IEEE80211_S_RUN:
10686 				if (led->led_act == BWN_LED_ACT_11G &&
10687 				    ic->ic_curmode != IEEE80211_MODE_11G)
10688 					on = 0;
10689 				break;
10690 			default:
10691 				if (led->led_act == BWN_LED_ACT_ASSOC)
10692 					on = 0;
10693 				break;
10694 			}
10695 			break;
10696 		}
10697 
10698 		val = bwn_led_onoff(led, val, on);
10699 	}
10700 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10701 }
10702 
10703 static void
10704 bwn_led_event(struct bwn_mac *mac, int event)
10705 {
10706 	struct bwn_softc *sc = mac->mac_sc;
10707 	struct bwn_led *led = sc->sc_blink_led;
10708 	int rate;
10709 
10710 	if (event == BWN_LED_EVENT_POLL) {
10711 		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10712 			return;
10713 		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10714 			return;
10715 	}
10716 
10717 	sc->sc_led_ticks = ticks;
10718 	if (sc->sc_led_blinking)
10719 		return;
10720 
10721 	switch (event) {
10722 	case BWN_LED_EVENT_RX:
10723 		rate = sc->sc_rx_rate;
10724 		break;
10725 	case BWN_LED_EVENT_TX:
10726 		rate = sc->sc_tx_rate;
10727 		break;
10728 	case BWN_LED_EVENT_POLL:
10729 		rate = 0;
10730 		break;
10731 	default:
10732 		panic("unknown LED event %d\n", event);
10733 		break;
10734 	}
10735 	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10736 	    bwn_led_duration[rate].off_dur);
10737 }
10738 
10739 static void
10740 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10741 {
10742 	struct bwn_softc *sc = mac->mac_sc;
10743 	struct bwn_led *led = sc->sc_blink_led;
10744 	uint16_t val;
10745 
10746 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10747 	val = bwn_led_onoff(led, val, 1);
10748 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10749 
10750 	if (led->led_flags & BWN_LED_F_SLOW) {
10751 		BWN_LED_SLOWDOWN(on_dur);
10752 		BWN_LED_SLOWDOWN(off_dur);
10753 	}
10754 
10755 	sc->sc_led_blinking = 1;
10756 	sc->sc_led_blink_offdur = off_dur;
10757 
10758 	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10759 }
10760 
10761 static void
10762 bwn_led_blink_next(void *arg)
10763 {
10764 	struct bwn_mac *mac = arg;
10765 	struct bwn_softc *sc = mac->mac_sc;
10766 	uint16_t val;
10767 
10768 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10769 	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10770 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10771 
10772 	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10773 	    bwn_led_blink_end, mac);
10774 }
10775 
10776 static void
10777 bwn_led_blink_end(void *arg)
10778 {
10779 	struct bwn_mac *mac = arg;
10780 	struct bwn_softc *sc = mac->mac_sc;
10781 
10782 	sc->sc_led_blinking = 0;
10783 }
10784 
10785 static int
10786 bwn_suspend(device_t dev)
10787 {
10788 	struct bwn_softc *sc = device_get_softc(dev);
10789 
10790 	bwn_stop(sc, 1);
10791 	return (0);
10792 }
10793 
10794 static int
10795 bwn_resume(device_t dev)
10796 {
10797 	struct bwn_softc *sc = device_get_softc(dev);
10798 	struct ifnet *ifp = sc->sc_ifp;
10799 
10800 	if (ifp->if_flags & IFF_UP)
10801 		bwn_init(sc);
10802 	return (0);
10803 }
10804 
10805 static void
10806 bwn_rfswitch(void *arg)
10807 {
10808 	struct bwn_softc *sc = arg;
10809 	struct bwn_mac *mac = sc->sc_curmac;
10810 	int cur = 0, prev = 0;
10811 
10812 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10813 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
10814 
10815 	if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10816 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10817 			& BWN_RF_HWENABLED_HI_MASK))
10818 			cur = 1;
10819 	} else {
10820 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10821 		    & BWN_RF_HWENABLED_LO_MASK)
10822 			cur = 1;
10823 	}
10824 
10825 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10826 		prev = 1;
10827 
10828 	if (cur != prev) {
10829 		if (cur)
10830 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10831 		else
10832 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10833 
10834 		device_printf(sc->sc_dev,
10835 		    "status of RF switch is changed to %s\n",
10836 		    cur ? "ON" : "OFF");
10837 		if (cur != mac->mac_phy.rf_on) {
10838 			if (cur)
10839 				bwn_rf_turnon(mac);
10840 			else
10841 				bwn_rf_turnoff(mac);
10842 		}
10843 	}
10844 
10845 	callout_schedule(&sc->sc_rfswitch_ch, hz);
10846 }
10847 
10848 static void
10849 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10850 {
10851 	struct bwn_phy *phy = &mac->mac_phy;
10852 	struct bwn_phy_lp *plp = &phy->phy_lp;
10853 
10854 	plp->plp_antenna = BWN_ANT_DEFAULT;
10855 }
10856 
10857 static int
10858 bwn_phy_lp_init(struct bwn_mac *mac)
10859 {
10860 	static const struct bwn_stxtable tables[] = {
10861 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10862 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10863 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10864 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10865 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10866 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10867 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10868 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10869 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10870 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10871 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10872 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10873 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10874 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10875 		{ 2, 11, 0x40, 0, 0x0f }
10876 	};
10877 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10878 	struct bwn_softc *sc = mac->mac_sc;
10879 	const struct bwn_stxtable *st;
10880 	struct ifnet *ifp = sc->sc_ifp;
10881 	struct ieee80211com *ic = ifp->if_l2com;
10882 	int i, error;
10883 	uint16_t tmp;
10884 
10885 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
10886 	bwn_phy_lp_bbinit(mac);
10887 
10888 	/* initialize RF */
10889 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10890 	DELAY(1);
10891 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10892 	DELAY(1);
10893 
10894 	if (mac->mac_phy.rf_ver == 0x2062)
10895 		bwn_phy_lp_b2062_init(mac);
10896 	else {
10897 		bwn_phy_lp_b2063_init(mac);
10898 
10899 		/* synchronize stx table. */
10900 		for (i = 0; i < N(tables); i++) {
10901 			st = &tables[i];
10902 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
10903 			tmp >>= st->st_rfshift;
10904 			tmp <<= st->st_physhift;
10905 			BWN_PHY_SETMASK(mac,
10906 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10907 			    ~(st->st_mask << st->st_physhift), tmp);
10908 		}
10909 
10910 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10911 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10912 	}
10913 
10914 	/* calibrate RC */
10915 	if (mac->mac_phy.rev >= 2)
10916 		bwn_phy_lp_rxcal_r2(mac);
10917 	else if (!plp->plp_rccap) {
10918 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10919 			bwn_phy_lp_rccal_r12(mac);
10920 	} else
10921 		bwn_phy_lp_set_rccap(mac);
10922 
10923 	error = bwn_phy_lp_switch_channel(mac, 7);
10924 	if (error)
10925 		device_printf(sc->sc_dev,
10926 		    "failed to change channel 7 (%d)\n", error);
10927 	bwn_phy_lp_txpctl_init(mac);
10928 	bwn_phy_lp_calib(mac);
10929 	return (0);
10930 }
10931 
10932 static uint16_t
10933 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10934 {
10935 
10936 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10937 	return (BWN_READ_2(mac, BWN_PHYDATA));
10938 }
10939 
10940 static void
10941 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10942 {
10943 
10944 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10945 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
10946 }
10947 
10948 static void
10949 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10950     uint16_t set)
10951 {
10952 
10953 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10954 	BWN_WRITE_2(mac, BWN_PHYDATA,
10955 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10956 }
10957 
10958 static uint16_t
10959 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10960 {
10961 
10962 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10963 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
10964 		reg |= 0x100;
10965 	if (mac->mac_phy.rev >= 2)
10966 		reg |= 0x200;
10967 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10968 	return BWN_READ_2(mac, BWN_RFDATALO);
10969 }
10970 
10971 static void
10972 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10973 {
10974 
10975 	KASSERT(reg != 1, ("unaccessible register %d", reg));
10976 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
10977 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
10978 }
10979 
10980 static void
10981 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10982 {
10983 
10984 	if (on) {
10985 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10986 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10987 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10988 		return;
10989 	}
10990 
10991 	if (mac->mac_phy.rev >= 2) {
10992 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10993 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10994 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10995 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10996 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10997 		return;
10998 	}
10999 
11000 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11001 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11002 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11003 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11004 }
11005 
11006 static int
11007 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11008 {
11009 	struct bwn_phy *phy = &mac->mac_phy;
11010 	struct bwn_phy_lp *plp = &phy->phy_lp;
11011 	int error;
11012 
11013 	if (phy->rf_ver == 0x2063) {
11014 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11015 		if (error)
11016 			return (error);
11017 	} else {
11018 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11019 		if (error)
11020 			return (error);
11021 		bwn_phy_lp_set_anafilter(mac, chan);
11022 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11023 	}
11024 
11025 	plp->plp_chan = chan;
11026 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11027 	return (0);
11028 }
11029 
11030 static uint32_t
11031 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11032 {
11033 	struct bwn_softc *sc = mac->mac_sc;
11034 	struct ifnet *ifp = sc->sc_ifp;
11035 	struct ieee80211com *ic = ifp->if_l2com;
11036 
11037 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11038 }
11039 
11040 static void
11041 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11042 {
11043 	struct bwn_phy *phy = &mac->mac_phy;
11044 	struct bwn_phy_lp *plp = &phy->phy_lp;
11045 
11046 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11047 		return;
11048 
11049 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11050 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11051 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11052 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11053 	plp->plp_antenna = antenna;
11054 }
11055 
11056 static void
11057 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11058 {
11059 
11060 	bwn_phy_lp_calib(mac);
11061 }
11062 
11063 static void
11064 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11065 {
11066 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11067 	struct bwn_softc *sc = mac->mac_sc;
11068 	struct ifnet *ifp = sc->sc_ifp;
11069 	struct ieee80211com *ic = ifp->if_l2com;
11070 
11071 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11072 		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11073 		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11074 		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11075 		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11076 		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11077 		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11078 		return;
11079 	}
11080 
11081 	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11082 	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11083 	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11084 	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11085 	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11086 	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11087 	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11088 	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11089 }
11090 
11091 static void
11092 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11093 {
11094 
11095 	bwn_phy_lp_tblinit(mac);
11096 	if (mac->mac_phy.rev >= 2)
11097 		bwn_phy_lp_bbinit_r2(mac);
11098 	else
11099 		bwn_phy_lp_bbinit_r01(mac);
11100 }
11101 
11102 static void
11103 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11104 {
11105 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11106 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11107 	struct bwn_softc *sc = mac->mac_sc;
11108 	struct ifnet *ifp = sc->sc_ifp;
11109 	struct ieee80211com *ic = ifp->if_l2com;
11110 
11111 	bwn_phy_lp_set_txgain(mac,
11112 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11113 	bwn_phy_lp_set_bbmult(mac, 150);
11114 }
11115 
11116 static void
11117 bwn_phy_lp_calib(struct bwn_mac *mac)
11118 {
11119 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11120 	struct bwn_softc *sc = mac->mac_sc;
11121 	struct ifnet *ifp = sc->sc_ifp;
11122 	struct ieee80211com *ic = ifp->if_l2com;
11123 	const struct bwn_rxcompco *rc = NULL;
11124 	struct bwn_txgain ogain;
11125 	int i, omode, oafeovr, orf, obbmult;
11126 	uint8_t mode, fc = 0;
11127 
11128 	if (plp->plp_chanfullcal != plp->plp_chan) {
11129 		plp->plp_chanfullcal = plp->plp_chan;
11130 		fc = 1;
11131 	}
11132 
11133 	bwn_mac_suspend(mac);
11134 
11135 	/* BlueTooth Coexistance Override */
11136 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11137 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11138 
11139 	if (mac->mac_phy.rev >= 2)
11140 		bwn_phy_lp_digflt_save(mac);
11141 	bwn_phy_lp_get_txpctlmode(mac);
11142 	mode = plp->plp_txpctlmode;
11143 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11144 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11145 		bwn_phy_lp_bugfix(mac);
11146 	if (mac->mac_phy.rev >= 2 && fc == 1) {
11147 		bwn_phy_lp_get_txpctlmode(mac);
11148 		omode = plp->plp_txpctlmode;
11149 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11150 		if (oafeovr)
11151 			ogain = bwn_phy_lp_get_txgain(mac);
11152 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11153 		obbmult = bwn_phy_lp_get_bbmult(mac);
11154 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11155 		if (oafeovr)
11156 			bwn_phy_lp_set_txgain(mac, &ogain);
11157 		bwn_phy_lp_set_bbmult(mac, obbmult);
11158 		bwn_phy_lp_set_txpctlmode(mac, omode);
11159 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11160 	}
11161 	bwn_phy_lp_set_txpctlmode(mac, mode);
11162 	if (mac->mac_phy.rev >= 2)
11163 		bwn_phy_lp_digflt_restore(mac);
11164 
11165 	/* do RX IQ Calculation; assumes that noise is true. */
11166 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11167 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11168 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11169 				rc = &bwn_rxcompco_5354[i];
11170 		}
11171 	} else if (mac->mac_phy.rev >= 2)
11172 		rc = &bwn_rxcompco_r2;
11173 	else {
11174 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11175 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11176 				rc = &bwn_rxcompco_r12[i];
11177 		}
11178 	}
11179 	if (rc == NULL)
11180 		goto fail;
11181 
11182 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11183 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11184 
11185 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11186 
11187 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11188 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11189 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11190 	} else {
11191 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11192 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11193 	}
11194 
11195 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11196 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11197 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11198 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11199 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11200 	bwn_phy_lp_set_deaf(mac, 0);
11201 	/* XXX no checking return value? */
11202 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11203 	bwn_phy_lp_clear_deaf(mac, 0);
11204 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11205 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11206 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11207 
11208 	/* disable RX GAIN override. */
11209 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11210 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11211 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11212 	if (mac->mac_phy.rev >= 2) {
11213 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11214 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11215 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11216 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11217 		}
11218 	} else {
11219 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11220 	}
11221 
11222 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11223 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11224 fail:
11225 	bwn_mac_enable(mac);
11226 }
11227 
11228 static void
11229 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11230 {
11231 
11232 	if (on) {
11233 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11234 		return;
11235 	}
11236 
11237 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11238 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11239 }
11240 
11241 static int
11242 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11243 {
11244 	static const struct bwn_b206x_chan *bc = NULL;
11245 	struct bwn_softc *sc = mac->mac_sc;
11246 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11247 	    tmp[6];
11248 	uint16_t old, scale, tmp16;
11249 	int i, div;
11250 
11251 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
11252 		if (bwn_b2063_chantable[i].bc_chan == chan) {
11253 			bc = &bwn_b2063_chantable[i];
11254 			break;
11255 		}
11256 	}
11257 	if (bc == NULL)
11258 		return (EINVAL);
11259 
11260 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11261 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11262 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11263 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11264 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11265 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11266 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11267 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11268 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11269 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11270 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11271 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11272 
11273 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
11274 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11275 
11276 	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11277 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11278 	freqref = freqxtal * 3;
11279 	div = (freqxtal <= 26000000 ? 1 : 2);
11280 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11281 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11282 		999999) / 1000000) + 1;
11283 
11284 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11285 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11286 	    0xfff8, timeout >> 2);
11287 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11288 	    0xff9f,timeout << 5);
11289 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11290 
11291 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11292 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11293 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11294 
11295 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11296 	    (timeoutref + 1)) - 1;
11297 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11298 	    0xf0, count >> 8);
11299 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11300 
11301 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
11302 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
11303 	while (tmp[1] >= freqref) {
11304 		tmp[0]++;
11305 		tmp[1] -= freqref;
11306 	}
11307 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11308 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11309 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11310 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11311 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11312 
11313 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11314 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11315 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11316 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11317 
11318 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11319 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11320 
11321 	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11322 		scale = 1;
11323 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11324 	} else {
11325 		scale = 0;
11326 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11327 	}
11328 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11329 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11330 
11331 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11332 	    (scale + 1);
11333 	if (tmp[5] > 150)
11334 		tmp[5] = 0;
11335 
11336 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11337 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11338 
11339 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11340 	if (freqxtal > 26000000)
11341 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11342 	else
11343 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11344 
11345 	if (val[0] == 45)
11346 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11347 	else
11348 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11349 
11350 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11351 	DELAY(1);
11352 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11353 
11354 	/* VCO Calibration */
11355 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11356 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11357 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11358 	DELAY(1);
11359 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11360 	DELAY(1);
11361 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11362 	DELAY(1);
11363 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11364 	DELAY(300);
11365 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11366 
11367 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11368 	return (0);
11369 }
11370 
11371 static int
11372 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11373 {
11374 	struct bwn_softc *sc = mac->mac_sc;
11375 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11376 	const struct bwn_b206x_chan *bc = NULL;
11377 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11378 	uint32_t tmp[9];
11379 	int i;
11380 
11381 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
11382 		if (bwn_b2062_chantable[i].bc_chan == chan) {
11383 			bc = &bwn_b2062_chantable[i];
11384 			break;
11385 		}
11386 	}
11387 
11388 	if (bc == NULL)
11389 		return (EINVAL);
11390 
11391 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11392 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11393 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11394 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11395 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11396 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11397 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11398 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11399 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11400 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11401 
11402 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11403 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11404 	bwn_phy_lp_b2062_reset_pllbias(mac);
11405 	tmp[0] = freqxtal / 1000;
11406 	tmp[1] = plp->plp_div * 1000;
11407 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11408 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
11409 		tmp[2] *= 2;
11410 	tmp[3] = 48 * tmp[0];
11411 	tmp[5] = tmp[2] / tmp[3];
11412 	tmp[6] = tmp[2] % tmp[3];
11413 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11414 	tmp[4] = tmp[6] * 0x100;
11415 	tmp[5] = tmp[4] / tmp[3];
11416 	tmp[6] = tmp[4] % tmp[3];
11417 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11418 	tmp[4] = tmp[6] * 0x100;
11419 	tmp[5] = tmp[4] / tmp[3];
11420 	tmp[6] = tmp[4] % tmp[3];
11421 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11422 	tmp[4] = tmp[6] * 0x100;
11423 	tmp[5] = tmp[4] / tmp[3];
11424 	tmp[6] = tmp[4] % tmp[3];
11425 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11426 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
11427 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11428 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11429 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11430 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11431 
11432 	bwn_phy_lp_b2062_vco_calib(mac);
11433 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11434 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11435 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11436 		bwn_phy_lp_b2062_reset_pllbias(mac);
11437 		bwn_phy_lp_b2062_vco_calib(mac);
11438 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11439 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11440 			return (EIO);
11441 		}
11442 	}
11443 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11444 	return (0);
11445 }
11446 
11447 static void
11448 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11449 {
11450 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11451 	uint16_t tmp = (channel == 14);
11452 
11453 	if (mac->mac_phy.rev < 2) {
11454 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11455 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11456 			bwn_phy_lp_set_rccap(mac);
11457 		return;
11458 	}
11459 
11460 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11461 }
11462 
11463 static void
11464 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11465 {
11466 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11467 	struct bwn_softc *sc = mac->mac_sc;
11468 	struct ifnet *ifp = sc->sc_ifp;
11469 	struct ieee80211com *ic = ifp->if_l2com;
11470 	uint16_t iso, tmp[3];
11471 
11472 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11473 
11474 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11475 		iso = plp->plp_txisoband_m;
11476 	else if (freq <= 5320)
11477 		iso = plp->plp_txisoband_l;
11478 	else if (freq <= 5700)
11479 		iso = plp->plp_txisoband_m;
11480 	else
11481 		iso = plp->plp_txisoband_h;
11482 
11483 	tmp[0] = ((iso - 26) / 12) << 12;
11484 	tmp[1] = tmp[0] + 0x1000;
11485 	tmp[2] = tmp[0] + 0x2000;
11486 
11487 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11488 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11489 }
11490 
11491 static void
11492 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11493 {
11494 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11495 	int i;
11496 	static const uint16_t addr[] = {
11497 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11498 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11499 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11500 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11501 		BWN_PHY_OFDM(0xcf),
11502 	};
11503 	static const uint16_t val[] = {
11504 		0xde5e, 0xe832, 0xe331, 0x4d26,
11505 		0x0026, 0x1420, 0x0020, 0xfe08,
11506 		0x0008,
11507 	};
11508 
11509 	for (i = 0; i < N(addr); i++) {
11510 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11511 		BWN_PHY_WRITE(mac, addr[i], val[i]);
11512 	}
11513 }
11514 
11515 static void
11516 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11517 {
11518 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11519 	struct bwn_softc *sc = mac->mac_sc;
11520 	uint16_t ctl;
11521 
11522 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11523 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11524 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11525 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11526 		break;
11527 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11528 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11529 		break;
11530 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11531 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11532 		break;
11533 	default:
11534 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11535 		device_printf(sc->sc_dev, "unknown command mode\n");
11536 		break;
11537 	}
11538 }
11539 
11540 static void
11541 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11542 {
11543 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11544 	uint16_t ctl;
11545 	uint8_t old;
11546 
11547 	bwn_phy_lp_get_txpctlmode(mac);
11548 	old = plp->plp_txpctlmode;
11549 	if (old == mode)
11550 		return;
11551 	plp->plp_txpctlmode = mode;
11552 
11553 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11554 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11555 		    plp->plp_tssiidx);
11556 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11557 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11558 
11559 		/* disable TX GAIN override */
11560 		if (mac->mac_phy.rev < 2)
11561 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11562 		else {
11563 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11564 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11565 		}
11566 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11567 
11568 		plp->plp_txpwridx = -1;
11569 	}
11570 	if (mac->mac_phy.rev >= 2) {
11571 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11572 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11573 		else
11574 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11575 	}
11576 
11577 	/* writes TX Power Control mode */
11578 	switch (plp->plp_txpctlmode) {
11579 	case BWN_PHYLP_TXPCTL_OFF:
11580 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11581 		break;
11582 	case BWN_PHYLP_TXPCTL_ON_HW:
11583 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11584 		break;
11585 	case BWN_PHYLP_TXPCTL_ON_SW:
11586 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11587 		break;
11588 	default:
11589 		ctl = 0;
11590 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11591 	}
11592 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11593 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11594 }
11595 
11596 static void
11597 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11598 {
11599 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11600 	struct bwn_softc *sc = mac->mac_sc;
11601 	const unsigned int size = 256;
11602 	struct bwn_txgain tg;
11603 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11604 	uint16_t tssinpt, tssiidx, value[2];
11605 	uint8_t mode;
11606 	int8_t txpwridx;
11607 
11608 	tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11609 	    M_NOWAIT | M_ZERO);
11610 	if (tabs == NULL) {
11611 		device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11612 		return;
11613 	}
11614 
11615 	bwn_phy_lp_get_txpctlmode(mac);
11616 	mode = plp->plp_txpctlmode;
11617 	txpwridx = plp->plp_txpwridx;
11618 	tssinpt = plp->plp_tssinpt;
11619 	tssiidx = plp->plp_tssiidx;
11620 
11621 	bwn_tab_read_multi(mac,
11622 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11623 	    BWN_TAB_4(7, 0x140), size, tabs);
11624 
11625 	bwn_phy_lp_tblinit(mac);
11626 	bwn_phy_lp_bbinit(mac);
11627 	bwn_phy_lp_txpctl_init(mac);
11628 	bwn_phy_lp_rf_onoff(mac, 1);
11629 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11630 
11631 	bwn_tab_write_multi(mac,
11632 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11633 	    BWN_TAB_4(7, 0x140), size, tabs);
11634 
11635 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11636 	plp->plp_tssinpt = tssinpt;
11637 	plp->plp_tssiidx = tssiidx;
11638 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11639 	if (txpwridx != -1) {
11640 		/* set TX power by index */
11641 		plp->plp_txpwridx = txpwridx;
11642 		bwn_phy_lp_get_txpctlmode(mac);
11643 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11644 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11645 		if (mac->mac_phy.rev >= 2) {
11646 			rxcomp = bwn_tab_read(mac,
11647 			    BWN_TAB_4(7, txpwridx + 320));
11648 			txgain = bwn_tab_read(mac,
11649 			    BWN_TAB_4(7, txpwridx + 192));
11650 			tg.tg_pad = (txgain >> 16) & 0xff;
11651 			tg.tg_gm = txgain & 0xff;
11652 			tg.tg_pga = (txgain >> 8) & 0xff;
11653 			tg.tg_dac = (rxcomp >> 28) & 0xff;
11654 			bwn_phy_lp_set_txgain(mac, &tg);
11655 		} else {
11656 			rxcomp = bwn_tab_read(mac,
11657 			    BWN_TAB_4(10, txpwridx + 320));
11658 			txgain = bwn_tab_read(mac,
11659 			    BWN_TAB_4(10, txpwridx + 192));
11660 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11661 			    0xf800, (txgain >> 4) & 0x7fff);
11662 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11663 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11664 		}
11665 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11666 
11667 		/* set TX IQCC */
11668 		value[0] = (rxcomp >> 10) & 0x3ff;
11669 		value[1] = rxcomp & 0x3ff;
11670 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11671 
11672 		coeff = bwn_tab_read(mac,
11673 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11674 		    BWN_TAB_4(10, txpwridx + 448));
11675 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11676 		if (mac->mac_phy.rev >= 2) {
11677 			rfpwr = bwn_tab_read(mac,
11678 			    BWN_TAB_4(7, txpwridx + 576));
11679 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11680 			    rfpwr & 0xffff);
11681 		}
11682 		bwn_phy_lp_set_txgain_override(mac);
11683 	}
11684 	if (plp->plp_rccap)
11685 		bwn_phy_lp_set_rccap(mac);
11686 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11687 	bwn_phy_lp_set_txpctlmode(mac, mode);
11688 	free(tabs, M_DEVBUF);
11689 }
11690 
11691 static void
11692 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11693 {
11694 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11695 	int i;
11696 	static const uint16_t addr[] = {
11697 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11698 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11699 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11700 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11701 		BWN_PHY_OFDM(0xcf),
11702 	};
11703 
11704 	for (i = 0; i < N(addr); i++)
11705 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11706 }
11707 
11708 static void
11709 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11710 {
11711 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11712 
11713 	if (mac->mac_phy.rev < 2) {
11714 		bwn_phy_lp_tblinit_r01(mac);
11715 		bwn_phy_lp_tblinit_txgain(mac);
11716 		bwn_phy_lp_set_gaintbl(mac, freq);
11717 		return;
11718 	}
11719 
11720 	bwn_phy_lp_tblinit_r2(mac);
11721 	bwn_phy_lp_tblinit_txgain(mac);
11722 }
11723 
11724 struct bwn_wpair {
11725 	uint16_t		reg;
11726 	uint16_t		value;
11727 };
11728 
11729 struct bwn_smpair {
11730 	uint16_t		offset;
11731 	uint16_t		mask;
11732 	uint16_t		set;
11733 };
11734 
11735 static void
11736 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11737 {
11738 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11739 	struct bwn_softc *sc = mac->mac_sc;
11740 	struct ifnet *ifp = sc->sc_ifp;
11741 	struct ieee80211com *ic = ifp->if_l2com;
11742 	static const struct bwn_wpair v1[] = {
11743 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
11744 		{ BWN_PHY_AFE_CTL, 0x8800 },
11745 		{ BWN_PHY_AFE_CTL_OVR, 0 },
11746 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
11747 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
11748 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
11749 		{ BWN_PHY_OFDM(0xf9), 0 },
11750 		{ BWN_PHY_TR_LOOKUP_1, 0 }
11751 	};
11752 	static const struct bwn_smpair v2[] = {
11753 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11754 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11755 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11756 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11757 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11758 	};
11759 	static const struct bwn_smpair v3[] = {
11760 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11761 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11762 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11763 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11764 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11765 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11766 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11767 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11768 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11769 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11770 
11771 	};
11772 	int i;
11773 
11774 	for (i = 0; i < N(v1); i++)
11775 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11776 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11777 	for (i = 0; i < N(v2); i++)
11778 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11779 
11780 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11781 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11782 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11783 	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11784 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11785 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11786 	} else {
11787 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11788 	}
11789 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11790 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11791 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11792 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11793 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11794 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11795 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11796 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11797 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11798 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11799 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11800 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11801 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11802 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11803 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11804 	} else {
11805 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11806 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11807 	}
11808 	for (i = 0; i < N(v3); i++)
11809 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11810 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11811 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11812 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11813 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11814 	}
11815 
11816 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11817 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11818 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11819 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11820 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11821 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11822 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11823 	} else
11824 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11825 
11826 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11827 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11828 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11829 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11830 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11831 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11832 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11833 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11834 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11835 
11836 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11837 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
11838 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11839 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11840 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11841 	}
11842 
11843 	bwn_phy_lp_digflt_save(mac);
11844 }
11845 
11846 static void
11847 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11848 {
11849 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11850 	struct bwn_softc *sc = mac->mac_sc;
11851 	struct ifnet *ifp = sc->sc_ifp;
11852 	struct ieee80211com *ic = ifp->if_l2com;
11853 	static const struct bwn_smpair v1[] = {
11854 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11855 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11856 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11857 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11858 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11859 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11860 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11861 	};
11862 	static const struct bwn_smpair v2[] = {
11863 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11864 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11865 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11866 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11867 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11868 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11869 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11870 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11871 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11872 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11873 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11874 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11875 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11876 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11877 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11878 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11879 	};
11880 	static const struct bwn_smpair v3[] = {
11881 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11882 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11883 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11884 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11885 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11886 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11887 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11888 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11889 	};
11890 	static const struct bwn_smpair v4[] = {
11891 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11892 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11893 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11894 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11895 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11896 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11897 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11898 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11899 	};
11900 	static const struct bwn_smpair v5[] = {
11901 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11902 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11903 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11904 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11905 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11906 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11907 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11908 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11909 	};
11910 	int i;
11911 	uint16_t tmp, tmp2;
11912 
11913 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11914 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11915 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11916 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11917 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11918 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11919 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11920 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11921 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11922 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11923 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11924 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11925 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11926 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11927 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11928 	for (i = 0; i < N(v1); i++)
11929 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11930 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11931 	    0xff00, plp->plp_rxpwroffset);
11932 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11933 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11934 	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11935 		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11936 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11937 		if (mac->mac_phy.rev == 0)
11938 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11939 			    0xffcf, 0x0010);
11940 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11941 	} else {
11942 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11943 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11944 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11945 	}
11946 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11947 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11948 	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11949 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11950 	else
11951 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11952 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11953 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11954 	    0xfff9, (plp->plp_bxarch << 1));
11955 	if (mac->mac_phy.rev == 1 &&
11956 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11957 		for (i = 0; i < N(v2); i++)
11958 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11959 			    v2[i].set);
11960 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11961 	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11962 	    ((mac->mac_phy.rev == 0) &&
11963 	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11964 		for (i = 0; i < N(v3); i++)
11965 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11966 			    v3[i].set);
11967 	} else if (mac->mac_phy.rev == 1 ||
11968 		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11969 		for (i = 0; i < N(v4); i++)
11970 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11971 			    v4[i].set);
11972 	} else {
11973 		for (i = 0; i < N(v5); i++)
11974 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11975 			    v5[i].set);
11976 	}
11977 	if (mac->mac_phy.rev == 1 &&
11978 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11979 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11980 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11981 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11982 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11983 	}
11984 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11985 	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11986 	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11987 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11988 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11989 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11990 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11991 	}
11992 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11993 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11994 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11995 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11996 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11997 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11998 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11999 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12000 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12001 	} else {
12002 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12003 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12004 	}
12005 	if (mac->mac_phy.rev == 1) {
12006 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12007 		tmp2 = (tmp & 0x03e0) >> 5;
12008 		tmp2 |= tmp2 << 5;
12009 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12010 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12011 		tmp2 = (tmp & 0x1f00) >> 8;
12012 		tmp2 |= tmp2 << 5;
12013 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12014 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12015 		tmp2 = tmp & 0x00ff;
12016 		tmp2 |= tmp << 8;
12017 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12018 	}
12019 }
12020 
12021 struct bwn_b2062_freq {
12022 	uint16_t		freq;
12023 	uint8_t			value[6];
12024 };
12025 
12026 static void
12027 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12028 {
12029 #define	CALC_CTL7(freq, div)						\
12030 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12031 #define	CALC_CTL18(freq, div)						\
12032 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12033 #define	CALC_CTL19(freq, div)						\
12034 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12035 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12036 	struct bwn_softc *sc = mac->mac_sc;
12037 	struct ifnet *ifp = sc->sc_ifp;
12038 	struct ieee80211com *ic = ifp->if_l2com;
12039 	static const struct bwn_b2062_freq freqdata_tab[] = {
12040 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
12041 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
12042 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
12043 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
12044 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
12045 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
12046 	};
12047 	static const struct bwn_wpair v1[] = {
12048 		{ BWN_B2062_N_TXCTL3, 0 },
12049 		{ BWN_B2062_N_TXCTL4, 0 },
12050 		{ BWN_B2062_N_TXCTL5, 0 },
12051 		{ BWN_B2062_N_TXCTL6, 0 },
12052 		{ BWN_B2062_N_PDNCTL0, 0x40 },
12053 		{ BWN_B2062_N_PDNCTL0, 0 },
12054 		{ BWN_B2062_N_CALIB_TS, 0x10 },
12055 		{ BWN_B2062_N_CALIB_TS, 0 }
12056 	};
12057 	const struct bwn_b2062_freq *f = NULL;
12058 	uint32_t xtalfreq, ref;
12059 	unsigned int i;
12060 
12061 	bwn_phy_lp_b2062_tblinit(mac);
12062 
12063 	for (i = 0; i < N(v1); i++)
12064 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12065 	if (mac->mac_phy.rev > 0)
12066 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12067 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12068 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12069 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12070 	else
12071 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12072 
12073 	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12074 	    ("%s:%d: fail", __func__, __LINE__));
12075 	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12076 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12077 
12078 	if (xtalfreq <= 30000000) {
12079 		plp->plp_div = 1;
12080 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12081 	} else {
12082 		plp->plp_div = 2;
12083 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12084 	}
12085 
12086 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12087 	    CALC_CTL7(xtalfreq, plp->plp_div));
12088 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12089 	    CALC_CTL18(xtalfreq, plp->plp_div));
12090 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12091 	    CALC_CTL19(xtalfreq, plp->plp_div));
12092 
12093 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12094 	ref &= 0xffff;
12095 	for (i = 0; i < N(freqdata_tab); i++) {
12096 		if (ref < freqdata_tab[i].freq) {
12097 			f = &freqdata_tab[i];
12098 			break;
12099 		}
12100 	}
12101 	if (f == NULL)
12102 		f = &freqdata_tab[N(freqdata_tab) - 1];
12103 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12104 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12105 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12106 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12107 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12108 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12109 #undef CALC_CTL7
12110 #undef CALC_CTL18
12111 #undef CALC_CTL19
12112 }
12113 
12114 static void
12115 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12116 {
12117 
12118 	bwn_phy_lp_b2063_tblinit(mac);
12119 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12120 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12121 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12122 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12123 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12124 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12125 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12126 	if (mac->mac_phy.rev == 2) {
12127 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12128 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12129 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12130 	} else {
12131 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12132 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12133 	}
12134 }
12135 
12136 static void
12137 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12138 {
12139 	struct bwn_softc *sc = mac->mac_sc;
12140 	static const struct bwn_wpair v1[] = {
12141 		{ BWN_B2063_RX_BB_SP8, 0x0 },
12142 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12143 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12144 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
12145 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
12146 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
12147 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
12148 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
12149 	};
12150 	static const struct bwn_wpair v2[] = {
12151 		{ BWN_B2063_TX_BB_SP3, 0x0 },
12152 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12153 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12154 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
12155 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
12156 	};
12157 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12158 	int i;
12159 	uint8_t tmp;
12160 
12161 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12162 
12163 	for (i = 0; i < 2; i++)
12164 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12165 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12166 	for (i = 2; i < N(v1); i++)
12167 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12168 	for (i = 0; i < 10000; i++) {
12169 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12170 			break;
12171 		DELAY(1000);
12172 	}
12173 
12174 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12175 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12176 
12177 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12178 
12179 	for (i = 0; i < N(v2); i++)
12180 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12181 	if (freqxtal == 24000000) {
12182 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12183 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12184 	} else {
12185 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12186 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12187 	}
12188 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12189 	for (i = 0; i < 10000; i++) {
12190 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12191 			break;
12192 		DELAY(1000);
12193 	}
12194 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12195 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12196 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12197 }
12198 
12199 static void
12200 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12201 {
12202 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12203 	struct bwn_softc *sc = mac->mac_sc;
12204 	struct bwn_phy_lp_iq_est ie;
12205 	struct bwn_txgain tx_gains;
12206 	static const uint32_t pwrtbl[21] = {
12207 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12208 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12209 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12210 		0x0004c, 0x0002c, 0x0001a,
12211 	};
12212 	uint32_t npwr, ipwr, sqpwr, tmp;
12213 	int loopback, i, j, sum, error;
12214 	uint16_t save[7];
12215 	uint8_t txo, bbmult, txpctlmode;
12216 
12217 	error = bwn_phy_lp_switch_channel(mac, 7);
12218 	if (error)
12219 		device_printf(sc->sc_dev,
12220 		    "failed to change channel to 7 (%d)\n", error);
12221 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12222 	bbmult = bwn_phy_lp_get_bbmult(mac);
12223 	if (txo)
12224 		tx_gains = bwn_phy_lp_get_txgain(mac);
12225 
12226 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12227 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12228 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12229 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12230 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12231 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12232 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12233 
12234 	bwn_phy_lp_get_txpctlmode(mac);
12235 	txpctlmode = plp->plp_txpctlmode;
12236 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12237 
12238 	/* disable CRS */
12239 	bwn_phy_lp_set_deaf(mac, 1);
12240 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
12241 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12242 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12243 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12244 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12245 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12246 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12247 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12248 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12249 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12250 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12251 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12252 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12253 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12254 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12255 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12256 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12257 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12258 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12259 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12260 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12261 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12262 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12263 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12264 
12265 	loopback = bwn_phy_lp_loopback(mac);
12266 	if (loopback == -1)
12267 		goto done;
12268 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
12269 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12270 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12271 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12272 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12273 
12274 	tmp = 0;
12275 	memset(&ie, 0, sizeof(ie));
12276 	for (i = 128; i <= 159; i++) {
12277 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12278 		sum = 0;
12279 		for (j = 5; j <= 25; j++) {
12280 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12281 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12282 				goto done;
12283 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12284 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12285 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12286 			    12);
12287 			sum += ((ipwr - npwr) * (ipwr - npwr));
12288 			if ((i == 128) || (sum < tmp)) {
12289 				plp->plp_rccap = i;
12290 				tmp = sum;
12291 			}
12292 		}
12293 	}
12294 	bwn_phy_lp_ddfs_turnoff(mac);
12295 done:
12296 	/* restore CRS */
12297 	bwn_phy_lp_clear_deaf(mac, 1);
12298 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12299 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12300 
12301 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12302 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12303 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12304 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12305 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12306 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12307 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12308 
12309 	bwn_phy_lp_set_bbmult(mac, bbmult);
12310 	if (txo)
12311 		bwn_phy_lp_set_txgain(mac, &tx_gains);
12312 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12313 	if (plp->plp_rccap)
12314 		bwn_phy_lp_set_rccap(mac);
12315 }
12316 
12317 static void
12318 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12319 {
12320 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12321 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12322 
12323 	if (mac->mac_phy.rev == 1)
12324 		rc_cap = MIN(rc_cap + 5, 15);
12325 
12326 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12327 	    MAX(plp->plp_rccap - 4, 0x80));
12328 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12329 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12330 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12331 }
12332 
12333 static uint32_t
12334 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12335 {
12336 	uint32_t i, q, r;
12337 
12338 	if (div == 0)
12339 		return (0);
12340 
12341 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12342 		q <<= 1;
12343 		if (r << 1 >= div) {
12344 			q++;
12345 			r = (r << 1) - div;
12346 		}
12347 	}
12348 	if (r << 1 >= div)
12349 		q++;
12350 	return (q);
12351 }
12352 
12353 static void
12354 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12355 {
12356 	struct bwn_softc *sc = mac->mac_sc;
12357 
12358 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12359 	DELAY(20);
12360 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12361 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12362 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12363 	} else {
12364 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12365 	}
12366 	DELAY(5);
12367 }
12368 
12369 static void
12370 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12371 {
12372 
12373 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12374 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12375 	DELAY(200);
12376 }
12377 
12378 static void
12379 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12380 {
12381 #define	FLAG_A	0x01
12382 #define	FLAG_G	0x02
12383 	struct bwn_softc *sc = mac->mac_sc;
12384 	struct ifnet *ifp = sc->sc_ifp;
12385 	struct ieee80211com *ic = ifp->if_l2com;
12386 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12387 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12388 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12389 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12390 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12391 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12392 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12393 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12394 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12395 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12396 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12397 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12398 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12399 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12400 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12401 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12402 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12403 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12404 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12405 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12406 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12407 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12408 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12409 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12410 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12411 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12412 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12413 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12414 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12415 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12416 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12417 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12418 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12419 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12420 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12421 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12422 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12423 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12424 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12425 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12426 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12427 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12428 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12429 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12430 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12431 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12432 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12433 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12434 	};
12435 	const struct bwn_b206x_rfinit_entry *br;
12436 	unsigned int i;
12437 
12438 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12439 		br = &bwn_b2062_init_tab[i];
12440 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12441 			if (br->br_flags & FLAG_G)
12442 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12443 		} else {
12444 			if (br->br_flags & FLAG_A)
12445 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12446 		}
12447 	}
12448 #undef FLAG_A
12449 #undef FLAG_B
12450 }
12451 
12452 static void
12453 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12454 {
12455 #define	FLAG_A	0x01
12456 #define	FLAG_G	0x02
12457 	struct bwn_softc *sc = mac->mac_sc;
12458 	struct ifnet *ifp = sc->sc_ifp;
12459 	struct ieee80211com *ic = ifp->if_l2com;
12460 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12461 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12462 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12463 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12464 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12465 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12466 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12467 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12468 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12469 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12470 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12471 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12472 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12473 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12474 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12475 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12476 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12477 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12478 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12479 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12480 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12481 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12482 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12483 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12484 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12485 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12486 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12487 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12488 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12489 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12490 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12491 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12492 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12493 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12494 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12495 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12496 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12497 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12498 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12499 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12500 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12501 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12502 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12503 	};
12504 	const struct bwn_b206x_rfinit_entry *br;
12505 	unsigned int i;
12506 
12507 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12508 		br = &bwn_b2063_init_tab[i];
12509 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12510 			if (br->br_flags & FLAG_G)
12511 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12512 		} else {
12513 			if (br->br_flags & FLAG_A)
12514 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12515 		}
12516 	}
12517 #undef FLAG_A
12518 #undef FLAG_B
12519 }
12520 
12521 static void
12522 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12523     int count, void *_data)
12524 {
12525 	unsigned int i;
12526 	uint32_t offset, type;
12527 	uint8_t *data = _data;
12528 
12529 	type = BWN_TAB_GETTYPE(typenoffset);
12530 	offset = BWN_TAB_GETOFFSET(typenoffset);
12531 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12532 
12533 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12534 
12535 	for (i = 0; i < count; i++) {
12536 		switch (type) {
12537 		case BWN_TAB_8BIT:
12538 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12539 			data++;
12540 			break;
12541 		case BWN_TAB_16BIT:
12542 			*((uint16_t *)data) = BWN_PHY_READ(mac,
12543 			    BWN_PHY_TABLEDATALO);
12544 			data += 2;
12545 			break;
12546 		case BWN_TAB_32BIT:
12547 			*((uint32_t *)data) = BWN_PHY_READ(mac,
12548 			    BWN_PHY_TABLEDATAHI);
12549 			*((uint32_t *)data) <<= 16;
12550 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
12551 			    BWN_PHY_TABLEDATALO);
12552 			data += 4;
12553 			break;
12554 		default:
12555 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12556 		}
12557 	}
12558 }
12559 
12560 static void
12561 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12562     int count, const void *_data)
12563 {
12564 	uint32_t offset, type, value;
12565 	const uint8_t *data = _data;
12566 	unsigned int i;
12567 
12568 	type = BWN_TAB_GETTYPE(typenoffset);
12569 	offset = BWN_TAB_GETOFFSET(typenoffset);
12570 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12571 
12572 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12573 
12574 	for (i = 0; i < count; i++) {
12575 		switch (type) {
12576 		case BWN_TAB_8BIT:
12577 			value = *data;
12578 			data++;
12579 			KASSERT(!(value & ~0xff),
12580 			    ("%s:%d: fail", __func__, __LINE__));
12581 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12582 			break;
12583 		case BWN_TAB_16BIT:
12584 			value = *((const uint16_t *)data);
12585 			data += 2;
12586 			KASSERT(!(value & ~0xffff),
12587 			    ("%s:%d: fail", __func__, __LINE__));
12588 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12589 			break;
12590 		case BWN_TAB_32BIT:
12591 			value = *((const uint32_t *)data);
12592 			data += 4;
12593 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12594 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12595 			break;
12596 		default:
12597 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12598 		}
12599 	}
12600 }
12601 
12602 static struct bwn_txgain
12603 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12604 {
12605 	struct bwn_txgain tg;
12606 	uint16_t tmp;
12607 
12608 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12609 	if (mac->mac_phy.rev < 2) {
12610 		tmp = BWN_PHY_READ(mac,
12611 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12612 		tg.tg_gm = tmp & 0x0007;
12613 		tg.tg_pga = (tmp & 0x0078) >> 3;
12614 		tg.tg_pad = (tmp & 0x780) >> 7;
12615 		return (tg);
12616 	}
12617 
12618 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12619 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12620 	tg.tg_gm = tmp & 0xff;
12621 	tg.tg_pga = (tmp >> 8) & 0xff;
12622 	return (tg);
12623 }
12624 
12625 static uint8_t
12626 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12627 {
12628 
12629 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12630 }
12631 
12632 static void
12633 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12634 {
12635 	uint16_t pa;
12636 
12637 	if (mac->mac_phy.rev < 2) {
12638 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12639 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12640 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12641 		bwn_phy_lp_set_txgain_override(mac);
12642 		return;
12643 	}
12644 
12645 	pa = bwn_phy_lp_get_pa_gain(mac);
12646 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12647 	    (tg->tg_pga << 8) | tg->tg_gm);
12648 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12649 	    tg->tg_pad | (pa << 6));
12650 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12651 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12652 	    tg->tg_pad | (pa << 8));
12653 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12654 	bwn_phy_lp_set_txgain_override(mac);
12655 }
12656 
12657 static void
12658 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12659 {
12660 
12661 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12662 }
12663 
12664 static void
12665 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12666 {
12667 	uint16_t trsw = (tx << 1) | rx;
12668 
12669 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12670 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12671 }
12672 
12673 static void
12674 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12675 {
12676 	struct bwn_softc *sc = mac->mac_sc;
12677 	struct ifnet *ifp = sc->sc_ifp;
12678 	struct ieee80211com *ic = ifp->if_l2com;
12679 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12680 
12681 	if (mac->mac_phy.rev < 2) {
12682 		trsw = gain & 0x1;
12683 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12684 		ext_lna = (gain & 2) >> 1;
12685 
12686 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12687 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12688 		    0xfbff, ext_lna << 10);
12689 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12690 		    0xf7ff, ext_lna << 11);
12691 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12692 	} else {
12693 		low_gain = gain & 0xffff;
12694 		high_gain = (gain >> 16) & 0xf;
12695 		ext_lna = (gain >> 21) & 0x1;
12696 		trsw = ~(gain >> 20) & 0x1;
12697 
12698 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12699 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12700 		    0xfdff, ext_lna << 9);
12701 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12702 		    0xfbff, ext_lna << 10);
12703 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12704 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12705 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12706 			tmp = (gain >> 2) & 0x3;
12707 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12708 			    0xe7ff, tmp<<11);
12709 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12710 			    tmp << 3);
12711 		}
12712 	}
12713 
12714 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12715 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12716 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12717 	if (mac->mac_phy.rev >= 2) {
12718 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12719 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12720 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12721 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12722 		}
12723 		return;
12724 	}
12725 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12726 }
12727 
12728 static void
12729 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12730 {
12731 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12732 
12733 	if (user)
12734 		plp->plp_crsusr_off = 1;
12735 	else
12736 		plp->plp_crssys_off = 1;
12737 
12738 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12739 }
12740 
12741 static void
12742 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12743 {
12744 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12745 	struct bwn_softc *sc = mac->mac_sc;
12746 	struct ifnet *ifp = sc->sc_ifp;
12747 	struct ieee80211com *ic = ifp->if_l2com;
12748 
12749 	if (user)
12750 		plp->plp_crsusr_off = 0;
12751 	else
12752 		plp->plp_crssys_off = 0;
12753 
12754 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
12755 		return;
12756 
12757 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12758 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12759 	else
12760 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12761 }
12762 
12763 static unsigned int
12764 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12765 {
12766 	/* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12767 	static uint8_t sqrt_table[256] = {
12768 		10, 14, 17, 20, 22, 24, 26, 28,
12769 		30, 31, 33, 34, 36, 37, 38, 40,
12770 		41, 42, 43, 44, 45, 46, 47, 48,
12771 		50, 50, 51, 52, 53, 54, 55, 56,
12772 		57, 58, 59, 60, 60, 61, 62, 63,
12773 		64, 64, 65, 66, 67, 67, 68, 69,
12774 		70, 70, 71, 72, 72, 73, 74, 74,
12775 		75, 76, 76, 77, 78, 78, 79, 80,
12776 		80, 81, 81, 82, 83, 83, 84, 84,
12777 		85, 86, 86, 87, 87, 88, 88, 89,
12778 		90, 90, 91, 91, 92, 92, 93, 93,
12779 		94, 94, 95, 95, 96, 96, 97, 97,
12780 		98, 98, 99, 100, 100, 100, 101, 101,
12781 		102, 102, 103, 103, 104, 104, 105, 105,
12782 		106, 106, 107, 107, 108, 108, 109, 109,
12783 		110, 110, 110, 111, 111, 112, 112, 113,
12784 		113, 114, 114, 114, 115, 115, 116, 116,
12785 		117, 117, 117, 118, 118, 119, 119, 120,
12786 		120, 120, 121, 121, 122, 122, 122, 123,
12787 		123, 124, 124, 124, 125, 125, 126, 126,
12788 		126, 127, 127, 128, 128, 128, 129, 129,
12789 		130, 130, 130, 131, 131, 131, 132, 132,
12790 		133, 133, 133, 134, 134, 134, 135, 135,
12791 		136, 136, 136, 137, 137, 137, 138, 138,
12792 		138, 139, 139, 140, 140, 140, 141, 141,
12793 		141, 142, 142, 142, 143, 143, 143, 144,
12794 		144, 144, 145, 145, 145, 146, 146, 146,
12795 		147, 147, 147, 148, 148, 148, 149, 149,
12796 		150, 150, 150, 150, 151, 151, 151, 152,
12797 		152, 152, 153, 153, 153, 154, 154, 154,
12798 		155, 155, 155, 156, 156, 156, 157, 157,
12799 		157, 158, 158, 158, 159, 159, 159, 160
12800 	};
12801 
12802 	if (x == 0)
12803 		return (0);
12804 	if (x >= 256) {
12805 		unsigned int tmp;
12806 
12807 		for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12808 			/* do nothing */ ;
12809 		return (tmp);
12810 	}
12811 	return (sqrt_table[x - 1] / 10);
12812 }
12813 
12814 static int
12815 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12816 {
12817 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
12818 	int _t;								\
12819 	_t = _x - 20;							\
12820 	if (_t >= 0) {							\
12821 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12822 	} else {							\
12823 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12824 	}								\
12825 } while (0)
12826 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
12827 	int _t;								\
12828 	_t = _x - 11;							\
12829 	if (_t >= 0)							\
12830 		tmp[3] = (_y << (31 - _x)) / (_z >> _t);		\
12831 	else								\
12832 		tmp[3] = (_y << (31 - _x)) / (_z << -_t);		\
12833 } while (0)
12834 	struct bwn_phy_lp_iq_est ie;
12835 	uint16_t v0, v1;
12836 	int tmp[2], ret;
12837 
12838 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12839 	v0 = v1 >> 8;
12840 	v1 |= 0xff;
12841 
12842 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12843 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12844 
12845 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12846 	if (ret == 0)
12847 		goto done;
12848 
12849 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12850 		ret = 0;
12851 		goto done;
12852 	}
12853 
12854 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12855 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12856 
12857 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12858 	v0 = tmp[0] >> 3;
12859 	v1 = tmp[1] >> 4;
12860 done:
12861 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12862 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12863 	return ret;
12864 #undef CALC_COEFF
12865 #undef CALC_COEFF2
12866 }
12867 
12868 static void
12869 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12870 {
12871 	static const uint16_t noisescale[] = {
12872 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12873 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12874 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12875 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12876 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12877 	};
12878 	static const uint16_t crsgainnft[] = {
12879 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12880 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12881 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12882 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12883 		0x013d,
12884 	};
12885 	static const uint16_t filterctl[] = {
12886 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12887 		0xff53, 0x0127,
12888 	};
12889 	static const uint32_t psctl[] = {
12890 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12891 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12892 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12893 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12894 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12895 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12896 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12897 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12898 	};
12899 	static const uint16_t ofdmcckgain_r0[] = {
12900 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12901 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12902 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12903 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12904 		0x755d,
12905 	};
12906 	static const uint16_t ofdmcckgain_r1[] = {
12907 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12908 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12909 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12910 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12911 		0x755d,
12912 	};
12913 	static const uint16_t gaindelta[] = {
12914 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12915 		0x0000,
12916 	};
12917 	static const uint32_t txpwrctl[] = {
12918 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12919 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12920 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12921 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12922 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12923 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12924 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12925 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12926 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12927 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12928 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12929 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12930 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12931 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12950 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12951 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12952 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12953 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12954 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12955 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12956 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12957 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12958 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12959 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12960 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12961 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12962 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12963 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12964 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12965 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12966 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12967 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12968 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12969 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12970 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12971 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12972 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12973 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12974 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12975 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12976 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12977 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12978 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12979 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12980 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12981 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12982 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12983 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12984 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12985 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12986 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12987 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12988 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12989 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12990 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12991 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12992 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12993 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12994 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12995 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12996 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12997 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12998 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12999 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13000 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13001 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13002 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13003 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13004 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13005 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13006 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13007 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13008 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13009 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13010 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13011 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13012 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13013 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13014 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13015 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13016 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13017 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13018 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13019 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13020 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13021 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13022 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13023 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13024 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13025 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13026 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13027 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13028 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13029 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13030 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13031 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13032 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13033 		0x00000702,
13034 	};
13035 
13036 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13037 
13038 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13039 	    bwn_tab_sigsq_tbl);
13040 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13041 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13042 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13043 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13044 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13045 	    bwn_tab_pllfrac_tbl);
13046 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13047 	    bwn_tabl_iqlocal_tbl);
13048 	if (mac->mac_phy.rev == 0) {
13049 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13050 		    ofdmcckgain_r0);
13051 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13052 		    ofdmcckgain_r0);
13053 	} else {
13054 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13055 		    ofdmcckgain_r1);
13056 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13057 		    ofdmcckgain_r1);
13058 	}
13059 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13060 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13061 }
13062 
13063 static void
13064 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13065 {
13066 	struct bwn_softc *sc = mac->mac_sc;
13067 	int i;
13068 	static const uint16_t noisescale[] = {
13069 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13070 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13071 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13072 		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13073 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13074 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13075 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13076 	};
13077 	static const uint32_t filterctl[] = {
13078 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13079 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13080 	};
13081 	static const uint32_t psctl[] = {
13082 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13083 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13084 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13085 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13086 	};
13087 	static const uint32_t gainidx[] = {
13088 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13089 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13090 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13091 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13092 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13093 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13094 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13095 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13096 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13097 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13098 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13099 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13100 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13101 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13102 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13103 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13104 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13105 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13106 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13107 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13108 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13109 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13110 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13111 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13112 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13113 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13114 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13115 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13116 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13117 		0x0000001a, 0x64ca55ad, 0x0000001a
13118 	};
13119 	static const uint16_t auxgainidx[] = {
13120 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13121 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13122 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13123 		0x0004, 0x0016
13124 	};
13125 	static const uint16_t swctl[] = {
13126 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13127 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13128 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13129 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13130 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13131 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13132 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13133 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13134 	};
13135 	static const uint8_t hf[] = {
13136 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13137 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13138 	};
13139 	static const uint32_t gainval[] = {
13140 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13141 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13142 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13143 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13144 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13145 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13146 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13147 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13148 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13149 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13150 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13151 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13152 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13153 		0x000000f1, 0x00000000, 0x00000000
13154 	};
13155 	static const uint16_t gain[] = {
13156 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13157 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13158 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13159 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13160 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13161 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13162 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13163 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13164 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13165 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13166 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13167 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13168 	};
13169 	static const uint32_t papdeps[] = {
13170 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13171 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13172 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13173 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13174 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13175 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13176 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13177 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13178 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13179 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13180 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13181 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13182 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13183 	};
13184 	static const uint32_t papdmult[] = {
13185 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13186 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13187 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13188 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13189 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13190 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13191 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13192 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13193 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13194 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13195 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13196 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13197 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13198 	};
13199 	static const uint32_t gainidx_a0[] = {
13200 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13201 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13202 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13203 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13204 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13205 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13206 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13207 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13208 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13209 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13210 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13211 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13212 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13213 	};
13214 	static const uint16_t auxgainidx_a0[] = {
13215 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13216 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13217 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13218 		0x0002, 0x0014
13219 	};
13220 	static const uint32_t gainval_a0[] = {
13221 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13222 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13223 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13224 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13225 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13226 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13227 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13228 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13229 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13230 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13231 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13232 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13233 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13234 		0x000000f7, 0x00000000, 0x00000000
13235 	};
13236 	static const uint16_t gain_a0[] = {
13237 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13238 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13239 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13240 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13241 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13242 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13243 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13244 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13245 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13246 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13247 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13248 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13249 	};
13250 
13251 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13252 
13253 	for (i = 0; i < 704; i++)
13254 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13255 
13256 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13257 	    bwn_tab_sigsq_tbl);
13258 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13259 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13260 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13261 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13262 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13263 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13264 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13265 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13266 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13267 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13268 	    bwn_tab_pllfrac_tbl);
13269 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13270 	    bwn_tabl_iqlocal_tbl);
13271 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13272 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13273 
13274 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13275 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
13276 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13277 		    gainidx_a0);
13278 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13279 		    auxgainidx_a0);
13280 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13281 		    gainval_a0);
13282 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13283 	}
13284 }
13285 
13286 static void
13287 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13288 {
13289 	struct bwn_softc *sc = mac->mac_sc;
13290 	struct ifnet *ifp = sc->sc_ifp;
13291 	struct ieee80211com *ic = ifp->if_l2com;
13292 	static struct bwn_txgain_entry txgain_r2[] = {
13293 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13294 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13295 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13296 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13297 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13298 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13299 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13300 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13301 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13302 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13303 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13304 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13305 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13306 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13307 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13308 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13309 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13310 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13311 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13312 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13313 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13314 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13315 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13316 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13317 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13318 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13319 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13320 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13321 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13322 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13323 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13324 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13325 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13326 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13327 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13328 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13329 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13330 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13331 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13332 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13333 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13334 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13335 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13336 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13337 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13338 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13339 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13340 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13341 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13342 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13343 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13344 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13345 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13346 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13347 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13348 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13349 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13350 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13351 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13352 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13353 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13354 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13355 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13356 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13357 	};
13358 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13359 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13360 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13361 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13362 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13363 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13364 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13365 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13366 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13367 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13368 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13369 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13370 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13371 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13372 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13373 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13374 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13375 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13376 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13377 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13378 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13379 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13380 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13381 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13382 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13383 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13384 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13385 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13386 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13387 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13388 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13389 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13390 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13391 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13392 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13393 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13394 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13395 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13396 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13397 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13398 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13399 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13400 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13401 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13402 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13403 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13404 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13405 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13406 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13407 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13408 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13409 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13410 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13411 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13412 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13413 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13414 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13415 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13416 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13417 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13418 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13419 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13420 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13421 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13422 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13423 	};
13424 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13425 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13426 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13427 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13428 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13429 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13430 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13431 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13432 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13433 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13434 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13435 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13436 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13437 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13438 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13439 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13440 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13441 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13442 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13443 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13444 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13445 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13446 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13447 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13448 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13449 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13450 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13451 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13452 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13453 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13454 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13455 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13456 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13457 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13458 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13459 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13460 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13461 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13462 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13463 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13464 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13465 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13466 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13467 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13468 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13469 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13470 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13471 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13472 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13473 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13474 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13475 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13476 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13477 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13478 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13479 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13480 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13481 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13482 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13483 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13484 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13485 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13486 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13487 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13488 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13489 	};
13490 	static struct bwn_txgain_entry txgain_r0[] = {
13491 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13492 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13493 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13494 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13495 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13496 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13497 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13498 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13499 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13500 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13501 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13502 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13503 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13504 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13505 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13506 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13507 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13508 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13509 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13510 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13511 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13512 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13513 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13514 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13515 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13516 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13517 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13518 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13519 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13520 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13521 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13522 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13523 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13524 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13525 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13526 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13527 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13528 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13529 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13530 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13531 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13532 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13533 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13534 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13535 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13536 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13537 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13538 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13539 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13540 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13541 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13542 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13543 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13544 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13545 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13546 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13547 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13548 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13549 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13550 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13551 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13552 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13553 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13554 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13555 	};
13556 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13557 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13558 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13559 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13560 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13561 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13562 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13563 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13564 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13565 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13566 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13567 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13568 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13569 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13570 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13571 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13572 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13573 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13574 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13575 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13576 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13577 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13578 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13579 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13580 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13581 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13582 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13583 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13584 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13585 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13586 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13587 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13588 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13589 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13590 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13591 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13592 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13593 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13594 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13595 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13596 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13597 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13598 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13599 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13600 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13601 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13602 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13603 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13604 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13605 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13606 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13607 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13608 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13609 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13610 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13611 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13612 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13613 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13614 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13615 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13616 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13617 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13618 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13619 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13620 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13621 	};
13622 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13623 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13624 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13625 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13626 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13627 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13628 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13629 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13630 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13631 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13632 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13633 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13634 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13635 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13636 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13637 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13638 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13639 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13640 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13641 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13642 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13643 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13644 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13645 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13646 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13647 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13648 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13649 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13650 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13651 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13652 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13653 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13654 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13655 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13656 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13657 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13658 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13659 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13660 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13661 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13662 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13663 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13664 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13665 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13666 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13667 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13668 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13669 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13670 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13671 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13672 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13673 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13674 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13675 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13676 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13677 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13678 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13679 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13680 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13681 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13682 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13683 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13684 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13685 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13686 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13687 	};
13688 	static struct bwn_txgain_entry txgain_r1[] = {
13689 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13690 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13691 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13692 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13693 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13694 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13695 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13696 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13697 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13698 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13699 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13700 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13701 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13702 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13703 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13704 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13705 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13706 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13707 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13708 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13709 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13710 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13711 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13712 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13713 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13714 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13715 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13716 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13717 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13718 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13719 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13720 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13721 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13722 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13723 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13724 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13725 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13726 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13727 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13728 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13729 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13730 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13731 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13732 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13733 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13734 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13735 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13736 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13737 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13738 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13739 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13740 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13741 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13742 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13743 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13744 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13745 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13746 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13747 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13748 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13749 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13750 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13751 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13752 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13753 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13754 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13755 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13756 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13757 		{ 7, 11, 6, 0, 71 }
13758 	};
13759 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13760 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13761 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13762 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13763 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13764 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13765 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13766 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13767 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13768 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13769 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13770 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13771 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13772 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13773 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13774 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13775 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13776 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13777 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13778 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13779 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13780 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13781 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13782 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13783 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13784 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13785 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13786 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13787 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13788 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13789 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13790 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13791 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13792 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13793 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13794 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13795 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13796 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13797 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13798 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13799 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13800 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13801 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13802 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13803 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13804 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13805 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13806 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13807 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13808 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13809 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13810 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13811 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13812 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13813 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13814 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13815 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13816 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13817 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13818 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13819 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13820 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13821 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13822 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13823 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13824 	};
13825 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13826 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13827 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13828 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13829 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13830 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13831 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13832 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13833 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13834 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13835 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13836 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13837 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13838 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13839 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13840 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13841 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13842 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13843 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13844 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13845 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13846 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13847 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13848 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13849 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13850 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13851 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13852 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13853 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13854 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13855 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13856 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13857 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13858 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13859 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13860 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13861 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13862 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13863 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13864 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13865 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13866 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13867 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13868 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13869 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13870 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13871 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13872 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13873 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13874 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13875 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13876 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13877 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13878 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13879 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13880 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13881 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13882 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13883 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13884 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13885 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13886 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13887 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13888 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13889 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13890 	};
13891 
13892 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13893 		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13894 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13895 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13896 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13897 			    txgain_2ghz_r2);
13898 		else
13899 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13900 			    txgain_5ghz_r2);
13901 		return;
13902 	}
13903 
13904 	if (mac->mac_phy.rev == 0) {
13905 		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13906 		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13907 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13908 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13909 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13910 			    txgain_2ghz_r0);
13911 		else
13912 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13913 			    txgain_5ghz_r0);
13914 		return;
13915 	}
13916 
13917 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13918 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13919 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13920 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13921 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13922 	else
13923 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13924 }
13925 
13926 static void
13927 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13928 {
13929 	uint32_t offset, type;
13930 
13931 	type = BWN_TAB_GETTYPE(typeoffset);
13932 	offset = BWN_TAB_GETOFFSET(typeoffset);
13933 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13934 
13935 	switch (type) {
13936 	case BWN_TAB_8BIT:
13937 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13938 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13939 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13940 		break;
13941 	case BWN_TAB_16BIT:
13942 		KASSERT(!(value & ~0xffff),
13943 		    ("%s:%d: fail", __func__, __LINE__));
13944 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13945 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13946 		break;
13947 	case BWN_TAB_32BIT:
13948 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13949 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13950 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13951 		break;
13952 	default:
13953 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13954 	}
13955 }
13956 
13957 static int
13958 bwn_phy_lp_loopback(struct bwn_mac *mac)
13959 {
13960 	struct bwn_phy_lp_iq_est ie;
13961 	int i, index = -1;
13962 	uint32_t tmp;
13963 
13964 	memset(&ie, 0, sizeof(ie));
13965 
13966 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
13967 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13968 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13969 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13970 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13971 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13972 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13973 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13974 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13975 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13976 	for (i = 0; i < 32; i++) {
13977 		bwn_phy_lp_set_rxgain_idx(mac, i);
13978 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13979 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13980 			continue;
13981 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13982 		if ((tmp > 4000) && (tmp < 10000)) {
13983 			index = i;
13984 			break;
13985 		}
13986 	}
13987 	bwn_phy_lp_ddfs_turnoff(mac);
13988 	return (index);
13989 }
13990 
13991 static void
13992 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13993 {
13994 
13995 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13996 }
13997 
13998 static void
13999 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14000     int incr1, int incr2, int scale_idx)
14001 {
14002 
14003 	bwn_phy_lp_ddfs_turnoff(mac);
14004 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14005 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14006 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14007 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14008 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14009 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14010 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14011 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14012 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14013 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14014 }
14015 
14016 static uint8_t
14017 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14018     struct bwn_phy_lp_iq_est *ie)
14019 {
14020 	int i;
14021 
14022 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14023 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14024 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14025 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14026 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14027 
14028 	for (i = 0; i < 500; i++) {
14029 		if (!(BWN_PHY_READ(mac,
14030 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14031 			break;
14032 		DELAY(1000);
14033 	}
14034 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14035 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14036 		return 0;
14037 	}
14038 
14039 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14040 	ie->ie_iqprod <<= 16;
14041 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14042 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14043 	ie->ie_ipwr <<= 16;
14044 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14045 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14046 	ie->ie_qpwr <<= 16;
14047 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14048 
14049 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14050 	return 1;
14051 }
14052 
14053 static uint32_t
14054 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14055 {
14056 	uint32_t offset, type, value;
14057 
14058 	type = BWN_TAB_GETTYPE(typeoffset);
14059 	offset = BWN_TAB_GETOFFSET(typeoffset);
14060 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14061 
14062 	switch (type) {
14063 	case BWN_TAB_8BIT:
14064 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14065 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14066 		break;
14067 	case BWN_TAB_16BIT:
14068 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14069 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14070 		break;
14071 	case BWN_TAB_32BIT:
14072 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14073 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14074 		value <<= 16;
14075 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14076 		break;
14077 	default:
14078 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14079 		value = 0;
14080 	}
14081 
14082 	return (value);
14083 }
14084 
14085 static void
14086 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14087 {
14088 
14089 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14090 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14091 }
14092 
14093 static void
14094 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14095 {
14096 	uint16_t ctl;
14097 
14098 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14099 	ctl |= dac << 7;
14100 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14101 }
14102 
14103 static void
14104 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14105 {
14106 
14107 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14108 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14109 }
14110 
14111 static void
14112 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14113 {
14114 
14115 	if (mac->mac_phy.rev < 2)
14116 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14117 	else {
14118 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14119 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14120 	}
14121 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14122 }
14123 
14124 static uint16_t
14125 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14126 {
14127 
14128 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14129 }
14130 
14131 static uint8_t
14132 bwn_nbits(int32_t val)
14133 {
14134 	uint32_t tmp;
14135 	uint8_t nbits = 0;
14136 
14137 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
14138 		nbits++;
14139 	return (nbits);
14140 }
14141 
14142 static void
14143 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14144     struct bwn_txgain_entry *table)
14145 {
14146 	int i;
14147 
14148 	for (i = offset; i < count; i++)
14149 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14150 }
14151 
14152 static void
14153 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14154     struct bwn_txgain_entry data)
14155 {
14156 
14157 	if (mac->mac_phy.rev >= 2)
14158 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14159 	else
14160 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14161 }
14162 
14163 static void
14164 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14165     struct bwn_txgain_entry te)
14166 {
14167 	struct bwn_softc *sc = mac->mac_sc;
14168 	struct ifnet *ifp = sc->sc_ifp;
14169 	struct ieee80211com *ic = ifp->if_l2com;
14170 	uint32_t tmp;
14171 
14172 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14173 
14174 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14175 	if (mac->mac_phy.rev >= 3) {
14176 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14177 		    (0x10 << 24) : (0x70 << 24));
14178 	} else {
14179 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14180 		    (0x14 << 24) : (0x7f << 24));
14181 	}
14182 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14183 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14184 	    te.te_bbmult << 20 | te.te_dac << 28);
14185 }
14186 
14187 static void
14188 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14189     struct bwn_txgain_entry te)
14190 {
14191 
14192 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14193 
14194 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14195 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14196 	    te.te_dac);
14197 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14198 }
14199 
14200 static void
14201 bwn_sysctl_node(struct bwn_softc *sc)
14202 {
14203 	device_t dev = sc->sc_dev;
14204 	struct bwn_mac *mac;
14205 	struct bwn_stats *stats;
14206 
14207 	/* XXX assume that count of MAC is only 1. */
14208 
14209 	if ((mac = sc->sc_curmac) == NULL)
14210 		return;
14211 	stats = &mac->mac_stats;
14212 
14213 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14214 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14215 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14216 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14217 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14218 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14219 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14220 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14221 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14222 
14223 #ifdef BWN_DEBUG
14224 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14225 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14226 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14227 #endif
14228 }
14229 
14230 static device_method_t bwn_methods[] = {
14231 	/* Device interface */
14232 	DEVMETHOD(device_probe,		bwn_probe),
14233 	DEVMETHOD(device_attach,	bwn_attach),
14234 	DEVMETHOD(device_detach,	bwn_detach),
14235 	DEVMETHOD(device_suspend,	bwn_suspend),
14236 	DEVMETHOD(device_resume,	bwn_resume),
14237 	KOBJMETHOD_END
14238 };
14239 static driver_t bwn_driver = {
14240 	"bwn",
14241 	bwn_methods,
14242 	sizeof(struct bwn_softc)
14243 };
14244 static devclass_t bwn_devclass;
14245 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14246 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14247 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
14248 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
14249 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
14250