xref: /freebsd/sys/dev/bwn/if_bwn.c (revision 32580301441a6c4f89a20c20f53e45e5557a8b64)
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_amrr.h>
71 #include <net80211/ieee80211_phy.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(struct siba_softc *);
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_newassoc(struct ieee80211_node *, int);
184 static void	bwn_updateslot(struct ifnet *);
185 static void	bwn_update_promisc(struct ifnet *);
186 static void	bwn_wme_init(struct bwn_mac *);
187 static int	bwn_wme_update(struct ieee80211com *);
188 static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
189 		    const uint8_t [IEEE80211_ADDR_LEN]);
190 static void	bwn_wme_clear(struct bwn_softc *);
191 static void	bwn_wme_load(struct bwn_mac *);
192 static void	bwn_wme_loadparams(struct bwn_mac *,
193 		    const struct wmeParams *, uint16_t);
194 static void	bwn_node_cleanup(struct ieee80211_node *);
195 static void	bwn_scan_start(struct ieee80211com *);
196 static void	bwn_scan_end(struct ieee80211com *);
197 static void	bwn_set_channel(struct ieee80211com *);
198 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
199 		    const char [IFNAMSIZ], int, int,
200 		    int, const uint8_t [IEEE80211_ADDR_LEN],
201 		    const uint8_t [IEEE80211_ADDR_LEN]);
202 static void	bwn_vap_delete(struct ieee80211vap *);
203 static void	bwn_stop(struct bwn_softc *, int);
204 static void	bwn_stop_locked(struct bwn_softc *, int);
205 static int	bwn_core_init(struct bwn_mac *);
206 static void	bwn_core_start(struct bwn_mac *);
207 static void	bwn_core_exit(struct bwn_mac *);
208 static void	bwn_fix_imcfglobug(struct bwn_mac *);
209 static void	bwn_bt_disable(struct bwn_mac *);
210 static int	bwn_chip_init(struct bwn_mac *);
211 static uint64_t	bwn_hf_read(struct bwn_mac *);
212 static void	bwn_hf_write(struct bwn_mac *, uint64_t);
213 static void	bwn_set_txretry(struct bwn_mac *, int, int);
214 static void	bwn_rate_init(struct bwn_mac *);
215 static void	bwn_set_phytxctl(struct bwn_mac *);
216 static void	bwn_spu_setdelay(struct bwn_mac *, int);
217 static void	bwn_bt_enable(struct bwn_mac *);
218 static void	bwn_set_macaddr(struct bwn_mac *);
219 static void	bwn_crypt_init(struct bwn_mac *);
220 static void	bwn_chip_exit(struct bwn_mac *);
221 static int	bwn_fw_fillinfo(struct bwn_mac *);
222 static int	bwn_fw_loaducode(struct bwn_mac *);
223 static int	bwn_gpio_init(struct bwn_mac *);
224 static int	bwn_fw_loadinitvals(struct bwn_mac *);
225 static int	bwn_phy_init(struct bwn_mac *);
226 static void	bwn_set_txantenna(struct bwn_mac *, int);
227 static void	bwn_set_opmode(struct bwn_mac *);
228 static void	bwn_gpio_cleanup(struct bwn_mac *);
229 static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
230 static uint8_t	bwn_plcp_getcck(const uint8_t);
231 static uint8_t	bwn_plcp_getofdm(const uint8_t);
232 static void	bwn_pio_init(struct bwn_mac *);
233 static uint16_t	bwn_pio_idx2base(struct bwn_mac *, int);
234 static void	bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
235 		    int);
236 static void	bwn_pio_setupqueue_rx(struct bwn_mac *,
237 		    struct bwn_pio_rxqueue *, int);
238 static void	bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
239 static uint16_t	bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
240 		    uint16_t);
241 static void	bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
242 static int	bwn_pio_rx(struct bwn_pio_rxqueue *);
243 static uint8_t	bwn_pio_rxeof(struct bwn_pio_rxqueue *);
244 static void	bwn_pio_handle_txeof(struct bwn_mac *,
245 		    const struct bwn_txstatus *);
246 static uint16_t	bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
247 static uint32_t	bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
248 static void	bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
249 		    uint16_t);
250 static void	bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
251 		    uint32_t);
252 static int	bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
253 		    struct mbuf *);
254 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
255 static uint32_t	bwn_pio_write_multi_4(struct bwn_mac *,
256 		    struct bwn_pio_txqueue *, uint32_t, const void *, int);
257 static void	bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
258 		    uint16_t, uint32_t);
259 static uint16_t	bwn_pio_write_multi_2(struct bwn_mac *,
260 		    struct bwn_pio_txqueue *, uint16_t, const void *, int);
261 static uint16_t	bwn_pio_write_mbuf_2(struct bwn_mac *,
262 		    struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
263 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
264 		    uint16_t, struct bwn_pio_txpkt **);
265 static void	bwn_dma_init(struct bwn_mac *);
266 static void	bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
267 static int	bwn_dma_mask2type(uint64_t);
268 static uint64_t	bwn_dma_mask(struct bwn_mac *);
269 static uint16_t	bwn_dma_base(int, int);
270 static void	bwn_dma_ringfree(struct bwn_dma_ring **);
271 static void	bwn_dma_32_getdesc(struct bwn_dma_ring *,
272 		    int, struct bwn_dmadesc_generic **,
273 		    struct bwn_dmadesc_meta **);
274 static void	bwn_dma_32_setdesc(struct bwn_dma_ring *,
275 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
276 		    int, int);
277 static void	bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
278 static void	bwn_dma_32_suspend(struct bwn_dma_ring *);
279 static void	bwn_dma_32_resume(struct bwn_dma_ring *);
280 static int	bwn_dma_32_get_curslot(struct bwn_dma_ring *);
281 static void	bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
282 static void	bwn_dma_64_getdesc(struct bwn_dma_ring *,
283 		    int, struct bwn_dmadesc_generic **,
284 		    struct bwn_dmadesc_meta **);
285 static void	bwn_dma_64_setdesc(struct bwn_dma_ring *,
286 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
287 		    int, int);
288 static void	bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
289 static void	bwn_dma_64_suspend(struct bwn_dma_ring *);
290 static void	bwn_dma_64_resume(struct bwn_dma_ring *);
291 static int	bwn_dma_64_get_curslot(struct bwn_dma_ring *);
292 static void	bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
293 static int	bwn_dma_allocringmemory(struct bwn_dma_ring *);
294 static void	bwn_dma_setup(struct bwn_dma_ring *);
295 static void	bwn_dma_free_ringmemory(struct bwn_dma_ring *);
296 static void	bwn_dma_cleanup(struct bwn_dma_ring *);
297 static void	bwn_dma_free_descbufs(struct bwn_dma_ring *);
298 static int	bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
299 static void	bwn_dma_rx(struct bwn_dma_ring *);
300 static int	bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
301 static void	bwn_dma_free_descbuf(struct bwn_dma_ring *,
302 		    struct bwn_dmadesc_meta *);
303 static void	bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
304 static int	bwn_dma_gettype(struct bwn_mac *);
305 static void	bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
306 static int	bwn_dma_freeslot(struct bwn_dma_ring *);
307 static int	bwn_dma_nextslot(struct bwn_dma_ring *, int);
308 static void	bwn_dma_rxeof(struct bwn_dma_ring *, int *);
309 static int	bwn_dma_newbuf(struct bwn_dma_ring *,
310 		    struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
311 		    int);
312 static void	bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
313 		    bus_size_t, int);
314 static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
315 static void	bwn_dma_handle_txeof(struct bwn_mac *,
316 		    const struct bwn_txstatus *);
317 static int	bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
318 		    struct mbuf *);
319 static int	bwn_dma_getslot(struct bwn_dma_ring *);
320 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
321 		    uint8_t);
322 static int	bwn_dma_attach(struct bwn_mac *);
323 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
324 		    int, int, int);
325 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
326 		    const struct bwn_txstatus *, uint16_t, int *);
327 static void	bwn_dma_free(struct bwn_mac *);
328 static void	bwn_phy_g_init_sub(struct bwn_mac *);
329 static uint8_t	bwn_has_hwpctl(struct bwn_mac *);
330 static void	bwn_phy_init_b5(struct bwn_mac *);
331 static void	bwn_phy_init_b6(struct bwn_mac *);
332 static void	bwn_phy_init_a(struct bwn_mac *);
333 static void	bwn_loopback_calcgain(struct bwn_mac *);
334 static uint16_t	bwn_rf_init_bcm2050(struct bwn_mac *);
335 static void	bwn_lo_g_init(struct bwn_mac *);
336 static void	bwn_lo_g_adjust(struct bwn_mac *);
337 static void	bwn_lo_get_powervector(struct bwn_mac *);
338 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
339 		    const struct bwn_bbatt *, const struct bwn_rfatt *);
340 static void	bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
341 static void	bwn_phy_hwpctl_init(struct bwn_mac *);
342 static void	bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
343 static void	bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
344 		    const struct bwn_bbatt *, const struct bwn_rfatt *,
345 		    uint8_t);
346 static void	bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
347 static uint16_t	bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
348 static void	bwn_spu_workaround(struct bwn_mac *, uint8_t);
349 static void	bwn_wa_init(struct bwn_mac *);
350 static void	bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
351 		    uint16_t);
352 static void	bwn_dummy_transmission(struct bwn_mac *, int, int);
353 static void	bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
354 		    uint32_t);
355 static void	bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
356 		    uint16_t);
357 static void	bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
358 static void	bwn_mac_suspend(struct bwn_mac *);
359 static void	bwn_mac_enable(struct bwn_mac *);
360 static void	bwn_psctl(struct bwn_mac *, uint32_t);
361 static int16_t	bwn_nrssi_read(struct bwn_mac *, uint16_t);
362 static void	bwn_nrssi_offset(struct bwn_mac *);
363 static void	bwn_nrssi_threshold(struct bwn_mac *);
364 static void	bwn_nrssi_slope_11g(struct bwn_mac *);
365 static void	bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
366 		    int16_t);
367 static void	bwn_set_original_gains(struct bwn_mac *);
368 static void	bwn_hwpctl_early_init(struct bwn_mac *);
369 static void	bwn_hwpctl_init_gphy(struct bwn_mac *);
370 static uint16_t	bwn_phy_g_chan2freq(uint8_t);
371 static int	bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
372 static int	bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
373 		    const char *, struct bwn_fwfile *);
374 static void	bwn_release_firmware(struct bwn_mac *);
375 static void	bwn_do_release_fw(struct bwn_fwfile *);
376 static uint16_t	bwn_fwcaps_read(struct bwn_mac *);
377 static int	bwn_fwinitvals_write(struct bwn_mac *,
378 		    const struct bwn_fwinitvals *, size_t, size_t);
379 static int	bwn_switch_channel(struct bwn_mac *, int);
380 static uint16_t	bwn_ant2phy(int);
381 static void	bwn_mac_write_bssid(struct bwn_mac *);
382 static void	bwn_mac_setfilter(struct bwn_mac *, uint16_t,
383 		    const uint8_t *);
384 static void	bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
385 		    const uint8_t *, size_t, const uint8_t *);
386 static void	bwn_key_macwrite(struct bwn_mac *, uint8_t,
387 		    const uint8_t *);
388 static void	bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
389 		    const uint8_t *);
390 static void	bwn_phy_exit(struct bwn_mac *);
391 static void	bwn_core_stop(struct bwn_mac *);
392 static int	bwn_switch_band(struct bwn_softc *,
393 		    struct ieee80211_channel *);
394 static void	bwn_phy_reset(struct bwn_mac *);
395 static int	bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
396 static void	bwn_set_pretbtt(struct bwn_mac *);
397 static int	bwn_intr(void *);
398 static void	bwn_intrtask(void *, int);
399 static void	bwn_restart(struct bwn_mac *, const char *);
400 static void	bwn_intr_ucode_debug(struct bwn_mac *);
401 static void	bwn_intr_tbtt_indication(struct bwn_mac *);
402 static void	bwn_intr_atim_end(struct bwn_mac *);
403 static void	bwn_intr_beacon(struct bwn_mac *);
404 static void	bwn_intr_pmq(struct bwn_mac *);
405 static void	bwn_intr_noise(struct bwn_mac *);
406 static void	bwn_intr_txeof(struct bwn_mac *);
407 static void	bwn_hwreset(void *, int);
408 static void	bwn_handle_fwpanic(struct bwn_mac *);
409 static void	bwn_load_beacon0(struct bwn_mac *);
410 static void	bwn_load_beacon1(struct bwn_mac *);
411 static uint32_t	bwn_jssi_read(struct bwn_mac *);
412 static void	bwn_noise_gensample(struct bwn_mac *);
413 static void	bwn_handle_txeof(struct bwn_mac *,
414 		    const struct bwn_txstatus *);
415 static void	bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
416 static void	bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
417 static void	bwn_start_locked(struct ifnet *);
418 static int	bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
419 		    struct mbuf *);
420 static int	bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
421 static int	bwn_set_txhdr(struct bwn_mac *,
422 		    struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
423 		    uint16_t);
424 static void	bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
425 		    const uint8_t);
426 static uint8_t	bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
427 static uint8_t	bwn_get_fbrate(uint8_t);
428 static int	bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
429 static void	bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
430 static void	bwn_phy_lock(struct bwn_mac *);
431 static void	bwn_phy_unlock(struct bwn_mac *);
432 static void	bwn_rf_lock(struct bwn_mac *);
433 static void	bwn_rf_unlock(struct bwn_mac *);
434 static void	bwn_txpwr(void *, int);
435 static void	bwn_tasks(void *);
436 static void	bwn_task_15s(struct bwn_mac *);
437 static void	bwn_task_30s(struct bwn_mac *);
438 static void	bwn_task_60s(struct bwn_mac *);
439 static int	bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
440 		    uint8_t);
441 static int	bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
442 static void	bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
443 		    const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
444 		    int, int);
445 static void	bwn_tsf_read(struct bwn_mac *, uint64_t *);
446 static void	bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
447 static void	bwn_set_slot_time(struct bwn_mac *, uint16_t);
448 static void	bwn_watchdog(void *);
449 static void	bwn_dma_stop(struct bwn_mac *);
450 static void	bwn_pio_stop(struct bwn_mac *);
451 static void	bwn_dma_ringstop(struct bwn_dma_ring **);
452 static void	bwn_led_attach(struct bwn_mac *);
453 static void	bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
454 static void	bwn_led_event(struct bwn_mac *, int);
455 static void	bwn_led_blink_start(struct bwn_mac *, int, int);
456 static void	bwn_led_blink_next(void *);
457 static void	bwn_led_blink_end(void *);
458 static void	bwn_rfswitch(void *);
459 static void	bwn_rf_turnon(struct bwn_mac *);
460 static void	bwn_rf_turnoff(struct bwn_mac *);
461 static void	bwn_phy_lp_init_pre(struct bwn_mac *);
462 static int	bwn_phy_lp_init(struct bwn_mac *);
463 static uint16_t	bwn_phy_lp_read(struct bwn_mac *, uint16_t);
464 static void	bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
465 static void	bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
466 		    uint16_t);
467 static uint16_t	bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
468 static void	bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
469 static void	bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
470 static int	bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
471 static uint32_t	bwn_phy_lp_get_default_chan(struct bwn_mac *);
472 static void	bwn_phy_lp_set_antenna(struct bwn_mac *, int);
473 static void	bwn_phy_lp_task_60s(struct bwn_mac *);
474 static void	bwn_phy_lp_readsprom(struct bwn_mac *);
475 static void	bwn_phy_lp_bbinit(struct bwn_mac *);
476 static void	bwn_phy_lp_txpctl_init(struct bwn_mac *);
477 static void	bwn_phy_lp_calib(struct bwn_mac *);
478 static void	bwn_phy_lp_switch_analog(struct bwn_mac *, int);
479 static int	bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
480 static int	bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
481 static void	bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
482 static void	bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
483 static void	bwn_phy_lp_digflt_save(struct bwn_mac *);
484 static void	bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
485 static void	bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
486 static void	bwn_phy_lp_bugfix(struct bwn_mac *);
487 static void	bwn_phy_lp_digflt_restore(struct bwn_mac *);
488 static void	bwn_phy_lp_tblinit(struct bwn_mac *);
489 static void	bwn_phy_lp_bbinit_r2(struct bwn_mac *);
490 static void	bwn_phy_lp_bbinit_r01(struct bwn_mac *);
491 static void	bwn_phy_lp_b2062_init(struct bwn_mac *);
492 static void	bwn_phy_lp_b2063_init(struct bwn_mac *);
493 static void	bwn_phy_lp_rxcal_r2(struct bwn_mac *);
494 static void	bwn_phy_lp_rccal_r12(struct bwn_mac *);
495 static void	bwn_phy_lp_set_rccap(struct bwn_mac *);
496 static uint32_t	bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
497 static void	bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
498 static void	bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
499 static void	bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
500 		    const void *);
501 static void	bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
502 static struct bwn_txgain
503 		bwn_phy_lp_get_txgain(struct bwn_mac *);
504 static uint8_t	bwn_phy_lp_get_bbmult(struct bwn_mac *);
505 static void	bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
506 static void	bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
507 static void	bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
508 static void	bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
509 static void	bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
510 static int	bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
511 static void	bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
512 static void	bwn_phy_lp_tblinit_r01(struct bwn_mac *);
513 static void	bwn_phy_lp_tblinit_r2(struct bwn_mac *);
514 static void	bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
515 static void	bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
516 static void	bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
517 static void	bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
518 static int	bwn_phy_lp_loopback(struct bwn_mac *);
519 static void	bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
520 static void	bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
521 		    int);
522 static uint8_t	bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
523 		    struct bwn_phy_lp_iq_est *);
524 static void	bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
525 static uint32_t	bwn_tab_read(struct bwn_mac *, uint32_t);
526 static void	bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
527 static void	bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
528 static void	bwn_phy_lp_set_txgain_override(struct bwn_mac *);
529 static uint16_t	bwn_phy_lp_get_pa_gain(struct bwn_mac *);
530 static uint8_t	bwn_nbits(int32_t);
531 static void	bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
532 		    struct bwn_txgain_entry *);
533 static void	bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
534 		    struct bwn_txgain_entry);
535 static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
536 		    struct bwn_txgain_entry);
537 static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
538 		    struct bwn_txgain_entry);
539 static void	bwn_sysctl_node(struct bwn_softc *);
540 
541 static struct resource_spec bwn_res_spec_legacy[] = {
542 	{ SYS_RES_IRQ,		0,		RF_ACTIVE | RF_SHAREABLE },
543 	{ -1,			0,		0 }
544 };
545 
546 static struct resource_spec bwn_res_spec_msi[] = {
547 	{ SYS_RES_IRQ,		1,		RF_ACTIVE },
548 	{ -1,			0,		0 }
549 };
550 
551 static const struct bwn_channelinfo bwn_chantable_bg = {
552 	.channels = {
553 		{ 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
554 		{ 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
555 		{ 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
556 		{ 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
557 		{ 2472, 13, 30 }, { 2484, 14, 30 } },
558 	.nchannels = 14
559 };
560 
561 static const struct bwn_channelinfo bwn_chantable_a = {
562 	.channels = {
563 		{ 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
564 		{ 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
565 		{ 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
566 		{ 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
567 		{ 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
568 		{ 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
569 		{ 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
570 		{ 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
571 		{ 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
572 		{ 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
573 		{ 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
574 		{ 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
575 		{ 6080, 216, 30 } },
576 	.nchannels = 37
577 };
578 
579 static const struct bwn_channelinfo bwn_chantable_n = {
580 	.channels = {
581 		{ 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
582 		{ 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
583 		{ 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
584 		{ 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
585 		{ 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
586 		{ 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
587 		{ 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
588 		{ 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
589 		{ 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
590 		{ 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
591 		{ 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
592 		{ 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
593 		{ 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
594 		{ 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
595 		{ 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
596 		{ 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
597 		{ 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
598 		{ 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
599 		{ 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
600 		{ 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
601 		{ 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
602 		{ 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
603 		{ 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
604 		{ 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
605 		{ 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
606 		{ 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
607 		{ 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
608 		{ 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
609 		{ 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
610 		{ 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
611 		{ 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
612 		{ 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
613 		{ 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
614 		{ 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
615 		{ 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
616 		{ 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
617 		{ 6130, 226, 30 }, { 6140, 228, 30 } },
618 	.nchannels = 110
619 };
620 
621 static const uint8_t bwn_b2063_chantable_data[33][12] = {
622 	{ 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
623 	{ 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
624 	{ 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
625 	{ 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
626 	{ 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
627 	{ 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
628 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
629 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
630 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
631 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
632 	{ 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
633 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
634 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
635 	{ 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
636 	{ 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
637 	{ 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
638 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
639 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
640 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
641 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
642 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
643 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
644 	{ 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
645 	{ 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
646 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
647 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
648 	{ 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
649 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
650 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
651 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
652 	{ 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
653 	{ 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
654 	{ 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
655 };
656 
657 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
658 	{ 1, 2412, bwn_b2063_chantable_data[0] },
659 	{ 2, 2417, bwn_b2063_chantable_data[0] },
660 	{ 3, 2422, bwn_b2063_chantable_data[0] },
661 	{ 4, 2427, bwn_b2063_chantable_data[1] },
662 	{ 5, 2432, bwn_b2063_chantable_data[1] },
663 	{ 6, 2437, bwn_b2063_chantable_data[1] },
664 	{ 7, 2442, bwn_b2063_chantable_data[1] },
665 	{ 8, 2447, bwn_b2063_chantable_data[1] },
666 	{ 9, 2452, bwn_b2063_chantable_data[2] },
667 	{ 10, 2457, bwn_b2063_chantable_data[2] },
668 	{ 11, 2462, bwn_b2063_chantable_data[3] },
669 	{ 12, 2467, bwn_b2063_chantable_data[3] },
670 	{ 13, 2472, bwn_b2063_chantable_data[3] },
671 	{ 14, 2484, bwn_b2063_chantable_data[4] },
672 	{ 34, 5170, bwn_b2063_chantable_data[5] },
673 	{ 36, 5180, bwn_b2063_chantable_data[6] },
674 	{ 38, 5190, bwn_b2063_chantable_data[7] },
675 	{ 40, 5200, bwn_b2063_chantable_data[8] },
676 	{ 42, 5210, bwn_b2063_chantable_data[9] },
677 	{ 44, 5220, bwn_b2063_chantable_data[10] },
678 	{ 46, 5230, bwn_b2063_chantable_data[11] },
679 	{ 48, 5240, bwn_b2063_chantable_data[12] },
680 	{ 52, 5260, bwn_b2063_chantable_data[13] },
681 	{ 56, 5280, bwn_b2063_chantable_data[14] },
682 	{ 60, 5300, bwn_b2063_chantable_data[14] },
683 	{ 64, 5320, bwn_b2063_chantable_data[15] },
684 	{ 100, 5500, bwn_b2063_chantable_data[16] },
685 	{ 104, 5520, bwn_b2063_chantable_data[17] },
686 	{ 108, 5540, bwn_b2063_chantable_data[18] },
687 	{ 112, 5560, bwn_b2063_chantable_data[19] },
688 	{ 116, 5580, bwn_b2063_chantable_data[20] },
689 	{ 120, 5600, bwn_b2063_chantable_data[21] },
690 	{ 124, 5620, bwn_b2063_chantable_data[21] },
691 	{ 128, 5640, bwn_b2063_chantable_data[22] },
692 	{ 132, 5660, bwn_b2063_chantable_data[22] },
693 	{ 136, 5680, bwn_b2063_chantable_data[22] },
694 	{ 140, 5700, bwn_b2063_chantable_data[23] },
695 	{ 149, 5745, bwn_b2063_chantable_data[23] },
696 	{ 153, 5765, bwn_b2063_chantable_data[23] },
697 	{ 157, 5785, bwn_b2063_chantable_data[23] },
698 	{ 161, 5805, bwn_b2063_chantable_data[23] },
699 	{ 165, 5825, bwn_b2063_chantable_data[23] },
700 	{ 184, 4920, bwn_b2063_chantable_data[24] },
701 	{ 188, 4940, bwn_b2063_chantable_data[25] },
702 	{ 192, 4960, bwn_b2063_chantable_data[26] },
703 	{ 196, 4980, bwn_b2063_chantable_data[27] },
704 	{ 200, 5000, bwn_b2063_chantable_data[28] },
705 	{ 204, 5020, bwn_b2063_chantable_data[29] },
706 	{ 208, 5040, bwn_b2063_chantable_data[30] },
707 	{ 212, 5060, bwn_b2063_chantable_data[31] },
708 	{ 216, 5080, bwn_b2063_chantable_data[32] }
709 };
710 
711 static const uint8_t bwn_b2062_chantable_data[22][12] = {
712 	{ 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
713 	{ 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 	{ 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715 	{ 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716 	{ 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
717 	{ 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
718 	{ 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
719 	{ 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
720 	{ 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
721 	{ 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
722 	{ 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
723 	{ 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
724 	{ 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
725 	{ 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726 	{ 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727 	{ 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
728 	{ 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
729 	{ 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
730 	{ 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
731 	{ 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
732 	{ 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
733 	{ 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
734 };
735 
736 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
737 	{ 1, 2412, bwn_b2062_chantable_data[0] },
738 	{ 2, 2417, bwn_b2062_chantable_data[0] },
739 	{ 3, 2422, bwn_b2062_chantable_data[0] },
740 	{ 4, 2427, bwn_b2062_chantable_data[0] },
741 	{ 5, 2432, bwn_b2062_chantable_data[0] },
742 	{ 6, 2437, bwn_b2062_chantable_data[0] },
743 	{ 7, 2442, bwn_b2062_chantable_data[0] },
744 	{ 8, 2447, bwn_b2062_chantable_data[0] },
745 	{ 9, 2452, bwn_b2062_chantable_data[0] },
746 	{ 10, 2457, bwn_b2062_chantable_data[0] },
747 	{ 11, 2462, bwn_b2062_chantable_data[0] },
748 	{ 12, 2467, bwn_b2062_chantable_data[0] },
749 	{ 13, 2472, bwn_b2062_chantable_data[0] },
750 	{ 14, 2484, bwn_b2062_chantable_data[0] },
751 	{ 34, 5170, bwn_b2062_chantable_data[1] },
752 	{ 38, 5190, bwn_b2062_chantable_data[2] },
753 	{ 42, 5210, bwn_b2062_chantable_data[2] },
754 	{ 46, 5230, bwn_b2062_chantable_data[3] },
755 	{ 36, 5180, bwn_b2062_chantable_data[4] },
756 	{ 40, 5200, bwn_b2062_chantable_data[5] },
757 	{ 44, 5220, bwn_b2062_chantable_data[6] },
758 	{ 48, 5240, bwn_b2062_chantable_data[3] },
759 	{ 52, 5260, bwn_b2062_chantable_data[3] },
760 	{ 56, 5280, bwn_b2062_chantable_data[3] },
761 	{ 60, 5300, bwn_b2062_chantable_data[7] },
762 	{ 64, 5320, bwn_b2062_chantable_data[8] },
763 	{ 100, 5500, bwn_b2062_chantable_data[9] },
764 	{ 104, 5520, bwn_b2062_chantable_data[10] },
765 	{ 108, 5540, bwn_b2062_chantable_data[10] },
766 	{ 112, 5560, bwn_b2062_chantable_data[10] },
767 	{ 116, 5580, bwn_b2062_chantable_data[11] },
768 	{ 120, 5600, bwn_b2062_chantable_data[12] },
769 	{ 124, 5620, bwn_b2062_chantable_data[12] },
770 	{ 128, 5640, bwn_b2062_chantable_data[12] },
771 	{ 132, 5660, bwn_b2062_chantable_data[12] },
772 	{ 136, 5680, bwn_b2062_chantable_data[12] },
773 	{ 140, 5700, bwn_b2062_chantable_data[12] },
774 	{ 149, 5745, bwn_b2062_chantable_data[12] },
775 	{ 153, 5765, bwn_b2062_chantable_data[12] },
776 	{ 157, 5785, bwn_b2062_chantable_data[12] },
777 	{ 161, 5805, bwn_b2062_chantable_data[12] },
778 	{ 165, 5825, bwn_b2062_chantable_data[12] },
779 	{ 184, 4920, bwn_b2062_chantable_data[13] },
780 	{ 188, 4940, bwn_b2062_chantable_data[14] },
781 	{ 192, 4960, bwn_b2062_chantable_data[15] },
782 	{ 196, 4980, bwn_b2062_chantable_data[16] },
783 	{ 200, 5000, bwn_b2062_chantable_data[17] },
784 	{ 204, 5020, bwn_b2062_chantable_data[18] },
785 	{ 208, 5040, bwn_b2062_chantable_data[19] },
786 	{ 212, 5060, bwn_b2062_chantable_data[20] },
787 	{ 216, 5080, bwn_b2062_chantable_data[21] }
788 };
789 
790 /* for LP PHY */
791 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
792 	{  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
793 	{  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
794 	{  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
795 	{ 13, -66, 13 }, { 14, -66, 13 },
796 };
797 
798 /* for LP PHY */
799 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
800 	{   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
801 	{   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
802 	{   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
803 	{  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
804 	{  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
805 	{  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
806 	{  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
807 	{ 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
808 	{ 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
809 	{ 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
810 	{ 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
811 	{ 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
812 	{ 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
813 };
814 
815 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
816 
817 static const uint8_t bwn_tab_sigsq_tbl[] = {
818 	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
819 	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
820 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
821 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
822 	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
823 	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
824 };
825 
826 static const uint8_t bwn_tab_pllfrac_tbl[] = {
827 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
828 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
829 };
830 
831 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
832 	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
833 	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
834 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
836 	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
837 	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
838 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
840 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
841 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
842 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
843 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
844 };
845 
846 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
847 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
848 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
849 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
850 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
851 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
852 
853 #define	VENDOR_LED_ACT(vendor)				\
854 {							\
855 	.vid = PCI_VENDOR_##vendor,			\
856 	.led_act = { BWN_VENDOR_LED_ACT_##vendor }	\
857 }
858 
859 static const struct {
860 	uint16_t	vid;
861 	uint8_t		led_act[BWN_LED_MAX];
862 } bwn_vendor_led_act[] = {
863 	VENDOR_LED_ACT(COMPAQ),
864 	VENDOR_LED_ACT(ASUSTEK)
865 };
866 
867 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
868 	{ BWN_VENDOR_LED_ACT_DEFAULT };
869 
870 #undef VENDOR_LED_ACT
871 
872 static const struct {
873 	int		on_dur;
874 	int		off_dur;
875 } bwn_led_duration[109] = {
876 	[0]	= { 400, 100 },
877 	[2]	= { 150, 75 },
878 	[4]	= { 90, 45 },
879 	[11]	= { 66, 34 },
880 	[12]	= { 53, 26 },
881 	[18]	= { 42, 21 },
882 	[22]	= { 35, 17 },
883 	[24]	= { 32, 16 },
884 	[36]	= { 21, 10 },
885 	[48]	= { 16, 8 },
886 	[72]	= { 11, 5 },
887 	[96]	= { 9, 4 },
888 	[108]	= { 7, 3 }
889 };
890 
891 static const uint16_t bwn_wme_shm_offsets[] = {
892 	[0] = BWN_WME_BESTEFFORT,
893 	[1] = BWN_WME_BACKGROUND,
894 	[2] = BWN_WME_VOICE,
895 	[3] = BWN_WME_VIDEO,
896 };
897 
898 static const struct siba_devid bwn_devs[] = {
899 	SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
900 	SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
901 	SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
902 	SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
903 	SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
904 	SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
905 	SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
906 	SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
907 	SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
908 };
909 
910 static int
911 bwn_probe(device_t dev)
912 {
913 	struct siba_dev_softc *sd = device_get_ivars(dev);
914 	int i;
915 
916 	for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
917 		if (sd->sd_id.sd_vendor == bwn_devs[i].sd_vendor &&
918 		    sd->sd_id.sd_device == bwn_devs[i].sd_device &&
919 		    sd->sd_id.sd_rev == bwn_devs[i].sd_rev)
920 			return (BUS_PROBE_DEFAULT);
921 	}
922 
923 	return (ENXIO);
924 }
925 
926 static int
927 bwn_attach(device_t dev)
928 {
929 	struct bwn_mac *mac;
930 	struct bwn_softc *sc = device_get_softc(dev);
931 	struct siba_dev_softc *sd = device_get_ivars(dev);
932 	struct siba_softc *siba = sd->sd_bus;
933 	int error, i, msic, reg;
934 
935 	sc->sc_dev = dev;
936 	sc->sc_sd = sd;
937 #ifdef BWN_DEBUG
938 	sc->sc_debug = bwn_debug;
939 #endif
940 
941 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
942 		error = bwn_attach_pre(sc);
943 		if (error != 0)
944 			return (error);
945 		bwn_sprom_bugfixes(sd->sd_bus);
946 		sc->sc_flags |= BWN_FLAG_ATTACHED;
947 	}
948 
949 	if (!TAILQ_EMPTY(&sc->sc_maclist)) {
950 		if (siba->siba_pci_did != 0x4313 &&
951 		    siba->siba_pci_did != 0x431a &&
952 		    siba->siba_pci_did != 0x4321) {
953 			device_printf(sc->sc_dev,
954 			    "skip 802.11 cores\n");
955 			return (ENODEV);
956 		}
957 	}
958 
959 	mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
960 	    M_NOWAIT | M_ZERO);
961 	if (mac == NULL)
962 		return (ENOMEM);
963 	mac->mac_sc = sc;
964 	mac->mac_sd = sd;
965 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
966 	if (bwn_bfp != 0)
967 		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
968 
969 	TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
970 	TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
971 	TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
972 
973 	error = bwn_attach_core(mac);
974 	if (error)
975 		goto fail0;
976 	bwn_led_attach(mac);
977 
978 	device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
979 	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
980 	    sd->sd_bus->siba_chipid, sd->sd_id.sd_rev,
981 	    mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
982 	    mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
983 	    mac->mac_phy.rf_rev);
984 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
985 		device_printf(sc->sc_dev, "DMA (%d bits)\n",
986 		    mac->mac_method.dma.dmatype);
987 	else
988 		device_printf(sc->sc_dev, "PIO\n");
989 
990 	/*
991 	 * setup PCI resources and interrupt.
992 	 */
993 	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
994 		msic = pci_msi_count(dev);
995 		if (bootverbose)
996 			device_printf(sc->sc_dev, "MSI count : %d\n", msic);
997 	} else
998 		msic = 0;
999 
1000 	mac->mac_intr_spec = bwn_res_spec_legacy;
1001 	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
1002 		if (pci_alloc_msi(dev, &msic) == 0) {
1003 			device_printf(sc->sc_dev,
1004 			    "Using %d MSI messages\n", msic);
1005 			mac->mac_intr_spec = bwn_res_spec_msi;
1006 			mac->mac_msi = 1;
1007 		}
1008 	}
1009 
1010 	error = bus_alloc_resources(dev, mac->mac_intr_spec,
1011 	    mac->mac_res_irq);
1012 	if (error) {
1013 		device_printf(sc->sc_dev,
1014 		    "couldn't allocate IRQ resources (%d)\n", error);
1015 		goto fail1;
1016 	}
1017 
1018 	if (mac->mac_msi == 0)
1019 		error = bus_setup_intr(dev, mac->mac_res_irq[0],
1020 		    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1021 		    &mac->mac_intrhand[0]);
1022 	else {
1023 		for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1024 			error = bus_setup_intr(dev, mac->mac_res_irq[i],
1025 			    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1026 			    &mac->mac_intrhand[i]);
1027 			if (error != 0) {
1028 				device_printf(sc->sc_dev,
1029 				    "couldn't setup interrupt (%d)\n", error);
1030 				break;
1031 			}
1032 		}
1033 	}
1034 
1035 	TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1036 
1037 	/*
1038 	 * calls attach-post routine
1039 	 */
1040 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1041 		bwn_attach_post(sc);
1042 
1043 	return (0);
1044 fail1:
1045 	if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1046 		pci_release_msi(dev);
1047 fail0:
1048 	free(mac, M_DEVBUF);
1049 	return (error);
1050 }
1051 
1052 static int
1053 bwn_is_valid_ether_addr(uint8_t *addr)
1054 {
1055 	char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1056 
1057 	if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1058 		return (FALSE);
1059 
1060 	return (TRUE);
1061 }
1062 
1063 static int
1064 bwn_attach_post(struct bwn_softc *sc)
1065 {
1066 	struct ieee80211com *ic;
1067 	struct ifnet *ifp = sc->sc_ifp;
1068 	struct siba_dev_softc *sd = sc->sc_sd;
1069 	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
1070 
1071 	ic = ifp->if_l2com;
1072 	ic->ic_ifp = ifp;
1073 	/* XXX not right but it's not used anywhere important */
1074 	ic->ic_phytype = IEEE80211_T_OFDM;
1075 	ic->ic_opmode = IEEE80211_M_STA;
1076 	ic->ic_caps =
1077 		  IEEE80211_C_STA		/* station mode supported */
1078 		| IEEE80211_C_MONITOR		/* monitor mode */
1079 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
1080 		| IEEE80211_C_SHSLOT		/* short slot time supported */
1081 		| IEEE80211_C_WME		/* WME/WMM supported */
1082 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
1083 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
1084 		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
1085 		;
1086 
1087 	/* call MI attach routine. */
1088 	ieee80211_ifattach(ic,
1089 	    bwn_is_valid_ether_addr(sprom->mac_80211a) ? sprom->mac_80211a :
1090 	    sprom->mac_80211bg);
1091 
1092 	ic->ic_headroom = sizeof(struct bwn_txhdr);
1093 
1094 	/* override default methods */
1095 	ic->ic_raw_xmit = bwn_raw_xmit;
1096 	ic->ic_newassoc = bwn_newassoc;
1097 	ic->ic_updateslot = bwn_updateslot;
1098 	ic->ic_update_promisc = bwn_update_promisc;
1099 	ic->ic_wme.wme_update = bwn_wme_update;
1100 
1101 	ic->ic_node_alloc = bwn_node_alloc;
1102 	sc->sc_node_cleanup = ic->ic_node_cleanup;
1103 	ic->ic_node_cleanup = bwn_node_cleanup;
1104 
1105 	ic->ic_scan_start = bwn_scan_start;
1106 	ic->ic_scan_end = bwn_scan_end;
1107 	ic->ic_set_channel = bwn_set_channel;
1108 
1109 	ic->ic_vap_create = bwn_vap_create;
1110 	ic->ic_vap_delete = bwn_vap_delete;
1111 
1112 	ieee80211_radiotap_attach(ic,
1113 	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1114 	    BWN_TX_RADIOTAP_PRESENT,
1115 	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1116 	    BWN_RX_RADIOTAP_PRESENT);
1117 
1118 	bwn_sysctl_node(sc);
1119 
1120 	if (bootverbose)
1121 		ieee80211_announce(ic);
1122 	return (0);
1123 }
1124 
1125 static void
1126 bwn_phy_detach(struct bwn_mac *mac)
1127 {
1128 
1129 	if (mac->mac_phy.detach != NULL)
1130 		mac->mac_phy.detach(mac);
1131 }
1132 
1133 static int
1134 bwn_detach(device_t dev)
1135 {
1136 	struct bwn_softc *sc = device_get_softc(dev);
1137 	struct bwn_mac *mac = sc->sc_curmac;
1138 	struct ifnet *ifp = sc->sc_ifp;
1139 	struct ieee80211com *ic = ifp->if_l2com;
1140 	int i;
1141 
1142 	sc->sc_flags |= BWN_FLAG_INVALID;
1143 
1144 	if (device_is_attached(sc->sc_dev)) {
1145 		bwn_stop(sc, 1);
1146 		bwn_dma_free(mac);
1147 		callout_drain(&sc->sc_led_blink_ch);
1148 		callout_drain(&sc->sc_rfswitch_ch);
1149 		callout_drain(&sc->sc_task_ch);
1150 		callout_drain(&sc->sc_watchdog_ch);
1151 		bwn_phy_detach(mac);
1152 		if (ifp != NULL) {
1153 			ieee80211_draintask(ic, &mac->mac_hwreset);
1154 			ieee80211_draintask(ic, &mac->mac_txpower);
1155 			ieee80211_ifdetach(ic);
1156 			if_free(ifp);
1157 		}
1158 	}
1159 	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1160 	taskqueue_free(sc->sc_tq);
1161 
1162 	for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1163 		if (mac->mac_intrhand[i] != NULL) {
1164 			bus_teardown_intr(dev, mac->mac_res_irq[i],
1165 			    mac->mac_intrhand[i]);
1166 			mac->mac_intrhand[i] = NULL;
1167 		}
1168 	}
1169 	bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1170 	if (mac->mac_msi != 0)
1171 		pci_release_msi(dev);
1172 
1173 	BWN_LOCK_DESTROY(sc);
1174 	return (0);
1175 }
1176 
1177 static int
1178 bwn_attach_pre(struct bwn_softc *sc)
1179 {
1180 	struct ifnet *ifp;
1181 	int error = 0;
1182 
1183 	BWN_LOCK_INIT(sc);
1184 	TAILQ_INIT(&sc->sc_maclist);
1185 	callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1186 	callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1187 	callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1188 
1189 	sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1190 		taskqueue_thread_enqueue, &sc->sc_tq);
1191 	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1192 		"%s taskq", device_get_nameunit(sc->sc_dev));
1193 
1194 	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1195 	if (ifp == NULL) {
1196 		device_printf(sc->sc_dev, "can not if_alloc()\n");
1197 		error = ENOSPC;
1198 		goto fail;
1199 	}
1200 
1201 	/* set these up early for if_printf use */
1202 	if_initname(ifp, device_get_name(sc->sc_dev),
1203 	    device_get_unit(sc->sc_dev));
1204 
1205 	ifp->if_softc = sc;
1206 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1207 	ifp->if_init = bwn_init;
1208 	ifp->if_ioctl = bwn_ioctl;
1209 	ifp->if_start = bwn_start;
1210 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
1211 	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
1212 	IFQ_SET_READY(&ifp->if_snd);
1213 
1214 	return (0);
1215 
1216 fail:	BWN_LOCK_DESTROY(sc);
1217 	return (error);
1218 }
1219 
1220 static void
1221 bwn_sprom_bugfixes(struct siba_softc *siba)
1222 {
1223 #define	BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)		\
1224 	((siba->siba_pci_vid == PCI_VENDOR_##_vendor) &&		\
1225 	 (siba->siba_pci_did == _device) &&				\
1226 	 (siba->siba_pci_subvid == PCI_VENDOR_##_subvendor) &&		\
1227 	 (siba->siba_pci_subdid == _subdevice))
1228 
1229 	if (siba->siba_board_vendor == PCI_VENDOR_APPLE &&
1230 	    siba->siba_board_type == 0x4e && siba->siba_board_rev > 0x40)
1231 		siba->siba_sprom.bf_lo |= BWN_BFL_PACTRL;
1232 	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_DELL &&
1233 	    siba->siba_chipid == 0x4301 && siba->siba_board_rev == 0x74)
1234 		siba->siba_sprom.bf_lo |= BWN_BFL_BTCOEXIST;
1235 	if (siba->siba_type == SIBA_TYPE_PCI) {
1236 		if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1237 		    BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1238 		    BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1239 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1240 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1241 		    BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1242 		    BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1243 			siba->siba_sprom.bf_lo &= ~BWN_BFL_BTCOEXIST;
1244 	}
1245 #undef	BWN_ISDEV
1246 }
1247 
1248 static int
1249 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1250 {
1251 #define	IS_RUNNING(ifp) \
1252 	((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1253 	struct bwn_softc *sc = ifp->if_softc;
1254 	struct ieee80211com *ic = ifp->if_l2com;
1255 	struct ifreq *ifr = (struct ifreq *)data;
1256 	int error = 0, startall;
1257 
1258 	switch (cmd) {
1259 	case SIOCSIFFLAGS:
1260 		startall = 0;
1261 		if (IS_RUNNING(ifp)) {
1262 			bwn_update_promisc(ifp);
1263 		} else if (ifp->if_flags & IFF_UP) {
1264 			if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1265 				bwn_init(sc);
1266 				startall = 1;
1267 			}
1268 		} else
1269 			bwn_stop(sc, 1);
1270 		if (startall)
1271 			ieee80211_start_all(ic);
1272 		break;
1273 	case SIOCGIFMEDIA:
1274 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1275 		break;
1276 	case SIOCGIFADDR:
1277 		error = ether_ioctl(ifp, cmd, data);
1278 		break;
1279 	default:
1280 		error = EINVAL;
1281 		break;
1282 	}
1283 	return (error);
1284 }
1285 
1286 static void
1287 bwn_start(struct ifnet *ifp)
1288 {
1289 	struct bwn_softc *sc = ifp->if_softc;
1290 
1291 	BWN_LOCK(sc);
1292 	bwn_start_locked(ifp);
1293 	BWN_UNLOCK(sc);
1294 }
1295 
1296 static void
1297 bwn_start_locked(struct ifnet *ifp)
1298 {
1299 	struct bwn_softc *sc = ifp->if_softc;
1300 	struct bwn_mac *mac = sc->sc_curmac;
1301 	struct ieee80211_frame *wh;
1302 	struct ieee80211_node *ni;
1303 	struct ieee80211_key *k;
1304 	struct mbuf *m;
1305 
1306 	BWN_ASSERT_LOCKED(sc);
1307 
1308 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1309 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
1310 		return;
1311 
1312 	for (;;) {
1313 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);	/* XXX: LOCK */
1314 		if (m == NULL)
1315 			break;
1316 
1317 		if (bwn_tx_isfull(sc, m))
1318 			break;
1319 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1320 		if (ni == NULL) {
1321 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
1322 			m_freem(m);
1323 			ifp->if_oerrors++;
1324 			continue;
1325 		}
1326 		KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1327 		wh = mtod(m, struct ieee80211_frame *);
1328 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1329 			k = ieee80211_crypto_encap(ni, m);
1330 			if (k == NULL) {
1331 				ieee80211_free_node(ni);
1332 				m_freem(m);
1333 				ifp->if_oerrors++;
1334 				continue;
1335 			}
1336 		}
1337 		wh = NULL;	/* Catch any invalid use */
1338 
1339 		if (bwn_tx_start(sc, ni, m) != 0) {
1340 			if (ni != NULL)
1341 				ieee80211_free_node(ni);
1342 			ifp->if_oerrors++;
1343 			continue;
1344 		}
1345 
1346 		sc->sc_watchdog_timer = 5;
1347 	}
1348 }
1349 
1350 static int
1351 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1352 {
1353 	struct bwn_dma_ring *dr;
1354 	struct bwn_mac *mac = sc->sc_curmac;
1355 	struct bwn_pio_txqueue *tq;
1356 	struct ifnet *ifp = sc->sc_ifp;
1357 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1358 
1359 	BWN_ASSERT_LOCKED(sc);
1360 
1361 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1362 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1363 		if (dr->dr_stop == 1 ||
1364 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1365 			dr->dr_stop = 1;
1366 			goto full;
1367 		}
1368 	} else {
1369 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1370 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1371 		    pktlen > (tq->tq_size - tq->tq_used)) {
1372 			tq->tq_stop = 1;
1373 			goto full;
1374 		}
1375 	}
1376 	return (0);
1377 full:
1378 	IFQ_DRV_PREPEND(&ifp->if_snd, m);
1379 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1380 	return (1);
1381 }
1382 
1383 static int
1384 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1385 {
1386 	struct bwn_mac *mac = sc->sc_curmac;
1387 	int error;
1388 
1389 	BWN_ASSERT_LOCKED(sc);
1390 
1391 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1392 		m_freem(m);
1393 		return (ENXIO);
1394 	}
1395 
1396 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1397 	    bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1398 	if (error) {
1399 		m_freem(m);
1400 		return (error);
1401 	}
1402 	return (0);
1403 }
1404 
1405 static int
1406 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1407 {
1408 	struct bwn_pio_txpkt *tp;
1409 	struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1410 	struct bwn_softc *sc = mac->mac_sc;
1411 	struct bwn_txhdr txhdr;
1412 	struct mbuf *m_new;
1413 	uint32_t ctl32;
1414 	int error;
1415 	uint16_t ctl16;
1416 
1417 	BWN_ASSERT_LOCKED(sc);
1418 
1419 	/* XXX TODO send packets after DTIM */
1420 
1421 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1422 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1423 	tp->tp_ni = ni;
1424 	tp->tp_m = m;
1425 
1426 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1427 	if (error) {
1428 		device_printf(sc->sc_dev, "tx fail\n");
1429 		return (error);
1430 	}
1431 
1432 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1433 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1434 	tq->tq_free--;
1435 
1436 	if (mac->mac_sd->sd_id.sd_rev >= 8) {
1437 		/*
1438 		 * XXX please removes m_defrag(9)
1439 		 */
1440 		m_new = m_defrag(m, M_DONTWAIT);
1441 		if (m_new == NULL) {
1442 			device_printf(sc->sc_dev,
1443 			    "%s: can't defrag TX buffer\n",
1444 			    __func__);
1445 			return (ENOBUFS);
1446 		}
1447 		if (m_new->m_next != NULL)
1448 			device_printf(sc->sc_dev,
1449 			    "TODO: fragmented packets for PIO\n");
1450 		tp->tp_m = m_new;
1451 
1452 		/* send HEADER */
1453 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1454 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1455 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1456 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1457 		/* send BODY */
1458 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1459 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1460 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1461 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1462 	} else {
1463 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1464 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1465 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1466 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1467 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1468 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1469 		    ctl16 | BWN_PIO_TXCTL_EOF);
1470 	}
1471 
1472 	return (0);
1473 }
1474 
1475 static struct bwn_pio_txqueue *
1476 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1477 {
1478 
1479 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1480 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1481 
1482 	switch (prio) {
1483 	case 0:
1484 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1485 	case 1:
1486 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1487 	case 2:
1488 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1489 	case 3:
1490 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1491 	}
1492 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1493 	return (NULL);
1494 }
1495 
1496 static int
1497 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1498 {
1499 #define	BWN_GET_TXHDRCACHE(slot)					\
1500 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1501 	struct bwn_dma *dma = &mac->mac_method.dma;
1502 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1503 	struct bwn_dmadesc_generic *desc;
1504 	struct bwn_dmadesc_meta *mt;
1505 	struct bwn_softc *sc = mac->mac_sc;
1506 	struct ifnet *ifp = sc->sc_ifp;
1507 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1508 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1509 
1510 	BWN_ASSERT_LOCKED(sc);
1511 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1512 
1513 	/* XXX send after DTIM */
1514 
1515 	slot = bwn_dma_getslot(dr);
1516 	dr->getdesc(dr, slot, &desc, &mt);
1517 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1518 	    ("%s:%d: fail", __func__, __LINE__));
1519 
1520 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1521 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1522 	    BWN_DMA_COOKIE(dr, slot));
1523 	if (error)
1524 		goto fail;
1525 	error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1526 	    BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1527 	    &mt->mt_paddr, BUS_DMA_NOWAIT);
1528 	if (error) {
1529 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1530 		    __func__, error);
1531 		goto fail;
1532 	}
1533 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1534 	    BUS_DMASYNC_PREWRITE);
1535 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1536 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1537 	    BUS_DMASYNC_PREWRITE);
1538 
1539 	slot = bwn_dma_getslot(dr);
1540 	dr->getdesc(dr, slot, &desc, &mt);
1541 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1542 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1543 	mt->mt_m = m;
1544 	mt->mt_ni = ni;
1545 
1546 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1547 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1548 	if (error && error != EFBIG) {
1549 		if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1550 		    __func__, error);
1551 		goto fail;
1552 	}
1553 	if (error) {    /* error == EFBIG */
1554 		struct mbuf *m_new;
1555 
1556 		m_new = m_defrag(m, M_DONTWAIT);
1557 		if (m_new == NULL) {
1558 			if_printf(ifp, "%s: can't defrag TX buffer\n",
1559 			    __func__);
1560 			error = ENOBUFS;
1561 			goto fail;
1562 		} else {
1563 			m = m_new;
1564 		}
1565 
1566 		mt->mt_m = m;
1567 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1568 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1569 		if (error) {
1570 			if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1571 			    __func__, error);
1572 			goto fail;
1573 		}
1574 	}
1575 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1576 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1577 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1578 	    BUS_DMASYNC_PREWRITE);
1579 
1580 	/* XXX send after DTIM */
1581 
1582 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1583 	return (0);
1584 fail:
1585 	dr->dr_curslot = backup[0];
1586 	dr->dr_usedslot = backup[1];
1587 	return (error);
1588 #undef BWN_GET_TXHDRCACHE
1589 }
1590 
1591 static void
1592 bwn_watchdog(void *arg)
1593 {
1594 	struct bwn_softc *sc = arg;
1595 	struct ifnet *ifp = sc->sc_ifp;
1596 
1597 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1598 		if_printf(ifp, "device timeout\n");
1599 		ifp->if_oerrors++;
1600 	}
1601 	callout_schedule(&sc->sc_watchdog_ch, hz);
1602 }
1603 
1604 static int
1605 bwn_attach_core(struct bwn_mac *mac)
1606 {
1607 	struct bwn_softc *sc = mac->mac_sc;
1608 	struct siba_dev_softc *sd = mac->mac_sd;
1609 	struct siba_softc *siba = sd->sd_bus;
1610 	int error, have_bg = 0, have_a = 0;
1611 	uint32_t high;
1612 
1613 	KASSERT(sd->sd_id.sd_rev >= 5,
1614 	    ("unsupported revision %d", sd->sd_id.sd_rev));
1615 
1616 	siba_powerup(siba, 0);
1617 
1618 	high = siba_read_4(sd, SIBA_TGSHIGH);
1619 	bwn_reset_core(mac,
1620 	    (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1621 	error = bwn_phy_getinfo(mac, high);
1622 	if (error)
1623 		goto fail;
1624 
1625 	have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1626 	have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1627 	if (siba->siba_pci_did != 0x4312 && siba->siba_pci_did != 0x4319 &&
1628 	    siba->siba_pci_did != 0x4324) {
1629 		have_a = have_bg = 0;
1630 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1631 			have_a = 1;
1632 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1633 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1634 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1635 			have_bg = 1;
1636 		else
1637 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1638 			    mac->mac_phy.type));
1639 	}
1640 	/* XXX turns off PHY A because it's not supported */
1641 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1642 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1643 		have_a = 0;
1644 		have_bg = 1;
1645 	}
1646 
1647 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1648 		mac->mac_phy.attach = bwn_phy_g_attach;
1649 		mac->mac_phy.detach = bwn_phy_g_detach;
1650 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1651 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1652 		mac->mac_phy.init = bwn_phy_g_init;
1653 		mac->mac_phy.exit = bwn_phy_g_exit;
1654 		mac->mac_phy.phy_read = bwn_phy_g_read;
1655 		mac->mac_phy.phy_write = bwn_phy_g_write;
1656 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1657 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1658 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1659 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1660 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1661 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1662 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1663 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1664 		mac->mac_phy.set_im = bwn_phy_g_im;
1665 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1666 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1667 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1668 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1669 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1670 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1671 		mac->mac_phy.init = bwn_phy_lp_init;
1672 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1673 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1674 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1675 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1676 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1677 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1678 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1679 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1680 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1681 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1682 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1683 	} else {
1684 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1685 		    mac->mac_phy.type);
1686 		error = ENXIO;
1687 		goto fail;
1688 	}
1689 
1690 	mac->mac_phy.gmode = have_bg;
1691 	if (mac->mac_phy.attach != NULL) {
1692 		error = mac->mac_phy.attach(mac);
1693 		if (error) {
1694 			device_printf(sc->sc_dev, "failed\n");
1695 			goto fail;
1696 		}
1697 	}
1698 
1699 	bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1700 
1701 	error = bwn_chiptest(mac);
1702 	if (error)
1703 		goto fail;
1704 	error = bwn_setup_channels(mac, have_bg, have_a);
1705 	if (error) {
1706 		device_printf(sc->sc_dev, "failed to setup channels\n");
1707 		goto fail;
1708 	}
1709 
1710 	if (sc->sc_curmac == NULL)
1711 		sc->sc_curmac = mac;
1712 
1713 	error = bwn_dma_attach(mac);
1714 	if (error != 0) {
1715 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1716 		goto fail;
1717 	}
1718 
1719 	mac->mac_phy.switch_analog(mac, 0);
1720 
1721 	siba_dev_down(sd, 0);
1722 fail:
1723 	siba_powerdown(siba);
1724 	return (error);
1725 }
1726 
1727 static void
1728 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1729 {
1730 	struct siba_dev_softc *sd = mac->mac_sd;
1731 	uint32_t low, ctl;
1732 
1733 	flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1734 
1735 	siba_dev_up(sd, flags);
1736 	DELAY(2000);
1737 
1738 	low = (siba_read_4(sd, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1739 	    ~BWN_TGSLOW_PHYRESET;
1740 	siba_write_4(sd, SIBA_TGSLOW, low);
1741 	siba_read_4(sd, SIBA_TGSLOW);
1742 	DELAY(1000);
1743 	siba_write_4(sd, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1744 	siba_read_4(sd, SIBA_TGSLOW);
1745 	DELAY(1000);
1746 
1747 	if (mac->mac_phy.switch_analog != NULL)
1748 		mac->mac_phy.switch_analog(mac, 1);
1749 
1750 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1751 	if (flags & BWN_TGSLOW_SUPPORT_G)
1752 		ctl |= BWN_MACCTL_GMODE;
1753 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1754 }
1755 
1756 static int
1757 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1758 {
1759 	struct bwn_phy *phy = &mac->mac_phy;
1760 	struct bwn_softc *sc = mac->mac_sc;
1761 	struct siba_dev_softc *sd = mac->mac_sd;
1762 	struct siba_softc *siba = sd->sd_bus;
1763 	uint32_t tmp;
1764 
1765 	/* PHY */
1766 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1767 	phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1768 	phy->rf_on = 1;
1769 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1770 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1771 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1772 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1773 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1774 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1775 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1776 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1777 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1778 		goto unsupphy;
1779 
1780 	/* RADIO */
1781 	if (siba->siba_chipid == 0x4317) {
1782 		if (siba->siba_chiprev == 0)
1783 			tmp = 0x3205017f;
1784 		else if (siba->siba_chiprev == 1)
1785 			tmp = 0x4205017f;
1786 		else
1787 			tmp = 0x5205017f;
1788 	} else {
1789 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1790 		tmp = BWN_READ_2(mac, BWN_RFDATALO);
1791 		BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1792 		tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1793 	}
1794 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1795 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1796 	phy->rf_manuf = (tmp & 0x00000fff);
1797 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1798 		goto unsupradio;
1799 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1800 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1801 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1802 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1803 	    (phy->type == BWN_PHYTYPE_N &&
1804 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1805 	    (phy->type == BWN_PHYTYPE_LP &&
1806 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1807 		goto unsupradio;
1808 
1809 	return (0);
1810 unsupphy:
1811 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1812 	    "analog %#x)\n",
1813 	    phy->type, phy->rev, phy->analog);
1814 	return (ENXIO);
1815 unsupradio:
1816 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1817 	    "rev %#x)\n",
1818 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1819 	return (ENXIO);
1820 }
1821 
1822 static int
1823 bwn_chiptest(struct bwn_mac *mac)
1824 {
1825 #define	TESTVAL0	0x55aaaa55
1826 #define	TESTVAL1	0xaa5555aa
1827 	struct bwn_softc *sc = mac->mac_sc;
1828 	struct siba_dev_softc *sd = mac->mac_sd;
1829 	uint32_t v, backup;
1830 
1831 	BWN_LOCK(sc);
1832 
1833 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1834 
1835 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1836 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1837 		goto error;
1838 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1839 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1840 		goto error;
1841 
1842 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1843 
1844 	if ((sd->sd_id.sd_rev >= 3) && (sd->sd_id.sd_rev <= 10)) {
1845 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1846 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1847 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1848 			goto error;
1849 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1850 			goto error;
1851 	}
1852 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1853 
1854 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1855 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1856 		goto error;
1857 
1858 	BWN_UNLOCK(sc);
1859 	return (0);
1860 error:
1861 	BWN_UNLOCK(sc);
1862 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1863 	return (ENODEV);
1864 }
1865 
1866 #define	IEEE80211_CHAN_HTG	(IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1867 #define	IEEE80211_CHAN_HTA	(IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1868 
1869 static int
1870 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1871 {
1872 	struct bwn_softc *sc = mac->mac_sc;
1873 	struct ifnet *ifp = sc->sc_ifp;
1874 	struct ieee80211com *ic = ifp->if_l2com;
1875 
1876 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1877 	ic->ic_nchans = 0;
1878 
1879 	if (have_bg)
1880 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1881 		    &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1882 	if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1883 		if (have_a)
1884 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1885 			    &ic->ic_nchans, &bwn_chantable_n,
1886 			    IEEE80211_CHAN_HTA);
1887 	} else {
1888 		if (have_a)
1889 			bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1890 			    &ic->ic_nchans, &bwn_chantable_a,
1891 			    IEEE80211_CHAN_A);
1892 	}
1893 
1894 	mac->mac_phy.supports_2ghz = have_bg;
1895 	mac->mac_phy.supports_5ghz = have_a;
1896 
1897 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1898 }
1899 
1900 static uint32_t
1901 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1902 {
1903 	uint32_t ret;
1904 
1905 	BWN_ASSERT_LOCKED(mac->mac_sc);
1906 
1907 	if (way == BWN_SHARED) {
1908 		KASSERT((offset & 0x0001) == 0,
1909 		    ("%s:%d warn", __func__, __LINE__));
1910 		if (offset & 0x0003) {
1911 			bwn_shm_ctlword(mac, way, offset >> 2);
1912 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1913 			ret <<= 16;
1914 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1915 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1916 			goto out;
1917 		}
1918 		offset >>= 2;
1919 	}
1920 	bwn_shm_ctlword(mac, way, offset);
1921 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1922 out:
1923 	return (ret);
1924 }
1925 
1926 static uint16_t
1927 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1928 {
1929 	uint16_t ret;
1930 
1931 	BWN_ASSERT_LOCKED(mac->mac_sc);
1932 
1933 	if (way == BWN_SHARED) {
1934 		KASSERT((offset & 0x0001) == 0,
1935 		    ("%s:%d warn", __func__, __LINE__));
1936 		if (offset & 0x0003) {
1937 			bwn_shm_ctlword(mac, way, offset >> 2);
1938 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1939 			goto out;
1940 		}
1941 		offset >>= 2;
1942 	}
1943 	bwn_shm_ctlword(mac, way, offset);
1944 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1945 out:
1946 
1947 	return (ret);
1948 }
1949 
1950 static void
1951 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1952     uint16_t offset)
1953 {
1954 	uint32_t control;
1955 
1956 	control = way;
1957 	control <<= 16;
1958 	control |= offset;
1959 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1960 }
1961 
1962 static void
1963 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1964     uint32_t value)
1965 {
1966 	BWN_ASSERT_LOCKED(mac->mac_sc);
1967 
1968 	if (way == BWN_SHARED) {
1969 		KASSERT((offset & 0x0001) == 0,
1970 		    ("%s:%d warn", __func__, __LINE__));
1971 		if (offset & 0x0003) {
1972 			bwn_shm_ctlword(mac, way, offset >> 2);
1973 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1974 				    (value >> 16) & 0xffff);
1975 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1976 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1977 			return;
1978 		}
1979 		offset >>= 2;
1980 	}
1981 	bwn_shm_ctlword(mac, way, offset);
1982 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1983 }
1984 
1985 static void
1986 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1987     uint16_t value)
1988 {
1989 	BWN_ASSERT_LOCKED(mac->mac_sc);
1990 
1991 	if (way == BWN_SHARED) {
1992 		KASSERT((offset & 0x0001) == 0,
1993 		    ("%s:%d warn", __func__, __LINE__));
1994 		if (offset & 0x0003) {
1995 			bwn_shm_ctlword(mac, way, offset >> 2);
1996 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1997 			return;
1998 		}
1999 		offset >>= 2;
2000 	}
2001 	bwn_shm_ctlword(mac, way, offset);
2002 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
2003 }
2004 
2005 static void
2006 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
2007     int txpow)
2008 {
2009 
2010 	c->ic_freq = freq;
2011 	c->ic_flags = flags;
2012 	c->ic_ieee = ieee;
2013 	c->ic_minpower = 0;
2014 	c->ic_maxpower = 2 * txpow;
2015 	c->ic_maxregpower = txpow;
2016 }
2017 
2018 static void
2019 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2020     const struct bwn_channelinfo *ci, int flags)
2021 {
2022 	struct ieee80211_channel *c;
2023 	int i;
2024 
2025 	c = &chans[*nchans];
2026 
2027 	for (i = 0; i < ci->nchannels; i++) {
2028 		const struct bwn_channel *hc;
2029 
2030 		hc = &ci->channels[i];
2031 		if (*nchans >= maxchans)
2032 			break;
2033 		bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2034 		c++, (*nchans)++;
2035 		if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2036 			/* g channel have a separate b-only entry */
2037 			if (*nchans >= maxchans)
2038 				break;
2039 			c[0] = c[-1];
2040 			c[-1].ic_flags = IEEE80211_CHAN_B;
2041 			c++, (*nchans)++;
2042 		}
2043 		if (flags == IEEE80211_CHAN_HTG) {
2044 			/* HT g channel have a separate g-only entry */
2045 			if (*nchans >= maxchans)
2046 				break;
2047 			c[-1].ic_flags = IEEE80211_CHAN_G;
2048 			c[0] = c[-1];
2049 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2050 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
2051 			c++, (*nchans)++;
2052 		}
2053 		if (flags == IEEE80211_CHAN_HTA) {
2054 			/* HT a channel have a separate a-only entry */
2055 			if (*nchans >= maxchans)
2056 				break;
2057 			c[-1].ic_flags = IEEE80211_CHAN_A;
2058 			c[0] = c[-1];
2059 			c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2060 			c[0].ic_flags |= IEEE80211_CHAN_HT20;	/* HT20 */
2061 			c++, (*nchans)++;
2062 		}
2063 	}
2064 }
2065 
2066 static int
2067 bwn_phy_g_attach(struct bwn_mac *mac)
2068 {
2069 	struct bwn_softc *sc = mac->mac_sc;
2070 	struct bwn_phy *phy = &mac->mac_phy;
2071 	struct bwn_phy_g *pg = &phy->phy_g;
2072 	struct siba_dev_softc *sd = mac->mac_sd;
2073 	struct siba_sprom *sprom = &sd->sd_bus->siba_sprom;
2074 	unsigned int i;
2075 	int16_t pab0 = (int16_t)(sprom->pa0b0), pab1 = (int16_t)(sprom->pa0b1),
2076 	    pab2 = (int16_t)(sprom->pa0b2);
2077 	static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2078 	int8_t bg = (int8_t)sprom->tssi_bg;
2079 
2080 	if ((sd->sd_bus->siba_chipid == 0x4301) && (phy->rf_ver != 0x2050))
2081 		device_printf(sc->sc_dev, "not supported anymore\n");
2082 
2083 	pg->pg_flags = 0;
2084 	if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2085 	    pab2 == -1) {
2086 		pg->pg_idletssi = 52;
2087 		pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2088 		return (0);
2089 	}
2090 
2091 	pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2092 	pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2093 	if (pg->pg_tssi2dbm == NULL) {
2094 		device_printf(sc->sc_dev, "failed to allocate buffer\n");
2095 		return (ENOMEM);
2096 	}
2097 	for (i = 0; i < 64; i++) {
2098 		int32_t m1, m2, f, q, delta;
2099 		int8_t j = 0;
2100 
2101 		m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2102 		m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2103 		f = 256;
2104 
2105 		do {
2106 			if (j > 15) {
2107 				device_printf(sc->sc_dev,
2108 				    "failed to generate tssi2dBm\n");
2109 				free(pg->pg_tssi2dbm, M_DEVBUF);
2110 				return (ENOMEM);
2111 			}
2112 			q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2113 			    f, 2048);
2114 			delta = abs(q - f);
2115 			f = q;
2116 			j++;
2117 		} while (delta >= 2);
2118 
2119 		pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2120 		    128);
2121 	}
2122 
2123 	pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2124 	return (0);
2125 }
2126 
2127 static void
2128 bwn_phy_g_detach(struct bwn_mac *mac)
2129 {
2130 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2131 
2132 	if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2133 		free(pg->pg_tssi2dbm, M_DEVBUF);
2134 		pg->pg_tssi2dbm = NULL;
2135 	}
2136 	pg->pg_flags = 0;
2137 }
2138 
2139 static void
2140 bwn_phy_g_init_pre(struct bwn_mac *mac)
2141 {
2142 	struct bwn_phy *phy = &mac->mac_phy;
2143 	struct bwn_phy_g *pg = &phy->phy_g;
2144 	void *tssi2dbm;
2145 	int idletssi;
2146 	unsigned int i;
2147 
2148 	tssi2dbm = pg->pg_tssi2dbm;
2149 	idletssi = pg->pg_idletssi;
2150 
2151 	memset(pg, 0, sizeof(*pg));
2152 
2153 	pg->pg_tssi2dbm = tssi2dbm;
2154 	pg->pg_idletssi = idletssi;
2155 
2156 	memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2157 
2158 	for (i = 0; i < N(pg->pg_nrssi); i++)
2159 		pg->pg_nrssi[i] = -1000;
2160 	for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2161 		pg->pg_nrssi_lt[i] = i;
2162 	pg->pg_lofcal = 0xffff;
2163 	pg->pg_initval = 0xffff;
2164 	pg->pg_immode = BWN_IMMODE_NONE;
2165 	pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2166 	pg->pg_avgtssi = 0xff;
2167 
2168 	pg->pg_loctl.tx_bias = 0xff;
2169 	TAILQ_INIT(&pg->pg_loctl.calib_list);
2170 }
2171 
2172 static int
2173 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2174 {
2175 	struct bwn_phy *phy = &mac->mac_phy;
2176 	struct bwn_phy_g *pg = &phy->phy_g;
2177 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2178 	struct siba_softc *bus = mac->mac_sd->sd_bus;
2179 	static const struct bwn_rfatt rfatt0[] = {
2180 		{ 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 },	{ 9, 0 }, { 2, 0 },
2181 		{ 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2182 		{ 3, 1 }, { 4, 1 }
2183 	};
2184 	static const struct bwn_rfatt rfatt1[] = {
2185 		{ 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2186 		{ 14, 1 }
2187 	};
2188 	static const struct bwn_rfatt rfatt2[] = {
2189 		{ 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2190 		{ 9, 1 }
2191 	};
2192 	static const struct bwn_bbatt bbatt_0[] = {
2193 		{ 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2194 	};
2195 
2196 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2197 
2198 	if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2199 		pg->pg_bbatt.att = 0;
2200 	else
2201 		pg->pg_bbatt.att = 2;
2202 
2203 	/* prepare Radio Attenuation */
2204 	pg->pg_rfatt.padmix = 0;
2205 
2206 	if (bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
2207 	    bus->siba_board_type == SIBA_BOARD_BCM4309G) {
2208 		if (bus->siba_board_rev < 0x43) {
2209 			pg->pg_rfatt.att = 2;
2210 			goto done;
2211 		} else if (bus->siba_board_rev < 0x51) {
2212 			pg->pg_rfatt.att = 3;
2213 			goto done;
2214 		}
2215 	}
2216 
2217 	if (phy->type == BWN_PHYTYPE_A) {
2218 		pg->pg_rfatt.att = 0x60;
2219 		goto done;
2220 	}
2221 
2222 	switch (phy->rf_ver) {
2223 	case 0x2050:
2224 		switch (phy->rf_rev) {
2225 		case 0:
2226 			pg->pg_rfatt.att = 5;
2227 			goto done;
2228 		case 1:
2229 			if (phy->type == BWN_PHYTYPE_G) {
2230 				if (bus->siba_board_vendor ==
2231 				    SIBA_BOARDVENDOR_BCM &&
2232 				    bus->siba_board_type ==
2233 				    SIBA_BOARD_BCM4309G &&
2234 				    bus->siba_board_rev >= 30)
2235 					pg->pg_rfatt.att = 3;
2236 				else if (bus->siba_board_vendor ==
2237 				    SIBA_BOARDVENDOR_BCM &&
2238 				    bus->siba_board_type == SIBA_BOARD_BU4306)
2239 					pg->pg_rfatt.att = 3;
2240 				else
2241 					pg->pg_rfatt.att = 1;
2242 			} else {
2243 				if (bus->siba_board_vendor ==
2244 				    SIBA_BOARDVENDOR_BCM &&
2245 				    bus->siba_board_type ==
2246 				    SIBA_BOARD_BCM4309G &&
2247 				    bus->siba_board_rev >= 30)
2248 					pg->pg_rfatt.att = 7;
2249 				else
2250 					pg->pg_rfatt.att = 6;
2251 			}
2252 			goto done;
2253 		case 2:
2254 			if (phy->type == BWN_PHYTYPE_G) {
2255 				if (bus->siba_board_vendor ==
2256 				    SIBA_BOARDVENDOR_BCM &&
2257 				    bus->siba_board_type ==
2258 				    SIBA_BOARD_BCM4309G &&
2259 				    bus->siba_board_rev >= 30)
2260 					pg->pg_rfatt.att = 3;
2261 				else if (bus->siba_board_vendor ==
2262 				    SIBA_BOARDVENDOR_BCM &&
2263 				    bus->siba_board_type == SIBA_BOARD_BU4306)
2264 					pg->pg_rfatt.att = 5;
2265 				else if (bus->siba_chipid == 0x4320)
2266 					pg->pg_rfatt.att = 4;
2267 				else
2268 					pg->pg_rfatt.att = 3;
2269 			} else
2270 				pg->pg_rfatt.att = 6;
2271 			goto done;
2272 		case 3:
2273 			pg->pg_rfatt.att = 5;
2274 			goto done;
2275 		case 4:
2276 		case 5:
2277 			pg->pg_rfatt.att = 1;
2278 			goto done;
2279 		case 6:
2280 		case 7:
2281 			pg->pg_rfatt.att = 5;
2282 			goto done;
2283 		case 8:
2284 			pg->pg_rfatt.att = 0xa;
2285 			pg->pg_rfatt.padmix = 1;
2286 			goto done;
2287 		case 9:
2288 		default:
2289 			pg->pg_rfatt.att = 5;
2290 			goto done;
2291 		}
2292 		break;
2293 	case 0x2053:
2294 		switch (phy->rf_rev) {
2295 		case 1:
2296 			pg->pg_rfatt.att = 6;
2297 			goto done;
2298 		}
2299 		break;
2300 	}
2301 	pg->pg_rfatt.att = 5;
2302 done:
2303 	pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2304 
2305 	if (!bwn_has_hwpctl(mac)) {
2306 		lo->rfatt.array = rfatt0;
2307 		lo->rfatt.len = N(rfatt0);
2308 		lo->rfatt.min = 0;
2309 		lo->rfatt.max = 9;
2310 		goto genbbatt;
2311 	}
2312 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2313 		lo->rfatt.array = rfatt1;
2314 		lo->rfatt.len = N(rfatt1);
2315 		lo->rfatt.min = 0;
2316 		lo->rfatt.max = 14;
2317 		goto genbbatt;
2318 	}
2319 	lo->rfatt.array = rfatt2;
2320 	lo->rfatt.len = N(rfatt2);
2321 	lo->rfatt.min = 0;
2322 	lo->rfatt.max = 9;
2323 genbbatt:
2324 	lo->bbatt.array = bbatt_0;
2325 	lo->bbatt.len = N(bbatt_0);
2326 	lo->bbatt.min = 0;
2327 	lo->bbatt.max = 8;
2328 
2329 	BWN_READ_4(mac, BWN_MACCTL);
2330 	if (phy->rev == 1) {
2331 		phy->gmode = 0;
2332 		bwn_reset_core(mac, 0);
2333 		bwn_phy_g_init_sub(mac);
2334 		phy->gmode = 1;
2335 		bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2336 	}
2337 	return (0);
2338 }
2339 
2340 static uint16_t
2341 bwn_phy_g_txctl(struct bwn_mac *mac)
2342 {
2343 	struct bwn_phy *phy = &mac->mac_phy;
2344 
2345 	if (phy->rf_ver != 0x2050)
2346 		return (0);
2347 	if (phy->rf_rev == 1)
2348 		return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2349 	if (phy->rf_rev < 6)
2350 		return (BWN_TXCTL_PA2DB);
2351 	if (phy->rf_rev == 8)
2352 		return (BWN_TXCTL_TXMIX);
2353 	return (0);
2354 }
2355 
2356 static int
2357 bwn_phy_g_init(struct bwn_mac *mac)
2358 {
2359 
2360 	bwn_phy_g_init_sub(mac);
2361 	return (0);
2362 }
2363 
2364 static void
2365 bwn_phy_g_exit(struct bwn_mac *mac)
2366 {
2367 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2368 	struct bwn_lo_calib *cal, *tmp;
2369 
2370 	if (lo == NULL)
2371 		return;
2372 	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2373 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2374 		free(cal, M_DEVBUF);
2375 	}
2376 }
2377 
2378 static uint16_t
2379 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2380 {
2381 
2382 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2383 	return (BWN_READ_2(mac, BWN_PHYDATA));
2384 }
2385 
2386 static void
2387 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2388 {
2389 
2390 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2391 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
2392 }
2393 
2394 static uint16_t
2395 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2396 {
2397 
2398 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2399 	BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2400 	return (BWN_READ_2(mac, BWN_RFDATALO));
2401 }
2402 
2403 static void
2404 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2405 {
2406 
2407 	KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2408 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
2409 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
2410 }
2411 
2412 static int
2413 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2414 {
2415 
2416 	return (mac->mac_phy.rev >= 6);
2417 }
2418 
2419 static void
2420 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2421 {
2422 	struct bwn_phy *phy = &mac->mac_phy;
2423 	struct bwn_phy_g *pg = &phy->phy_g;
2424 	unsigned int channel;
2425 	uint16_t rfover, rfoverval;
2426 
2427 	if (on) {
2428 		if (phy->rf_on)
2429 			return;
2430 
2431 		BWN_PHY_WRITE(mac, 0x15, 0x8000);
2432 		BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2433 		BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2434 		if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2435 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2436 			    pg->pg_radioctx_over);
2437 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2438 			    pg->pg_radioctx_overval);
2439 			pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2440 		}
2441 		channel = phy->chan;
2442 		bwn_phy_g_switch_chan(mac, 6, 1);
2443 		bwn_phy_g_switch_chan(mac, channel, 0);
2444 		return;
2445 	}
2446 
2447 	rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2448 	rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2449 	pg->pg_radioctx_over = rfover;
2450 	pg->pg_radioctx_overval = rfoverval;
2451 	pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2452 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2453 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2454 }
2455 
2456 static int
2457 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2458 {
2459 
2460 	if ((newchan < 1) || (newchan > 14))
2461 		return (EINVAL);
2462 	bwn_phy_g_switch_chan(mac, newchan, 0);
2463 
2464 	return (0);
2465 }
2466 
2467 static uint32_t
2468 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2469 {
2470 
2471 	return (1);
2472 }
2473 
2474 static void
2475 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2476 {
2477 	struct bwn_phy *phy = &mac->mac_phy;
2478 	uint64_t hf;
2479 	int autodiv = 0;
2480 	uint16_t tmp;
2481 
2482 	if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2483 		autodiv = 1;
2484 
2485 	hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2486 	bwn_hf_write(mac, hf);
2487 
2488 	BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2489 	    (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2490 	    ((autodiv ? BWN_ANTAUTO1 : antenna)
2491 		<< BWN_PHY_BBANDCFG_RXANT_SHIFT));
2492 
2493 	if (autodiv) {
2494 		tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2495 		if (antenna == BWN_ANTAUTO1)
2496 			tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2497 		else
2498 			tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2499 		BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2500 	}
2501 	tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2502 	if (autodiv)
2503 		tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2504 	else
2505 		tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2506 	BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2507 	if (phy->rev >= 2) {
2508 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2509 		    BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2510 		BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2511 		    (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2512 		    0x15);
2513 		if (phy->rev == 2)
2514 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2515 		else
2516 			BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2517 			    (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2518 			    8);
2519 	}
2520 	if (phy->rev >= 6)
2521 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2522 
2523 	hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2524 	bwn_hf_write(mac, hf);
2525 }
2526 
2527 static int
2528 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2529 {
2530 	struct bwn_phy *phy = &mac->mac_phy;
2531 	struct bwn_phy_g *pg = &phy->phy_g;
2532 
2533 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2534 	KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2535 
2536 	if (phy->rev == 0 || !phy->gmode)
2537 		return (ENODEV);
2538 
2539 	pg->pg_aci_wlan_automatic = 0;
2540 	return (0);
2541 }
2542 
2543 static int
2544 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2545 {
2546 	struct bwn_phy *phy = &mac->mac_phy;
2547 	struct bwn_phy_g *pg = &phy->phy_g;
2548 	struct bwn_softc *sc = mac->mac_sc;
2549 	struct siba_softc *siba = mac->mac_sd->sd_bus;
2550 	unsigned int tssi;
2551 	int cck, ofdm;
2552 	int power;
2553 	int rfatt, bbatt;
2554 	unsigned int max;
2555 
2556 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2557 
2558 	cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2559 	ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2560 	if (cck < 0 && ofdm < 0) {
2561 		if (ignore_tssi == 0)
2562 			return (BWN_TXPWR_RES_DONE);
2563 		cck = 0;
2564 		ofdm = 0;
2565 	}
2566 	tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2567 	if (pg->pg_avgtssi != 0xff)
2568 		tssi = (tssi + pg->pg_avgtssi) / 2;
2569 	pg->pg_avgtssi = tssi;
2570 	KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2571 
2572 	max = siba->siba_sprom.maxpwr_bg;
2573 	if (siba->siba_sprom.bf_lo & BWN_BFL_PACTRL)
2574 		max -= 3;
2575 	if (max >= 120) {
2576 		device_printf(sc->sc_dev, "invalid max TX-power value\n");
2577 		siba->siba_sprom.maxpwr_bg = max = 80;
2578 	}
2579 
2580 	power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2581 	    (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2582 	     tssi, 0x00), 0x3f)]);
2583 	if (power == 0)
2584 		return (BWN_TXPWR_RES_DONE);
2585 
2586 	rfatt = -((power + 7) / 8);
2587 	bbatt = (-(power / 2)) - (4 * rfatt);
2588 	if ((rfatt == 0) && (bbatt == 0))
2589 		return (BWN_TXPWR_RES_DONE);
2590 	pg->pg_bbatt_delta = bbatt;
2591 	pg->pg_rfatt_delta = rfatt;
2592 	return (BWN_TXPWR_RES_NEED_ADJUST);
2593 }
2594 
2595 static void
2596 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2597 {
2598 	struct bwn_phy *phy = &mac->mac_phy;
2599 	struct bwn_phy_g *pg = &phy->phy_g;
2600 	struct bwn_softc *sc = mac->mac_sc;
2601 	int rfatt, bbatt;
2602 	uint8_t txctl;
2603 
2604 	bwn_mac_suspend(mac);
2605 
2606 	BWN_ASSERT_LOCKED(sc);
2607 
2608 	bbatt = pg->pg_bbatt.att;
2609 	bbatt += pg->pg_bbatt_delta;
2610 	rfatt = pg->pg_rfatt.att;
2611 	rfatt += pg->pg_rfatt_delta;
2612 
2613 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2614 	txctl = pg->pg_txctl;
2615 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2616 		if (rfatt <= 1) {
2617 			if (txctl == 0) {
2618 				txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2619 				rfatt += 2;
2620 				bbatt += 2;
2621 			} else if (mac->mac_sd->sd_bus->siba_sprom.
2622 				   bf_lo &
2623 				   BWN_BFL_PACTRL) {
2624 				bbatt += 4 * (rfatt - 2);
2625 				rfatt = 2;
2626 			}
2627 		} else if (rfatt > 4 && txctl) {
2628 			txctl = 0;
2629 			if (bbatt < 3) {
2630 				rfatt -= 3;
2631 				bbatt += 2;
2632 			} else {
2633 				rfatt -= 2;
2634 				bbatt -= 2;
2635 			}
2636 		}
2637 	}
2638 	pg->pg_txctl = txctl;
2639 	bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2640 	pg->pg_rfatt.att = rfatt;
2641 	pg->pg_bbatt.att = bbatt;
2642 
2643 	DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2644 
2645 	bwn_phy_lock(mac);
2646 	bwn_rf_lock(mac);
2647 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2648 	    pg->pg_txctl);
2649 	bwn_rf_unlock(mac);
2650 	bwn_phy_unlock(mac);
2651 
2652 	bwn_mac_enable(mac);
2653 }
2654 
2655 static void
2656 bwn_phy_g_task_15s(struct bwn_mac *mac)
2657 {
2658 	struct bwn_phy *phy = &mac->mac_phy;
2659 	struct bwn_phy_g *pg = &phy->phy_g;
2660 	struct bwn_softc *sc = mac->mac_sc;
2661 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2662 	unsigned long expire, now;
2663 	struct bwn_lo_calib *cal, *tmp;
2664 	uint8_t expired = 0;
2665 
2666 	bwn_mac_suspend(mac);
2667 
2668 	if (lo == NULL)
2669 		goto fail;
2670 
2671 	BWN_GETTIME(now);
2672 	if (bwn_has_hwpctl(mac)) {
2673 		expire = now - BWN_LO_PWRVEC_EXPIRE;
2674 		if (time_before(lo->pwr_vec_read_time, expire)) {
2675 			bwn_lo_get_powervector(mac);
2676 			bwn_phy_g_dc_lookup_init(mac, 0);
2677 		}
2678 		goto fail;
2679 	}
2680 
2681 	expire = now - BWN_LO_CALIB_EXPIRE;
2682 	TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2683 		if (!time_before(cal->calib_time, expire))
2684 			continue;
2685 		if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2686 		    BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2687 			KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2688 			expired = 1;
2689 		}
2690 
2691 		DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2692 		    cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2693 		    cal->ctl.i, cal->ctl.q);
2694 
2695 		TAILQ_REMOVE(&lo->calib_list, cal, list);
2696 		free(cal, M_DEVBUF);
2697 	}
2698 	if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2699 		cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2700 		    &pg->pg_rfatt);
2701 		if (cal == NULL) {
2702 			device_printf(sc->sc_dev,
2703 			    "failed to recalibrate LO\n");
2704 			goto fail;
2705 		}
2706 		TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2707 		bwn_lo_write(mac, &cal->ctl);
2708 	}
2709 
2710 fail:
2711 	bwn_mac_enable(mac);
2712 }
2713 
2714 static void
2715 bwn_phy_g_task_60s(struct bwn_mac *mac)
2716 {
2717 	struct bwn_phy *phy = &mac->mac_phy;
2718 	uint8_t old = phy->chan;
2719 
2720 	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI))
2721 		return;
2722 
2723 	bwn_mac_suspend(mac);
2724 	bwn_nrssi_slope_11g(mac);
2725 	if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2726 		bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2727 		bwn_switch_channel(mac, old);
2728 	}
2729 	bwn_mac_enable(mac);
2730 }
2731 
2732 static void
2733 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2734 {
2735 
2736 	BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2737 }
2738 
2739 static int
2740 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2741 	const struct ieee80211_bpf_params *params)
2742 {
2743 	struct ieee80211com *ic = ni->ni_ic;
2744 	struct ifnet *ifp = ic->ic_ifp;
2745 	struct bwn_softc *sc = ifp->if_softc;
2746 	struct bwn_mac *mac = sc->sc_curmac;
2747 
2748 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2749 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
2750 		ieee80211_free_node(ni);
2751 		m_freem(m);
2752 		return (ENETDOWN);
2753 	}
2754 
2755 	BWN_LOCK(sc);
2756 	if (bwn_tx_isfull(sc, m)) {
2757 		ieee80211_free_node(ni);
2758 		m_freem(m);
2759 		ifp->if_oerrors++;
2760 		BWN_UNLOCK(sc);
2761 		return (ENOBUFS);
2762 	}
2763 
2764 	if (bwn_tx_start(sc, ni, m) != 0) {
2765 		if (ni != NULL)
2766 			ieee80211_free_node(ni);
2767 		ifp->if_oerrors++;
2768 	}
2769 	sc->sc_watchdog_timer = 5;
2770 	BWN_UNLOCK(sc);
2771 	return (0);
2772 }
2773 
2774 /*
2775  * Setup driver-specific state for a newly associated node.
2776  * Note that we're called also on a re-associate, the isnew
2777  * param tells us if this is the first time or not.
2778  */
2779 static void
2780 bwn_newassoc(struct ieee80211_node *ni, int isnew)
2781 {
2782 	struct ieee80211vap *vap = ni->ni_vap;
2783 
2784 	ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
2785 	    &BWN_NODE(ni)->bn_amn, ni);
2786 }
2787 
2788 /*
2789  * Callback from the 802.11 layer to update the slot time
2790  * based on the current setting.  We use it to notify the
2791  * firmware of ERP changes and the f/w takes care of things
2792  * like slot time and preamble.
2793  */
2794 static void
2795 bwn_updateslot(struct ifnet *ifp)
2796 {
2797 	struct bwn_softc *sc = ifp->if_softc;
2798 	struct ieee80211com *ic = ifp->if_l2com;
2799 	struct bwn_mac *mac;
2800 
2801 	BWN_LOCK(sc);
2802 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2803 		mac = (struct bwn_mac *)sc->sc_curmac;
2804 		bwn_set_slot_time(mac,
2805 		    (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2806 	}
2807 	BWN_UNLOCK(sc);
2808 }
2809 
2810 /*
2811  * Callback from the 802.11 layer after a promiscuous mode change.
2812  * Note this interface does not check the operating mode as this
2813  * is an internal callback and we are expected to honor the current
2814  * state (e.g. this is used for setting the interface in promiscuous
2815  * mode when operating in hostap mode to do ACS).
2816  */
2817 static void
2818 bwn_update_promisc(struct ifnet *ifp)
2819 {
2820 	struct bwn_softc *sc = ifp->if_softc;
2821 	struct bwn_mac *mac = sc->sc_curmac;
2822 
2823 	BWN_LOCK(sc);
2824 	mac = sc->sc_curmac;
2825 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2826 		if (ifp->if_flags & IFF_PROMISC)
2827 			sc->sc_filters |= BWN_MACCTL_PROMISC;
2828 		else
2829 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2830 		bwn_set_opmode(mac);
2831 	}
2832 	BWN_UNLOCK(sc);
2833 }
2834 
2835 /*
2836  * Callback from the 802.11 layer to update WME parameters.
2837  */
2838 static int
2839 bwn_wme_update(struct ieee80211com *ic)
2840 {
2841 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2842 	struct bwn_mac *mac = sc->sc_curmac;
2843 	struct wmeParams *wmep;
2844 	int i;
2845 
2846 	BWN_LOCK(sc);
2847 	mac = sc->sc_curmac;
2848 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2849 		bwn_mac_suspend(mac);
2850 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
2851 			wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2852 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2853 		}
2854 		bwn_mac_enable(mac);
2855 	}
2856 	BWN_UNLOCK(sc);
2857 	return (0);
2858 }
2859 
2860 static struct ieee80211_node *
2861 bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
2862 {
2863 	struct ieee80211com *ic = vap->iv_ic;
2864 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2865 	const size_t space = sizeof(struct bwn_node);
2866 	struct bwn_node *bn;
2867 
2868 	bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
2869 	if (bn == NULL) {
2870 		/* XXX stat+msg */
2871 		return (NULL);
2872 	}
2873 	DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
2874 	return (&bn->bn_node);
2875 }
2876 
2877 static void
2878 bwn_node_cleanup(struct ieee80211_node *ni)
2879 {
2880 	struct ieee80211com *ic = ni->ni_ic;
2881 	struct bwn_softc *sc = ic->ic_ifp->if_softc;
2882 
2883 	sc->sc_node_cleanup(ni);
2884 }
2885 
2886 static void
2887 bwn_scan_start(struct ieee80211com *ic)
2888 {
2889 	struct ifnet *ifp = ic->ic_ifp;
2890 	struct bwn_softc *sc = ifp->if_softc;
2891 	struct bwn_mac *mac;
2892 
2893 	BWN_LOCK(sc);
2894 	mac = sc->sc_curmac;
2895 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2896 		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2897 		bwn_set_opmode(mac);
2898 		/* disable CFP update during scan */
2899 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2900 	}
2901 	BWN_UNLOCK(sc);
2902 }
2903 
2904 static void
2905 bwn_scan_end(struct ieee80211com *ic)
2906 {
2907 	struct ifnet *ifp = ic->ic_ifp;
2908 	struct bwn_softc *sc = ifp->if_softc;
2909 	struct bwn_mac *mac;
2910 
2911 	BWN_LOCK(sc);
2912 	mac = sc->sc_curmac;
2913 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2914 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2915 		bwn_set_opmode(mac);
2916 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2917 	}
2918 	BWN_UNLOCK(sc);
2919 }
2920 
2921 static void
2922 bwn_set_channel(struct ieee80211com *ic)
2923 {
2924 	struct ifnet *ifp = ic->ic_ifp;
2925 	struct bwn_softc *sc = ifp->if_softc;
2926 	struct bwn_mac *mac = sc->sc_curmac;
2927 	struct bwn_phy *phy = &mac->mac_phy;
2928 	int chan, error;
2929 
2930 	BWN_LOCK(sc);
2931 
2932 	error = bwn_switch_band(sc, ic->ic_curchan);
2933 	if (error)
2934 		goto fail;;
2935 	bwn_mac_suspend(mac);
2936 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2937 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2938 	if (chan != phy->chan)
2939 		bwn_switch_channel(mac, chan);
2940 
2941 	/* TX power level */
2942 	if (ic->ic_curchan->ic_maxpower != 0 &&
2943 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
2944 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2945 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2946 		    BWN_TXPWR_IGNORE_TSSI);
2947 	}
2948 
2949 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2950 	if (phy->set_antenna)
2951 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2952 
2953 	if (sc->sc_rf_enabled != phy->rf_on) {
2954 		if (sc->sc_rf_enabled) {
2955 			bwn_rf_turnon(mac);
2956 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2957 				device_printf(sc->sc_dev,
2958 				    "please turns on the RF switch\n");
2959 		} else
2960 			bwn_rf_turnoff(mac);
2961 	}
2962 
2963 	bwn_mac_enable(mac);
2964 
2965 fail:
2966 	/*
2967 	 * Setup radio tap channel freq and flags
2968 	 */
2969 	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2970 		htole16(ic->ic_curchan->ic_freq);
2971 	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2972 		htole16(ic->ic_curchan->ic_flags & 0xffff);
2973 
2974 	BWN_UNLOCK(sc);
2975 }
2976 
2977 static struct ieee80211vap *
2978 bwn_vap_create(struct ieee80211com *ic,
2979 	const char name[IFNAMSIZ], int unit, int opmode, int flags,
2980 	const uint8_t bssid[IEEE80211_ADDR_LEN],
2981 	const uint8_t mac0[IEEE80211_ADDR_LEN])
2982 {
2983 	struct ifnet *ifp = ic->ic_ifp;
2984 	struct bwn_softc *sc = ifp->if_softc;
2985 	struct ieee80211vap *vap;
2986 	struct bwn_vap *bvp;
2987 	uint8_t mac[IEEE80211_ADDR_LEN];
2988 
2989 	IEEE80211_ADDR_COPY(mac, mac0);
2990 	switch (opmode) {
2991 	case IEEE80211_M_HOSTAP:
2992 	case IEEE80211_M_MBSS:
2993 	case IEEE80211_M_STA:
2994 	case IEEE80211_M_WDS:
2995 	case IEEE80211_M_MONITOR:
2996 	case IEEE80211_M_IBSS:
2997 	case IEEE80211_M_AHDEMO:
2998 		break;
2999 	default:
3000 		return (NULL);
3001 	}
3002 
3003 	IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
3004 
3005 	bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
3006 	    M_80211_VAP, M_NOWAIT | M_ZERO);
3007 	if (bvp == NULL) {
3008 		device_printf(sc->sc_dev, "failed to allocate a buffer\n");
3009 		return (NULL);
3010 	}
3011 	vap = &bvp->bv_vap;
3012 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
3013 	IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
3014 	/* override with driver methods */
3015 	bvp->bv_newstate = vap->iv_newstate;
3016 	vap->iv_newstate = bwn_newstate;
3017 
3018 	/* override max aid so sta's cannot assoc when we're out of sta id's */
3019 	vap->iv_max_aid = BWN_STAID_MAX;
3020 
3021 	ieee80211_amrr_init(&bvp->bv_amrr, vap,
3022 	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
3023 	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
3024 	    500 /*ms*/);
3025 
3026 	/* complete setup */
3027 	ieee80211_vap_attach(vap, ieee80211_media_change,
3028 	    ieee80211_media_status);
3029 	return (vap);
3030 }
3031 
3032 static void
3033 bwn_vap_delete(struct ieee80211vap *vap)
3034 {
3035 	struct bwn_vap *bvp = BWN_VAP(vap);
3036 
3037 	ieee80211_amrr_cleanup(&bvp->bv_amrr);
3038 	ieee80211_vap_detach(vap);
3039 	free(bvp, M_80211_VAP);
3040 }
3041 
3042 static void
3043 bwn_init(void *arg)
3044 {
3045 	struct bwn_softc *sc = arg;
3046 	struct ifnet *ifp = sc->sc_ifp;
3047 	struct ieee80211com *ic = ifp->if_l2com;
3048 	int error = 0;
3049 
3050 	DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3051 		__func__, ifp->if_flags);
3052 
3053 	BWN_LOCK(sc);
3054 	error = bwn_init_locked(sc);
3055 	BWN_UNLOCK(sc);
3056 
3057 	if (error == 0)
3058 		ieee80211_start_all(ic);	/* start all vap's */
3059 }
3060 
3061 static int
3062 bwn_init_locked(struct bwn_softc *sc)
3063 {
3064 	struct bwn_mac *mac;
3065 	struct ifnet *ifp = sc->sc_ifp;
3066 	int error;
3067 
3068 	BWN_ASSERT_LOCKED(sc);
3069 
3070 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3071 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3072 	sc->sc_filters = 0;
3073 	bwn_wme_clear(sc);
3074 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3075 	sc->sc_rf_enabled = 1;
3076 
3077 	mac = sc->sc_curmac;
3078 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3079 		error = bwn_core_init(mac);
3080 		if (error != 0)
3081 			return (error);
3082 	}
3083 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
3084 		bwn_core_start(mac);
3085 
3086 	bwn_set_opmode(mac);
3087 	bwn_set_pretbtt(mac);
3088 	bwn_spu_setdelay(mac, 0);
3089 	bwn_set_macaddr(mac);
3090 
3091 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
3092 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3093 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3094 
3095 	return (0);
3096 }
3097 
3098 static void
3099 bwn_stop(struct bwn_softc *sc, int statechg)
3100 {
3101 
3102 	BWN_LOCK(sc);
3103 	bwn_stop_locked(sc, statechg);
3104 	BWN_UNLOCK(sc);
3105 }
3106 
3107 static void
3108 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3109 {
3110 	struct bwn_mac *mac = sc->sc_curmac;
3111 	struct ifnet *ifp = sc->sc_ifp;
3112 
3113 	BWN_ASSERT_LOCKED(sc);
3114 
3115 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3116 		/* XXX FIXME opmode not based on VAP */
3117 		bwn_set_opmode(mac);
3118 		bwn_set_macaddr(mac);
3119 	}
3120 
3121 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3122 		bwn_core_stop(mac);
3123 
3124 	callout_stop(&sc->sc_led_blink_ch);
3125 	sc->sc_led_blinking = 0;
3126 
3127 	bwn_core_exit(mac);
3128 	sc->sc_rf_enabled = 0;
3129 
3130 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3131 }
3132 
3133 static void
3134 bwn_wme_clear(struct bwn_softc *sc)
3135 {
3136 #define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
3137 	struct wmeParams *p;
3138 	unsigned int i;
3139 
3140 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3141 	    ("%s:%d: fail", __func__, __LINE__));
3142 
3143 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
3144 		p = &(sc->sc_wmeParams[i]);
3145 
3146 		switch (bwn_wme_shm_offsets[i]) {
3147 		case BWN_WME_VOICE:
3148 			p->wmep_txopLimit = 0;
3149 			p->wmep_aifsn = 2;
3150 			/* XXX FIXME: log2(cwmin) */
3151 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3152 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3153 			break;
3154 		case BWN_WME_VIDEO:
3155 			p->wmep_txopLimit = 0;
3156 			p->wmep_aifsn = 2;
3157 			/* XXX FIXME: log2(cwmin) */
3158 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3159 			p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3160 			break;
3161 		case BWN_WME_BESTEFFORT:
3162 			p->wmep_txopLimit = 0;
3163 			p->wmep_aifsn = 3;
3164 			/* XXX FIXME: log2(cwmin) */
3165 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3166 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3167 			break;
3168 		case BWN_WME_BACKGROUND:
3169 			p->wmep_txopLimit = 0;
3170 			p->wmep_aifsn = 7;
3171 			/* XXX FIXME: log2(cwmin) */
3172 			p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3173 			p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3174 			break;
3175 		default:
3176 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3177 		}
3178 	}
3179 }
3180 
3181 static int
3182 bwn_core_init(struct bwn_mac *mac)
3183 {
3184 #ifdef BWN_DEBUG
3185 	struct bwn_softc *sc = mac->mac_sc;
3186 #endif
3187 	struct siba_dev_softc *sd = mac->mac_sd;
3188 	struct siba_softc *siba = sd->sd_bus;
3189 	struct siba_sprom *sprom = &siba->siba_sprom;
3190 	uint64_t hf;
3191 	int error;
3192 
3193 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3194 	    ("%s:%d: fail", __func__, __LINE__));
3195 
3196 	siba_powerup(siba, 0);
3197 	if (!siba_dev_isup(sd))
3198 		bwn_reset_core(mac,
3199 		    mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3200 
3201 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3202 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3203 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3204 	BWN_GETTIME(mac->mac_phy.nexttime);
3205 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3206 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3207 	mac->mac_stats.link_noise = -95;
3208 	mac->mac_reason_intr = 0;
3209 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
3210 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3211 #ifdef BWN_DEBUG
3212 	if (sc->sc_debug & BWN_DEBUG_XMIT)
3213 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3214 #endif
3215 	mac->mac_suspended = 1;
3216 	mac->mac_task_state = 0;
3217 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3218 
3219 	mac->mac_phy.init_pre(mac);
3220 
3221 	siba_pcicore_intr(&siba->siba_pci, sd);
3222 
3223 	bwn_fix_imcfglobug(mac);
3224 	bwn_bt_disable(mac);
3225 	if (mac->mac_phy.prepare_hw) {
3226 		error = mac->mac_phy.prepare_hw(mac);
3227 		if (error)
3228 			goto fail0;
3229 	}
3230 	error = bwn_chip_init(mac);
3231 	if (error)
3232 		goto fail0;
3233 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3234 	    mac->mac_sd->sd_id.sd_rev);
3235 	hf = bwn_hf_read(mac);
3236 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3237 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3238 		if (sprom->bf_lo & BWN_BFL_PACTRL)
3239 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3240 		if (mac->mac_phy.rev == 1)
3241 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3242 	}
3243 	if (mac->mac_phy.rf_ver == 0x2050) {
3244 		if (mac->mac_phy.rf_rev < 6)
3245 			hf |= BWN_HF_FORCE_VCO_RECALC;
3246 		if (mac->mac_phy.rf_rev == 6)
3247 			hf |= BWN_HF_4318_TSSI;
3248 	}
3249 	if (sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW)
3250 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3251 	if ((siba->siba_type == SIBA_TYPE_PCI) &&
3252 	    (siba->siba_pci.spc_dev->sd_id.sd_rev <= 10))
3253 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3254 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3255 	bwn_hf_write(mac, hf);
3256 
3257 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3258 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3259 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3260 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3261 
3262 	bwn_rate_init(mac);
3263 	bwn_set_phytxctl(mac);
3264 
3265 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3266 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3267 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3268 
3269 	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3270 		bwn_pio_init(mac);
3271 	else
3272 		bwn_dma_init(mac);
3273 	if (error)
3274 		goto fail1;
3275 	bwn_wme_init(mac);
3276 	bwn_spu_setdelay(mac, 1);
3277 	bwn_bt_enable(mac);
3278 
3279 	siba_powerup(siba, !(sprom->bf_lo & BWN_BFL_CRYSTAL_NOSLOW));
3280 	bwn_set_macaddr(mac);
3281 	bwn_crypt_init(mac);
3282 
3283 	/* XXX LED initializatin */
3284 
3285 	mac->mac_status = BWN_MAC_STATUS_INITED;
3286 
3287 	return (error);
3288 
3289 fail1:
3290 	bwn_chip_exit(mac);
3291 fail0:
3292 	siba_powerdown(siba);
3293 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3294 	    ("%s:%d: fail", __func__, __LINE__));
3295 	return (error);
3296 }
3297 
3298 static void
3299 bwn_core_start(struct bwn_mac *mac)
3300 {
3301 	struct bwn_softc *sc = mac->mac_sc;
3302 	uint32_t tmp;
3303 
3304 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3305 	    ("%s:%d: fail", __func__, __LINE__));
3306 
3307 	if (mac->mac_sd->sd_id.sd_rev < 5)
3308 		return;
3309 
3310 	while (1) {
3311 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3312 		if (!(tmp & 0x00000001))
3313 			break;
3314 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3315 	}
3316 
3317 	bwn_mac_enable(mac);
3318 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3319 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3320 
3321 	mac->mac_status = BWN_MAC_STATUS_STARTED;
3322 }
3323 
3324 static void
3325 bwn_core_exit(struct bwn_mac *mac)
3326 {
3327 	uint32_t macctl;
3328 
3329 	BWN_ASSERT_LOCKED(mac->mac_sc);
3330 
3331 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3332 	    ("%s:%d: fail", __func__, __LINE__));
3333 
3334 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
3335 		return;
3336 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
3337 
3338 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3339 	macctl &= ~BWN_MACCTL_MCODE_RUN;
3340 	macctl |= BWN_MACCTL_MCODE_JMP0;
3341 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3342 
3343 	bwn_dma_stop(mac);
3344 	bwn_pio_stop(mac);
3345 	bwn_chip_exit(mac);
3346 	mac->mac_phy.switch_analog(mac, 0);
3347 	siba_dev_down(mac->mac_sd, 0);
3348 	siba_powerdown(mac->mac_sd->sd_bus);
3349 }
3350 
3351 static void
3352 bwn_fix_imcfglobug(struct bwn_mac *mac)
3353 {
3354 	struct siba_dev_softc *sd = mac->mac_sd;
3355 	struct siba_softc *siba = sd->sd_bus;
3356 	uint32_t tmp;
3357 
3358 	if (siba->siba_pci.spc_dev == NULL)
3359 		return;
3360 	if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI ||
3361 	    siba->siba_pci.spc_dev->sd_id.sd_rev > 5)
3362 		return;
3363 
3364 	tmp = siba_read_4(sd, SIBA_IMCFGLO) &
3365 	    ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO);
3366 	switch (siba->siba_type) {
3367 	case SIBA_TYPE_PCI:
3368 	case SIBA_TYPE_PCMCIA:
3369 		tmp |= 0x32;
3370 		break;
3371 	case SIBA_TYPE_SSB:
3372 		tmp |= 0x53;
3373 		break;
3374 	}
3375 	siba_write_4(sd, SIBA_IMCFGLO, tmp);
3376 }
3377 
3378 static void
3379 bwn_bt_disable(struct bwn_mac *mac)
3380 {
3381 	struct bwn_softc *sc = mac->mac_sc;
3382 
3383 	(void)sc;
3384 	/* XXX do nothing yet */
3385 }
3386 
3387 static int
3388 bwn_chip_init(struct bwn_mac *mac)
3389 {
3390 	struct bwn_phy *phy = &mac->mac_phy;
3391 	uint32_t macctl;
3392 	int error;
3393 
3394 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3395 	if (phy->gmode)
3396 		macctl |= BWN_MACCTL_GMODE;
3397 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3398 
3399 	error = bwn_fw_fillinfo(mac);
3400 	if (error)
3401 		return (error);
3402 	error = bwn_fw_loaducode(mac);
3403 	if (error)
3404 		return (error);
3405 
3406 	error = bwn_gpio_init(mac);
3407 	if (error)
3408 		return (error);
3409 
3410 	error = bwn_fw_loadinitvals(mac);
3411 	if (error) {
3412 		bwn_gpio_cleanup(mac);
3413 		return (error);
3414 	}
3415 	phy->switch_analog(mac, 1);
3416 	error = bwn_phy_init(mac);
3417 	if (error) {
3418 		bwn_gpio_cleanup(mac);
3419 		return (error);
3420 	}
3421 	if (phy->set_im)
3422 		phy->set_im(mac, BWN_IMMODE_NONE);
3423 	if (phy->set_antenna)
3424 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
3425 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3426 
3427 	if (phy->type == BWN_PHYTYPE_B)
3428 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3429 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
3430 	if (mac->mac_sd->sd_id.sd_rev < 5)
3431 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
3432 
3433 	BWN_WRITE_4(mac, BWN_MACCTL,
3434 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3435 	BWN_WRITE_4(mac, BWN_MACCTL,
3436 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3437 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3438 
3439 	bwn_set_opmode(mac);
3440 	if (mac->mac_sd->sd_id.sd_rev < 3) {
3441 		BWN_WRITE_2(mac, 0x060e, 0x0000);
3442 		BWN_WRITE_2(mac, 0x0610, 0x8000);
3443 		BWN_WRITE_2(mac, 0x0604, 0x0000);
3444 		BWN_WRITE_2(mac, 0x0606, 0x0200);
3445 	} else {
3446 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
3447 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
3448 	}
3449 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3450 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3451 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3452 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3453 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3454 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3455 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3456 	siba_write_4(mac->mac_sd, SIBA_TGSLOW,
3457 	    siba_read_4(mac->mac_sd, SIBA_TGSLOW) | 0x00100000);
3458 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY,
3459 	    mac->mac_sd->sd_bus->siba_cc.scc_powerup_delay);
3460 	return (error);
3461 }
3462 
3463 /* read hostflags */
3464 static uint64_t
3465 bwn_hf_read(struct bwn_mac *mac)
3466 {
3467 	uint64_t ret;
3468 
3469 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3470 	ret <<= 16;
3471 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3472 	ret <<= 16;
3473 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3474 	return (ret);
3475 }
3476 
3477 static void
3478 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3479 {
3480 
3481 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3482 	    (value & 0x00000000ffffull));
3483 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3484 	    (value & 0x0000ffff0000ull) >> 16);
3485 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3486 	    (value & 0xffff00000000ULL) >> 32);
3487 }
3488 
3489 static void
3490 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3491 {
3492 
3493 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3494 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3495 }
3496 
3497 static void
3498 bwn_rate_init(struct bwn_mac *mac)
3499 {
3500 
3501 	switch (mac->mac_phy.type) {
3502 	case BWN_PHYTYPE_A:
3503 	case BWN_PHYTYPE_G:
3504 	case BWN_PHYTYPE_LP:
3505 	case BWN_PHYTYPE_N:
3506 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3507 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3508 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3509 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3510 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3511 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3512 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3513 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
3514 			break;
3515 		/* FALLTHROUGH */
3516 	case BWN_PHYTYPE_B:
3517 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3518 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3519 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3520 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3521 		break;
3522 	default:
3523 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3524 	}
3525 }
3526 
3527 static void
3528 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3529 {
3530 	uint16_t offset;
3531 
3532 	if (ofdm) {
3533 		offset = 0x480;
3534 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3535 	} else {
3536 		offset = 0x4c0;
3537 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3538 	}
3539 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3540 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
3541 }
3542 
3543 static uint8_t
3544 bwn_plcp_getcck(const uint8_t bitrate)
3545 {
3546 
3547 	switch (bitrate) {
3548 	case BWN_CCK_RATE_1MB:
3549 		return (0x0a);
3550 	case BWN_CCK_RATE_2MB:
3551 		return (0x14);
3552 	case BWN_CCK_RATE_5MB:
3553 		return (0x37);
3554 	case BWN_CCK_RATE_11MB:
3555 		return (0x6e);
3556 	}
3557 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3558 	return (0);
3559 }
3560 
3561 static uint8_t
3562 bwn_plcp_getofdm(const uint8_t bitrate)
3563 {
3564 
3565 	switch (bitrate) {
3566 	case BWN_OFDM_RATE_6MB:
3567 		return (0xb);
3568 	case BWN_OFDM_RATE_9MB:
3569 		return (0xf);
3570 	case BWN_OFDM_RATE_12MB:
3571 		return (0xa);
3572 	case BWN_OFDM_RATE_18MB:
3573 		return (0xe);
3574 	case BWN_OFDM_RATE_24MB:
3575 		return (0x9);
3576 	case BWN_OFDM_RATE_36MB:
3577 		return (0xd);
3578 	case BWN_OFDM_RATE_48MB:
3579 		return (0x8);
3580 	case BWN_OFDM_RATE_54MB:
3581 		return (0xc);
3582 	}
3583 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3584 	return (0);
3585 }
3586 
3587 static void
3588 bwn_set_phytxctl(struct bwn_mac *mac)
3589 {
3590 	uint16_t ctl;
3591 
3592 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3593 	    BWN_TX_PHY_TXPWR);
3594 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3595 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3596 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3597 }
3598 
3599 static void
3600 bwn_pio_init(struct bwn_mac *mac)
3601 {
3602 	struct bwn_pio *pio = &mac->mac_method.pio;
3603 
3604 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3605 	    & ~BWN_MACCTL_BIGENDIAN);
3606 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3607 
3608 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3609 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3610 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3611 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3612 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3613 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3614 }
3615 
3616 static void
3617 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3618     int index)
3619 {
3620 	struct bwn_pio_txpkt *tp;
3621 	unsigned int i;
3622 
3623 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3624 	tq->tq_index = index;
3625 
3626 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3627 	if (mac->mac_sd->sd_id.sd_rev >= 8)
3628 		tq->tq_size = 1920;
3629 	else {
3630 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3631 		tq->tq_size -= 80;
3632 	}
3633 
3634 	TAILQ_INIT(&tq->tq_pktlist);
3635 	for (i = 0; i < N(tq->tq_pkts); i++) {
3636 		tp = &(tq->tq_pkts[i]);
3637 		tp->tp_index = i;
3638 		tp->tp_queue = tq;
3639 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3640 	}
3641 }
3642 
3643 static uint16_t
3644 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3645 {
3646 	struct bwn_softc *sc = mac->mac_sc;
3647 	static const uint16_t bases[] = {
3648 		BWN_PIO_BASE0,
3649 		BWN_PIO_BASE1,
3650 		BWN_PIO_BASE2,
3651 		BWN_PIO_BASE3,
3652 		BWN_PIO_BASE4,
3653 		BWN_PIO_BASE5,
3654 		BWN_PIO_BASE6,
3655 		BWN_PIO_BASE7,
3656 	};
3657 	static const uint16_t bases_rev11[] = {
3658 		BWN_PIO11_BASE0,
3659 		BWN_PIO11_BASE1,
3660 		BWN_PIO11_BASE2,
3661 		BWN_PIO11_BASE3,
3662 		BWN_PIO11_BASE4,
3663 		BWN_PIO11_BASE5,
3664 	};
3665 
3666 	if (mac->mac_sd->sd_id.sd_rev >= 11) {
3667 		if (index >= N(bases_rev11))
3668 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
3669 		return (bases_rev11[index]);
3670 	}
3671 	if (index >= N(bases))
3672 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
3673 	return (bases[index]);
3674 }
3675 
3676 static void
3677 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3678     int index)
3679 {
3680 
3681 	prq->prq_mac = mac;
3682 	prq->prq_rev = mac->mac_sd->sd_id.sd_rev;
3683 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3684 	bwn_dma_rxdirectfifo(mac, index, 1);
3685 }
3686 
3687 static void
3688 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3689 {
3690 	if (tq == NULL)
3691 		return;
3692 	bwn_pio_cancel_tx_packets(tq);
3693 }
3694 
3695 static void
3696 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3697 {
3698 
3699 	bwn_destroy_pioqueue_tx(pio);
3700 }
3701 
3702 static uint16_t
3703 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3704     uint16_t offset)
3705 {
3706 
3707 	return (BWN_READ_2(mac, tq->tq_base + offset));
3708 }
3709 
3710 static void
3711 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3712 {
3713 	uint32_t ctl;
3714 	int type;
3715 	uint16_t base;
3716 
3717 	type = bwn_dma_mask2type(bwn_dma_mask(mac));
3718 	base = bwn_dma_base(type, idx);
3719 	if (type == BWN_DMA_64BIT) {
3720 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3721 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3722 		if (enable)
3723 			ctl |= BWN_DMA64_RXDIRECTFIFO;
3724 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3725 	} else {
3726 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3727 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3728 		if (enable)
3729 			ctl |= BWN_DMA32_RXDIRECTFIFO;
3730 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3731 	}
3732 }
3733 
3734 static uint64_t
3735 bwn_dma_mask(struct bwn_mac *mac)
3736 {
3737 	uint32_t tmp;
3738 	uint16_t base;
3739 
3740 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3741 	if (tmp & SIBA_TGSHIGH_DMA64)
3742 		return (BWN_DMA_BIT_MASK(64));
3743 	base = bwn_dma_base(0, 0);
3744 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3745 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3746 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
3747 		return (BWN_DMA_BIT_MASK(32));
3748 
3749 	return (BWN_DMA_BIT_MASK(30));
3750 }
3751 
3752 static int
3753 bwn_dma_mask2type(uint64_t dmamask)
3754 {
3755 
3756 	if (dmamask == BWN_DMA_BIT_MASK(30))
3757 		return (BWN_DMA_30BIT);
3758 	if (dmamask == BWN_DMA_BIT_MASK(32))
3759 		return (BWN_DMA_32BIT);
3760 	if (dmamask == BWN_DMA_BIT_MASK(64))
3761 		return (BWN_DMA_64BIT);
3762 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3763 	return (BWN_DMA_30BIT);
3764 }
3765 
3766 static void
3767 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3768 {
3769 	struct bwn_pio_txpkt *tp;
3770 	unsigned int i;
3771 
3772 	for (i = 0; i < N(tq->tq_pkts); i++) {
3773 		tp = &(tq->tq_pkts[i]);
3774 		if (tp->tp_m) {
3775 			m_freem(tp->tp_m);
3776 			tp->tp_m = NULL;
3777 		}
3778 	}
3779 }
3780 
3781 static uint16_t
3782 bwn_dma_base(int type, int controller_idx)
3783 {
3784 	static const uint16_t map64[] = {
3785 		BWN_DMA64_BASE0,
3786 		BWN_DMA64_BASE1,
3787 		BWN_DMA64_BASE2,
3788 		BWN_DMA64_BASE3,
3789 		BWN_DMA64_BASE4,
3790 		BWN_DMA64_BASE5,
3791 	};
3792 	static const uint16_t map32[] = {
3793 		BWN_DMA32_BASE0,
3794 		BWN_DMA32_BASE1,
3795 		BWN_DMA32_BASE2,
3796 		BWN_DMA32_BASE3,
3797 		BWN_DMA32_BASE4,
3798 		BWN_DMA32_BASE5,
3799 	};
3800 
3801 	if (type == BWN_DMA_64BIT) {
3802 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3803 		    ("%s:%d: fail", __func__, __LINE__));
3804 		return (map64[controller_idx]);
3805 	}
3806 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3807 	    ("%s:%d: fail", __func__, __LINE__));
3808 	return (map32[controller_idx]);
3809 }
3810 
3811 static void
3812 bwn_dma_init(struct bwn_mac *mac)
3813 {
3814 	struct bwn_dma *dma = &mac->mac_method.dma;
3815 
3816 	/* setup TX DMA channels. */
3817 	bwn_dma_setup(dma->wme[WME_AC_BK]);
3818 	bwn_dma_setup(dma->wme[WME_AC_BE]);
3819 	bwn_dma_setup(dma->wme[WME_AC_VI]);
3820 	bwn_dma_setup(dma->wme[WME_AC_VO]);
3821 	bwn_dma_setup(dma->mcast);
3822 	/* setup RX DMA channel. */
3823 	bwn_dma_setup(dma->rx);
3824 }
3825 
3826 static struct bwn_dma_ring *
3827 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3828     int for_tx, int type)
3829 {
3830 	struct bwn_dma *dma = &mac->mac_method.dma;
3831 	struct bwn_dma_ring *dr;
3832 	struct bwn_dmadesc_generic *desc;
3833 	struct bwn_dmadesc_meta *mt;
3834 	struct bwn_softc *sc = mac->mac_sc;
3835 	int error, i;
3836 
3837 	dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3838 	if (dr == NULL)
3839 		goto out;
3840 	dr->dr_numslots = BWN_RXRING_SLOTS;
3841 	if (for_tx)
3842 		dr->dr_numslots = BWN_TXRING_SLOTS;
3843 
3844 	dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3845 	    M_DEVBUF, M_NOWAIT | M_ZERO);
3846 	if (dr->dr_meta == NULL)
3847 		goto fail0;
3848 
3849 	dr->dr_type = type;
3850 	dr->dr_mac = mac;
3851 	dr->dr_base = bwn_dma_base(type, controller_index);
3852 	dr->dr_index = controller_index;
3853 	if (type == BWN_DMA_64BIT) {
3854 		dr->getdesc = bwn_dma_64_getdesc;
3855 		dr->setdesc = bwn_dma_64_setdesc;
3856 		dr->start_transfer = bwn_dma_64_start_transfer;
3857 		dr->suspend = bwn_dma_64_suspend;
3858 		dr->resume = bwn_dma_64_resume;
3859 		dr->get_curslot = bwn_dma_64_get_curslot;
3860 		dr->set_curslot = bwn_dma_64_set_curslot;
3861 	} else {
3862 		dr->getdesc = bwn_dma_32_getdesc;
3863 		dr->setdesc = bwn_dma_32_setdesc;
3864 		dr->start_transfer = bwn_dma_32_start_transfer;
3865 		dr->suspend = bwn_dma_32_suspend;
3866 		dr->resume = bwn_dma_32_resume;
3867 		dr->get_curslot = bwn_dma_32_get_curslot;
3868 		dr->set_curslot = bwn_dma_32_set_curslot;
3869 	}
3870 	if (for_tx) {
3871 		dr->dr_tx = 1;
3872 		dr->dr_curslot = -1;
3873 	} else {
3874 		if (dr->dr_index == 0) {
3875 			dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3876 			dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3877 		} else
3878 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3879 	}
3880 
3881 	error = bwn_dma_allocringmemory(dr);
3882 	if (error)
3883 		goto fail2;
3884 
3885 	if (for_tx) {
3886 		/*
3887 		 * Assumption: BWN_TXRING_SLOTS can be divided by
3888 		 * BWN_TX_SLOTS_PER_FRAME
3889 		 */
3890 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3891 		    ("%s:%d: fail", __func__, __LINE__));
3892 
3893 		dr->dr_txhdr_cache =
3894 		    malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3895 			BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3896 		KASSERT(dr->dr_txhdr_cache != NULL,
3897 		    ("%s:%d: fail", __func__, __LINE__));
3898 
3899 		/*
3900 		 * Create TX ring DMA stuffs
3901 		 */
3902 		error = bus_dma_tag_create(dma->parent_dtag,
3903 				    BWN_ALIGN, 0,
3904 				    BUS_SPACE_MAXADDR,
3905 				    BUS_SPACE_MAXADDR,
3906 				    NULL, NULL,
3907 				    BWN_HDRSIZE(mac),
3908 				    1,
3909 				    BUS_SPACE_MAXSIZE_32BIT,
3910 				    0,
3911 				    NULL, NULL,
3912 				    &dr->dr_txring_dtag);
3913 		if (error) {
3914 			device_printf(sc->sc_dev,
3915 			    "can't create TX ring DMA tag: TODO frees\n");
3916 			goto fail1;
3917 		}
3918 
3919 		for (i = 0; i < dr->dr_numslots; i += 2) {
3920 			dr->getdesc(dr, i, &desc, &mt);
3921 
3922 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3923 			mt->mt_m = NULL;
3924 			mt->mt_ni = NULL;
3925 			mt->mt_islast = 0;
3926 			error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3927 			    &mt->mt_dmap);
3928 			if (error) {
3929 				device_printf(sc->sc_dev,
3930 				     "can't create RX buf DMA map\n");
3931 				goto fail1;
3932 			}
3933 
3934 			dr->getdesc(dr, i + 1, &desc, &mt);
3935 
3936 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3937 			mt->mt_m = NULL;
3938 			mt->mt_ni = NULL;
3939 			mt->mt_islast = 1;
3940 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
3941 			    &mt->mt_dmap);
3942 			if (error) {
3943 				device_printf(sc->sc_dev,
3944 				     "can't create RX buf DMA map\n");
3945 				goto fail1;
3946 			}
3947 		}
3948 	} else {
3949 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3950 		    &dr->dr_spare_dmap);
3951 		if (error) {
3952 			device_printf(sc->sc_dev,
3953 			    "can't create RX buf DMA map\n");
3954 			goto out;		/* XXX wrong! */
3955 		}
3956 
3957 		for (i = 0; i < dr->dr_numslots; i++) {
3958 			dr->getdesc(dr, i, &desc, &mt);
3959 
3960 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3961 			    &mt->mt_dmap);
3962 			if (error) {
3963 				device_printf(sc->sc_dev,
3964 				    "can't create RX buf DMA map\n");
3965 				goto out;	/* XXX wrong! */
3966 			}
3967 			error = bwn_dma_newbuf(dr, desc, mt, 1);
3968 			if (error) {
3969 				device_printf(sc->sc_dev,
3970 				    "failed to allocate RX buf\n");
3971 				goto out;	/* XXX wrong! */
3972 			}
3973 		}
3974 
3975 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3976 		    BUS_DMASYNC_PREWRITE);
3977 
3978 		dr->dr_usedslot = dr->dr_numslots;
3979 	}
3980 
3981       out:
3982 	return (dr);
3983 
3984 fail2:
3985 	free(dr->dr_txhdr_cache, M_DEVBUF);
3986 fail1:
3987 	free(dr->dr_meta, M_DEVBUF);
3988 fail0:
3989 	free(dr, M_DEVBUF);
3990 	return (NULL);
3991 }
3992 
3993 static void
3994 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3995 {
3996 
3997 	if (dr == NULL)
3998 		return;
3999 
4000 	bwn_dma_free_descbufs(*dr);
4001 	bwn_dma_free_ringmemory(*dr);
4002 
4003 	free((*dr)->dr_txhdr_cache, M_DEVBUF);
4004 	free((*dr)->dr_meta, M_DEVBUF);
4005 	free(*dr, M_DEVBUF);
4006 
4007 	*dr = NULL;
4008 }
4009 
4010 static void
4011 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
4012     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4013 {
4014 	struct bwn_dmadesc32 *desc;
4015 
4016 	*meta = &(dr->dr_meta[slot]);
4017 	desc = dr->dr_ring_descbase;
4018 	desc = &(desc[slot]);
4019 
4020 	*gdesc = (struct bwn_dmadesc_generic *)desc;
4021 }
4022 
4023 static void
4024 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
4025     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4026     int start, int end, int irq)
4027 {
4028 	struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
4029 	uint32_t addr, addrext, ctl;
4030 	int slot;
4031 
4032 	slot = (int)(&(desc->dma.dma32) - descbase);
4033 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
4034 	    ("%s:%d: fail", __func__, __LINE__));
4035 
4036 	addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
4037 	addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
4038 	addr |= siba_dma_translation(dr->dr_mac->mac_sd);
4039 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
4040 	if (slot == dr->dr_numslots - 1)
4041 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
4042 	if (start)
4043 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
4044 	if (end)
4045 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
4046 	if (irq)
4047 		ctl |= BWN_DMA32_DCTL_IRQ;
4048 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
4049 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
4050 
4051 	desc->dma.dma32.control = htole32(ctl);
4052 	desc->dma.dma32.address = htole32(addr);
4053 }
4054 
4055 static void
4056 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
4057 {
4058 
4059 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
4060 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
4061 }
4062 
4063 static void
4064 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
4065 {
4066 
4067 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4068 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
4069 }
4070 
4071 static void
4072 bwn_dma_32_resume(struct bwn_dma_ring *dr)
4073 {
4074 
4075 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4076 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
4077 }
4078 
4079 static int
4080 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4081 {
4082 	uint32_t val;
4083 
4084 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4085 	val &= BWN_DMA32_RXDPTR;
4086 
4087 	return (val / sizeof(struct bwn_dmadesc32));
4088 }
4089 
4090 static void
4091 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4092 {
4093 
4094 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4095 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4096 }
4097 
4098 static void
4099 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4100     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4101 {
4102 	struct bwn_dmadesc64 *desc;
4103 
4104 	*meta = &(dr->dr_meta[slot]);
4105 	desc = dr->dr_ring_descbase;
4106 	desc = &(desc[slot]);
4107 
4108 	*gdesc = (struct bwn_dmadesc_generic *)desc;
4109 }
4110 
4111 static void
4112 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4113     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4114     int start, int end, int irq)
4115 {
4116 	struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4117 	int slot;
4118 	uint32_t ctl0 = 0, ctl1 = 0;
4119 	uint32_t addrlo, addrhi;
4120 	uint32_t addrext;
4121 
4122 	slot = (int)(&(desc->dma.dma64) - descbase);
4123 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
4124 	    ("%s:%d: fail", __func__, __LINE__));
4125 
4126 	addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4127 	addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4128 	addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4129 	    30;
4130 	addrhi |= (siba_dma_translation(dr->dr_mac->mac_sd) << 1);
4131 	if (slot == dr->dr_numslots - 1)
4132 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4133 	if (start)
4134 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4135 	if (end)
4136 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4137 	if (irq)
4138 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
4139 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4140 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4141 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
4142 
4143 	desc->dma.dma64.control0 = htole32(ctl0);
4144 	desc->dma.dma64.control1 = htole32(ctl1);
4145 	desc->dma.dma64.address_low = htole32(addrlo);
4146 	desc->dma.dma64.address_high = htole32(addrhi);
4147 }
4148 
4149 static void
4150 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4151 {
4152 
4153 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4154 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4155 }
4156 
4157 static void
4158 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4159 {
4160 
4161 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4162 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4163 }
4164 
4165 static void
4166 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4167 {
4168 
4169 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4170 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4171 }
4172 
4173 static int
4174 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4175 {
4176 	uint32_t val;
4177 
4178 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4179 	val &= BWN_DMA64_RXSTATDPTR;
4180 
4181 	return (val / sizeof(struct bwn_dmadesc64));
4182 }
4183 
4184 static void
4185 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4186 {
4187 
4188 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4189 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4190 }
4191 
4192 static int
4193 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4194 {
4195 	struct bwn_mac *mac = dr->dr_mac;
4196 	struct bwn_dma *dma = &mac->mac_method.dma;
4197 	struct bwn_softc *sc = mac->mac_sc;
4198 	int error;
4199 
4200 	error = bus_dma_tag_create(dma->parent_dtag,
4201 			    BWN_ALIGN, 0,
4202 			    BUS_SPACE_MAXADDR,
4203 			    BUS_SPACE_MAXADDR,
4204 			    NULL, NULL,
4205 			    BWN_DMA_RINGMEMSIZE,
4206 			    1,
4207 			    BUS_SPACE_MAXSIZE_32BIT,
4208 			    0,
4209 			    NULL, NULL,
4210 			    &dr->dr_ring_dtag);
4211 	if (error) {
4212 		device_printf(sc->sc_dev,
4213 		    "can't create TX ring DMA tag: TODO frees\n");
4214 		return (-1);
4215 	}
4216 
4217 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
4218 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4219 	    &dr->dr_ring_dmap);
4220 	if (error) {
4221 		device_printf(sc->sc_dev,
4222 		    "can't allocate DMA mem: TODO frees\n");
4223 		return (-1);
4224 	}
4225 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4226 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4227 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4228 	if (error) {
4229 		device_printf(sc->sc_dev,
4230 		    "can't load DMA mem: TODO free\n");
4231 		return (-1);
4232 	}
4233 
4234 	return (0);
4235 }
4236 
4237 static void
4238 bwn_dma_setup(struct bwn_dma_ring *dr)
4239 {
4240 	uint64_t ring64;
4241 	uint32_t addrext, ring32, value;
4242 	uint32_t trans = siba_dma_translation(dr->dr_mac->mac_sd);
4243 
4244 	if (dr->dr_tx) {
4245 		dr->dr_curslot = -1;
4246 
4247 		if (dr->dr_type == BWN_DMA_64BIT) {
4248 			ring64 = (uint64_t)(dr->dr_ring_dmabase);
4249 			addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4250 			    >> 30;
4251 			value = BWN_DMA64_TXENABLE;
4252 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4253 			    & BWN_DMA64_TXADDREXT_MASK;
4254 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4255 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4256 			    (ring64 & 0xffffffff));
4257 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4258 			    ((ring64 >> 32) &
4259 			    ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4260 		} else {
4261 			ring32 = (uint32_t)(dr->dr_ring_dmabase);
4262 			addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4263 			value = BWN_DMA32_TXENABLE;
4264 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4265 			    & BWN_DMA32_TXADDREXT_MASK;
4266 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4267 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4268 			    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4269 		}
4270 		return;
4271 	}
4272 
4273 	/*
4274 	 * set for RX
4275 	 */
4276 	dr->dr_usedslot = dr->dr_numslots;
4277 
4278 	if (dr->dr_type == BWN_DMA_64BIT) {
4279 		ring64 = (uint64_t)(dr->dr_ring_dmabase);
4280 		addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4281 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4282 		value |= BWN_DMA64_RXENABLE;
4283 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4284 		    & BWN_DMA64_RXADDREXT_MASK;
4285 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4286 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4287 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4288 		    ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4289 		    | (trans << 1));
4290 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4291 		    sizeof(struct bwn_dmadesc64));
4292 	} else {
4293 		ring32 = (uint32_t)(dr->dr_ring_dmabase);
4294 		addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4295 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4296 		value |= BWN_DMA32_RXENABLE;
4297 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4298 		    & BWN_DMA32_RXADDREXT_MASK;
4299 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4300 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4301 		    (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4302 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4303 		    sizeof(struct bwn_dmadesc32));
4304 	}
4305 }
4306 
4307 static void
4308 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4309 {
4310 
4311 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4312 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4313 	    dr->dr_ring_dmap);
4314 }
4315 
4316 static void
4317 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4318 {
4319 
4320 	if (dr->dr_tx) {
4321 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4322 		if (dr->dr_type == BWN_DMA_64BIT) {
4323 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4324 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4325 		} else
4326 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4327 	} else {
4328 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4329 		if (dr->dr_type == BWN_DMA_64BIT) {
4330 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4331 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4332 		} else
4333 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4334 	}
4335 }
4336 
4337 static void
4338 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4339 {
4340 	struct bwn_dmadesc_generic *desc;
4341 	struct bwn_dmadesc_meta *meta;
4342 	struct bwn_mac *mac = dr->dr_mac;
4343 	struct bwn_dma *dma = &mac->mac_method.dma;
4344 	struct bwn_softc *sc = mac->mac_sc;
4345 	int i;
4346 
4347 	if (!dr->dr_usedslot)
4348 		return;
4349 	for (i = 0; i < dr->dr_numslots; i++) {
4350 		dr->getdesc(dr, i, &desc, &meta);
4351 
4352 		if (meta->mt_m == NULL) {
4353 			if (!dr->dr_tx)
4354 				device_printf(sc->sc_dev, "%s: not TX?\n",
4355 				    __func__);
4356 			continue;
4357 		}
4358 		if (dr->dr_tx) {
4359 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4360 				bus_dmamap_unload(dr->dr_txring_dtag,
4361 				    meta->mt_dmap);
4362 			else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4363 				bus_dmamap_unload(dma->txbuf_dtag,
4364 				    meta->mt_dmap);
4365 		} else
4366 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4367 		bwn_dma_free_descbuf(dr, meta);
4368 	}
4369 }
4370 
4371 static int
4372 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4373     int type)
4374 {
4375 	struct bwn_softc *sc = mac->mac_sc;
4376 	uint32_t value;
4377 	int i;
4378 	uint16_t offset;
4379 
4380 	for (i = 0; i < 10; i++) {
4381 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4382 		    BWN_DMA32_TXSTATUS;
4383 		value = BWN_READ_4(mac, base + offset);
4384 		if (type == BWN_DMA_64BIT) {
4385 			value &= BWN_DMA64_TXSTAT;
4386 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
4387 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4388 			    value == BWN_DMA64_TXSTAT_STOPPED)
4389 				break;
4390 		} else {
4391 			value &= BWN_DMA32_TXSTATE;
4392 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
4393 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4394 			    value == BWN_DMA32_TXSTAT_STOPPED)
4395 				break;
4396 		}
4397 		DELAY(1000);
4398 	}
4399 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4400 	BWN_WRITE_4(mac, base + offset, 0);
4401 	for (i = 0; i < 10; i++) {
4402 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4403 						   BWN_DMA32_TXSTATUS;
4404 		value = BWN_READ_4(mac, base + offset);
4405 		if (type == BWN_DMA_64BIT) {
4406 			value &= BWN_DMA64_TXSTAT;
4407 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
4408 				i = -1;
4409 				break;
4410 			}
4411 		} else {
4412 			value &= BWN_DMA32_TXSTATE;
4413 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
4414 				i = -1;
4415 				break;
4416 			}
4417 		}
4418 		DELAY(1000);
4419 	}
4420 	if (i != -1) {
4421 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4422 		return (ENODEV);
4423 	}
4424 	DELAY(1000);
4425 
4426 	return (0);
4427 }
4428 
4429 static int
4430 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4431     int type)
4432 {
4433 	struct bwn_softc *sc = mac->mac_sc;
4434 	uint32_t value;
4435 	int i;
4436 	uint16_t offset;
4437 
4438 	offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4439 	BWN_WRITE_4(mac, base + offset, 0);
4440 	for (i = 0; i < 10; i++) {
4441 		offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4442 		    BWN_DMA32_RXSTATUS;
4443 		value = BWN_READ_4(mac, base + offset);
4444 		if (type == BWN_DMA_64BIT) {
4445 			value &= BWN_DMA64_RXSTAT;
4446 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
4447 				i = -1;
4448 				break;
4449 			}
4450 		} else {
4451 			value &= BWN_DMA32_RXSTATE;
4452 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
4453 				i = -1;
4454 				break;
4455 			}
4456 		}
4457 		DELAY(1000);
4458 	}
4459 	if (i != -1) {
4460 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4461 		return (ENODEV);
4462 	}
4463 
4464 	return (0);
4465 }
4466 
4467 static void
4468 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4469     struct bwn_dmadesc_meta *meta)
4470 {
4471 
4472 	if (meta->mt_m != NULL) {
4473 		m_freem(meta->mt_m);
4474 		meta->mt_m = NULL;
4475 	}
4476 	if (meta->mt_ni != NULL) {
4477 		ieee80211_free_node(meta->mt_ni);
4478 		meta->mt_ni = NULL;
4479 	}
4480 }
4481 
4482 static void
4483 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4484 {
4485 	struct bwn_rxhdr4 *rxhdr;
4486 	unsigned char *frame;
4487 
4488 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
4489 	rxhdr->frame_len = 0;
4490 
4491 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4492 	    sizeof(struct bwn_plcp6) + 2,
4493 	    ("%s:%d: fail", __func__, __LINE__));
4494 	frame = mtod(m, char *) + dr->dr_frameoffset;
4495 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4496 }
4497 
4498 static uint8_t
4499 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4500 {
4501 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4502 
4503 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4504 	    == 0xff);
4505 }
4506 
4507 static void
4508 bwn_wme_init(struct bwn_mac *mac)
4509 {
4510 
4511 	bwn_wme_load(mac);
4512 
4513 	/* enable WME support. */
4514 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4515 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4516 	    BWN_IFSCTL_USE_EDCF);
4517 }
4518 
4519 static void
4520 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4521 {
4522 	struct bwn_softc *sc = mac->mac_sc;
4523 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4524 	uint16_t delay;	/* microsec */
4525 
4526 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4527 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4528 		delay = 500;
4529 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4530 		delay = max(delay, (uint16_t)2400);
4531 
4532 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4533 }
4534 
4535 static void
4536 bwn_bt_enable(struct bwn_mac *mac)
4537 {
4538 	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
4539 	uint64_t hf;
4540 
4541 	if (bwn_bluetooth == 0)
4542 		return;
4543 	if ((sprom->bf_lo & BWN_BFL_BTCOEXIST) == 0)
4544 		return;
4545 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4546 		return;
4547 
4548 	hf = bwn_hf_read(mac);
4549 	if (sprom->bf_lo & BWN_BFL_BTCMOD)
4550 		hf |= BWN_HF_BT_COEXISTALT;
4551 	else
4552 		hf |= BWN_HF_BT_COEXIST;
4553 	bwn_hf_write(mac, hf);
4554 }
4555 
4556 static void
4557 bwn_set_macaddr(struct bwn_mac *mac)
4558 {
4559 
4560 	bwn_mac_write_bssid(mac);
4561 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4562 }
4563 
4564 static void
4565 bwn_clear_keys(struct bwn_mac *mac)
4566 {
4567 	int i;
4568 
4569 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
4570 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4571 		    ("%s:%d: fail", __func__, __LINE__));
4572 
4573 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4574 		    NULL, BWN_SEC_KEYSIZE, NULL);
4575 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4576 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4577 			    NULL, BWN_SEC_KEYSIZE, NULL);
4578 		}
4579 		mac->mac_key[i].keyconf = NULL;
4580 	}
4581 }
4582 
4583 static void
4584 bwn_crypt_init(struct bwn_mac *mac)
4585 {
4586 
4587 	mac->mac_max_nr_keys = (mac->mac_sd->sd_id.sd_rev >= 5) ? 58 : 20;
4588 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4589 	    ("%s:%d: fail", __func__, __LINE__));
4590 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4591 	mac->mac_ktp *= 2;
4592 	if (mac->mac_sd->sd_id.sd_rev >= 5) {
4593 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT,
4594 		    mac->mac_max_nr_keys - 8);
4595 	}
4596 	bwn_clear_keys(mac);
4597 }
4598 
4599 static void
4600 bwn_chip_exit(struct bwn_mac *mac)
4601 {
4602 
4603 	bwn_phy_exit(mac);
4604 	bwn_gpio_cleanup(mac);
4605 }
4606 
4607 static int
4608 bwn_fw_fillinfo(struct bwn_mac *mac)
4609 {
4610 	int error;
4611 
4612 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4613 	if (error == 0)
4614 		return (0);
4615 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4616 	if (error == 0)
4617 		return (0);
4618 	return (error);
4619 }
4620 
4621 static int
4622 bwn_gpio_init(struct bwn_mac *mac)
4623 {
4624 	struct siba_softc *bus = mac->mac_sd->sd_bus;
4625 	struct siba_dev_softc *sd;
4626 	uint32_t mask = 0x0000001f, set = 0x0000000f;
4627 
4628 	BWN_WRITE_4(mac, BWN_MACCTL,
4629 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4630 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
4631 	    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4632 
4633 	if (bus->siba_chipid == 0x4301) {
4634 		mask |= 0x0060;
4635 		set |= 0x0060;
4636 	}
4637 	if (bus->siba_sprom.bf_lo & BWN_BFL_PACTRL) {
4638 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
4639 		    BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4640 		mask |= 0x0200;
4641 		set |= 0x0200;
4642 	}
4643 	if (mac->mac_sd->sd_id.sd_rev >= 2)
4644 		mask |= 0x0010;
4645 	sd = (bus->siba_cc.scc_dev != NULL) ? bus->siba_cc.scc_dev :
4646 	    bus->siba_pci.spc_dev;
4647 	if (sd == NULL)
4648 		return (0);
4649 	siba_write_4(sd, BWN_GPIOCTL,
4650 	    (siba_read_4(sd, BWN_GPIOCTL) & mask) | set);
4651 
4652 	return (0);
4653 }
4654 
4655 static int
4656 bwn_fw_loadinitvals(struct bwn_mac *mac)
4657 {
4658 #define	GETFWOFFSET(fwp, offset)				\
4659 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4660 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
4661 	const struct bwn_fwhdr *hdr;
4662 	struct bwn_fw *fw = &mac->mac_fw;
4663 	int error;
4664 
4665 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4666 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4667 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4668 	if (error)
4669 		return (error);
4670 	if (fw->initvals_band.fw) {
4671 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4672 		error = bwn_fwinitvals_write(mac,
4673 		    GETFWOFFSET(fw->initvals_band, hdr_len),
4674 		    be32toh(hdr->size),
4675 		    fw->initvals_band.fw->datasize - hdr_len);
4676 	}
4677 	return (error);
4678 #undef GETFWOFFSET
4679 }
4680 
4681 static int
4682 bwn_phy_init(struct bwn_mac *mac)
4683 {
4684 	struct bwn_softc *sc = mac->mac_sc;
4685 	int error;
4686 
4687 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4688 	mac->mac_phy.rf_onoff(mac, 1);
4689 	error = mac->mac_phy.init(mac);
4690 	if (error) {
4691 		device_printf(sc->sc_dev, "PHY init failed\n");
4692 		goto fail0;
4693 	}
4694 	error = bwn_switch_channel(mac,
4695 	    mac->mac_phy.get_default_chan(mac));
4696 	if (error) {
4697 		device_printf(sc->sc_dev,
4698 		    "failed to switch default channel\n");
4699 		goto fail1;
4700 	}
4701 	return (0);
4702 fail1:
4703 	if (mac->mac_phy.exit)
4704 		mac->mac_phy.exit(mac);
4705 fail0:
4706 	mac->mac_phy.rf_onoff(mac, 0);
4707 
4708 	return (error);
4709 }
4710 
4711 static void
4712 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4713 {
4714 	uint16_t ant;
4715 	uint16_t tmp;
4716 
4717 	ant = bwn_ant2phy(antenna);
4718 
4719 	/* For ACK/CTS */
4720 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4721 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4722 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4723 	/* For Probe Resposes */
4724 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4725 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4726 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4727 }
4728 
4729 static void
4730 bwn_set_opmode(struct bwn_mac *mac)
4731 {
4732 	struct bwn_softc *sc = mac->mac_sc;
4733 	struct ifnet *ifp = sc->sc_ifp;
4734 	struct ieee80211com *ic = ifp->if_l2com;
4735 	uint32_t ctl;
4736 	uint16_t cfp_pretbtt;
4737 
4738 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4739 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4740 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4741 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4742 	ctl |= BWN_MACCTL_STA;
4743 
4744 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4745 	    ic->ic_opmode == IEEE80211_M_MBSS)
4746 		ctl |= BWN_MACCTL_HOSTAP;
4747 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
4748 		ctl &= ~BWN_MACCTL_STA;
4749 	ctl |= sc->sc_filters;
4750 
4751 	if (mac->mac_sd->sd_id.sd_rev <= 4)
4752 		ctl |= BWN_MACCTL_PROMISC;
4753 
4754 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4755 
4756 	cfp_pretbtt = 2;
4757 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4758 		if (mac->mac_sd->sd_bus->siba_chipid == 0x4306 &&
4759 		    mac->mac_sd->sd_bus->siba_chiprev == 3)
4760 			cfp_pretbtt = 100;
4761 		else
4762 			cfp_pretbtt = 50;
4763 	}
4764 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4765 }
4766 
4767 static void
4768 bwn_gpio_cleanup(struct bwn_mac *mac)
4769 {
4770 	struct siba_softc *bus = mac->mac_sd->sd_bus;
4771 	struct siba_dev_softc *gpiodev, *pcidev = NULL;
4772 
4773 	pcidev = bus->siba_pci.spc_dev;
4774 	gpiodev = bus->siba_cc.scc_dev ? bus->siba_cc.scc_dev : pcidev;
4775 	if (!gpiodev)
4776 		return;
4777 	siba_write_4(gpiodev, BWN_GPIOCTL, 0);
4778 }
4779 
4780 static int
4781 bwn_dma_gettype(struct bwn_mac *mac)
4782 {
4783 	uint32_t tmp;
4784 	uint16_t base;
4785 
4786 	tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4787 	if (tmp & SIBA_TGSHIGH_DMA64)
4788 		return (BWN_DMA_64BIT);
4789 	base = bwn_dma_base(0, 0);
4790 	BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4791 	tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4792 	if (tmp & BWN_DMA32_TXADDREXT_MASK)
4793 		return (BWN_DMA_32BIT);
4794 
4795 	return (BWN_DMA_30BIT);
4796 }
4797 
4798 static void
4799 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4800 {
4801 	if (!error) {
4802 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4803 		*((bus_addr_t *)arg) = seg->ds_addr;
4804 	}
4805 }
4806 
4807 static void
4808 bwn_phy_g_init_sub(struct bwn_mac *mac)
4809 {
4810 	struct bwn_phy *phy = &mac->mac_phy;
4811 	struct bwn_phy_g *pg = &phy->phy_g;
4812 	uint16_t i, tmp;
4813 
4814 	if (phy->rev == 1)
4815 		bwn_phy_init_b5(mac);
4816 	else
4817 		bwn_phy_init_b6(mac);
4818 
4819 	if (phy->rev >= 2 || phy->gmode)
4820 		bwn_phy_init_a(mac);
4821 
4822 	if (phy->rev >= 2) {
4823 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4824 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4825 	}
4826 	if (phy->rev == 2) {
4827 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4828 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4829 	}
4830 	if (phy->rev > 5) {
4831 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4832 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4833 	}
4834 	if (phy->gmode || phy->rev >= 2) {
4835 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4836 		tmp &= BWN_PHYVER_VERSION;
4837 		if (tmp == 3 || tmp == 5) {
4838 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4839 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4840 		}
4841 		if (tmp == 5) {
4842 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4843 			    0x1f00);
4844 		}
4845 	}
4846 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4847 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4848 	if (phy->rf_rev == 8) {
4849 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4850 		BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4851 	}
4852 	if (BWN_HAS_LOOPBACK(phy))
4853 		bwn_loopback_calcgain(mac);
4854 
4855 	if (phy->rf_rev != 8) {
4856 		if (pg->pg_initval == 0xffff)
4857 			pg->pg_initval = bwn_rf_init_bcm2050(mac);
4858 		else
4859 			BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4860 	}
4861 	bwn_lo_g_init(mac);
4862 	if (BWN_HAS_TXMAG(phy)) {
4863 		BWN_RF_WRITE(mac, 0x52,
4864 		    (BWN_RF_READ(mac, 0x52) & 0xff00)
4865 		    | pg->pg_loctl.tx_bias |
4866 		    pg->pg_loctl.tx_magn);
4867 	} else {
4868 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4869 	}
4870 	if (phy->rev >= 6) {
4871 		BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4872 		    (pg->pg_loctl.tx_bias << 12));
4873 	}
4874 	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL)
4875 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4876 	else
4877 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4878 	if (phy->rev < 2)
4879 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4880 	else
4881 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4882 	if (phy->gmode || phy->rev >= 2) {
4883 		bwn_lo_g_adjust(mac);
4884 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4885 	}
4886 
4887 	if (!(mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
4888 		for (i = 0; i < 64; i++) {
4889 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4890 			BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4891 			    (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4892 			    -32), 31));
4893 		}
4894 		bwn_nrssi_threshold(mac);
4895 	} else if (phy->gmode || phy->rev >= 2) {
4896 		if (pg->pg_nrssi[0] == -1000) {
4897 			KASSERT(pg->pg_nrssi[1] == -1000,
4898 			    ("%s:%d: fail", __func__, __LINE__));
4899 			bwn_nrssi_slope_11g(mac);
4900 		} else
4901 			bwn_nrssi_threshold(mac);
4902 	}
4903 	if (phy->rf_rev == 8)
4904 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4905 	bwn_phy_hwpctl_init(mac);
4906 	if ((mac->mac_sd->sd_bus->siba_chipid == 0x4306
4907 	     && mac->mac_sd->sd_bus->siba_chippkg == 2) || 0) {
4908 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4909 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4910 	}
4911 }
4912 
4913 static uint8_t
4914 bwn_has_hwpctl(struct bwn_mac *mac)
4915 {
4916 
4917 	if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4918 		return (0);
4919 	return (mac->mac_phy.use_hwpctl(mac));
4920 }
4921 
4922 static void
4923 bwn_phy_init_b5(struct bwn_mac *mac)
4924 {
4925 	struct siba_softc *bus = mac->mac_sd->sd_bus;
4926 	struct bwn_phy *phy = &mac->mac_phy;
4927 	struct bwn_phy_g *pg = &phy->phy_g;
4928 	uint16_t offset, value;
4929 	uint8_t old_channel;
4930 
4931 	if (phy->analog == 1)
4932 		BWN_RF_SET(mac, 0x007a, 0x0050);
4933 	if ((bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM) &&
4934 	    (bus->siba_board_type != SIBA_BOARD_BU4306)) {
4935 		value = 0x2120;
4936 		for (offset = 0x00a8; offset < 0x00c7; offset++) {
4937 			BWN_PHY_WRITE(mac, offset, value);
4938 			value += 0x202;
4939 		}
4940 	}
4941 	BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4942 	if (phy->rf_ver == 0x2050)
4943 		BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4944 
4945 	if (phy->gmode || phy->rev >= 2) {
4946 		if (phy->rf_ver == 0x2050) {
4947 			BWN_RF_SET(mac, 0x007a, 0x0020);
4948 			BWN_RF_SET(mac, 0x0051, 0x0004);
4949 		}
4950 		BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4951 
4952 		BWN_PHY_SET(mac, 0x0802, 0x0100);
4953 		BWN_PHY_SET(mac, 0x042b, 0x2000);
4954 
4955 		BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4956 
4957 		BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4958 		BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4959 		BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4960 	}
4961 
4962 	if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4963 		BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4964 
4965 	if (phy->analog == 1) {
4966 		BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4967 		BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4968 		BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4969 		BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4970 		BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4971 	} else
4972 		BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4973 	BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4974 	BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4975 
4976 	if (phy->analog == 1)
4977 		BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4978 	else
4979 		BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4980 
4981 	if (phy->analog == 0)
4982 		BWN_WRITE_2(mac, 0x03e4, 0x3000);
4983 
4984 	old_channel = phy->chan;
4985 	bwn_phy_g_switch_chan(mac, 7, 0);
4986 
4987 	if (phy->rf_ver != 0x2050) {
4988 		BWN_RF_WRITE(mac, 0x0075, 0x0080);
4989 		BWN_RF_WRITE(mac, 0x0079, 0x0081);
4990 	}
4991 
4992 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
4993 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
4994 
4995 	if (phy->rf_ver == 0x2050) {
4996 		BWN_RF_WRITE(mac, 0x0050, 0x0020);
4997 		BWN_RF_WRITE(mac, 0x005a, 0x0070);
4998 	}
4999 
5000 	BWN_RF_WRITE(mac, 0x005b, 0x007b);
5001 	BWN_RF_WRITE(mac, 0x005c, 0x00b0);
5002 	BWN_RF_SET(mac, 0x007a, 0x0007);
5003 
5004 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5005 	BWN_PHY_WRITE(mac, 0x0014, 0x0080);
5006 	BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
5007 	BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
5008 
5009 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5010 	    pg->pg_txctl);
5011 
5012 	if (phy->rf_ver == 0x2050)
5013 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5014 
5015 	BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
5016 }
5017 
5018 static void
5019 bwn_loopback_calcgain(struct bwn_mac *mac)
5020 {
5021 	struct bwn_phy *phy = &mac->mac_phy;
5022 	struct bwn_phy_g *pg = &phy->phy_g;
5023 	uint16_t backup_phy[16] = { 0 };
5024 	uint16_t backup_radio[3];
5025 	uint16_t backup_bband;
5026 	uint16_t i, j, loop_i_max;
5027 	uint16_t trsw_rx;
5028 	uint16_t loop1_outer_done, loop1_inner_done;
5029 
5030 	backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5031 	backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
5032 	backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5033 	backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5034 	if (phy->rev != 1) {
5035 		backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5036 		backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5037 	}
5038 	backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5039 	backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5040 	backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5041 	backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
5042 	backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
5043 	backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5044 	backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5045 	backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
5046 	backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5047 	backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5048 	backup_bband = pg->pg_bbatt.att;
5049 	backup_radio[0] = BWN_RF_READ(mac, 0x52);
5050 	backup_radio[1] = BWN_RF_READ(mac, 0x43);
5051 	backup_radio[2] = BWN_RF_READ(mac, 0x7a);
5052 
5053 	BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
5054 	BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
5055 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
5056 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
5057 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
5058 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
5059 	if (phy->rev != 1) {
5060 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
5061 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
5062 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
5063 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
5064 	}
5065 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
5066 	BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
5067 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
5068 	BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
5069 
5070 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
5071 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5072 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5073 
5074 	BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
5075 	if (phy->rev != 1) {
5076 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
5077 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
5078 	}
5079 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
5080 
5081 	if (phy->rf_rev == 8)
5082 		BWN_RF_WRITE(mac, 0x43, 0x000f);
5083 	else {
5084 		BWN_RF_WRITE(mac, 0x52, 0);
5085 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
5086 	}
5087 	bwn_phy_g_set_bbatt(mac, 11);
5088 
5089 	if (phy->rev >= 3)
5090 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5091 	else
5092 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5093 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5094 
5095 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5096 	BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5097 
5098 	BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5099 	BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5100 
5101 	if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) {
5102 		if (phy->rev >= 7) {
5103 			BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5104 			BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5105 		}
5106 	}
5107 	BWN_RF_MASK(mac, 0x7a, 0x00f7);
5108 
5109 	j = 0;
5110 	loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5111 	for (i = 0; i < loop_i_max; i++) {
5112 		for (j = 0; j < 16; j++) {
5113 			BWN_RF_WRITE(mac, 0x43, i);
5114 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5115 			    (j << 8));
5116 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5117 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5118 			DELAY(20);
5119 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5120 				goto done0;
5121 		}
5122 	}
5123 done0:
5124 	loop1_outer_done = i;
5125 	loop1_inner_done = j;
5126 	if (j >= 8) {
5127 		BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5128 		trsw_rx = 0x1b;
5129 		for (j = j - 8; j < 16; j++) {
5130 			BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5131 			BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5132 			BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5133 			DELAY(20);
5134 			trsw_rx -= 3;
5135 			if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5136 				goto done1;
5137 		}
5138 	} else
5139 		trsw_rx = 0x18;
5140 done1:
5141 
5142 	if (phy->rev != 1) {
5143 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5144 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5145 	}
5146 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5147 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5148 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5149 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5150 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5151 	BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5152 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5153 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5154 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5155 
5156 	bwn_phy_g_set_bbatt(mac, backup_bband);
5157 
5158 	BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5159 	BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5160 	BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5161 
5162 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5163 	DELAY(10);
5164 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5165 	BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5166 	BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5167 	BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5168 
5169 	pg->pg_max_lb_gain =
5170 	    ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5171 	pg->pg_trsw_rx_gain = trsw_rx * 2;
5172 }
5173 
5174 static uint16_t
5175 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5176 {
5177 	struct bwn_phy *phy = &mac->mac_phy;
5178 	uint32_t tmp1 = 0, tmp2 = 0;
5179 	uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5180 	    analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5181 	    radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5182 	static const uint8_t rcc_table[] = {
5183 		0x02, 0x03, 0x01, 0x0f,
5184 		0x06, 0x07, 0x05, 0x0f,
5185 		0x0a, 0x0b, 0x09, 0x0f,
5186 		0x0e, 0x0f, 0x0d, 0x0f,
5187 	};
5188 
5189 	loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5190 	    rfoverval = rfover = cck3 = 0;
5191 	radio0 = BWN_RF_READ(mac, 0x43);
5192 	radio1 = BWN_RF_READ(mac, 0x51);
5193 	radio2 = BWN_RF_READ(mac, 0x52);
5194 	pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5195 	cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5196 	cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5197 	cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5198 
5199 	if (phy->type == BWN_PHYTYPE_B) {
5200 		cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5201 		reg0 = BWN_READ_2(mac, 0x3ec);
5202 
5203 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5204 		BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5205 	} else if (phy->gmode || phy->rev >= 2) {
5206 		rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5207 		rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5208 		analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5209 		analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5210 		crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5211 		classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5212 
5213 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5214 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5215 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5216 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5217 		if (BWN_HAS_LOOPBACK(phy)) {
5218 			lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5219 			loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5220 			if (phy->rev >= 3)
5221 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5222 			else
5223 				BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5224 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5225 		}
5226 
5227 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5228 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5229 			BWN_LPD(0, 1, 1)));
5230 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5231 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5232 	}
5233 	BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5234 
5235 	syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5236 	BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5237 	reg1 = BWN_READ_2(mac, 0x3e6);
5238 	reg2 = BWN_READ_2(mac, 0x3f4);
5239 
5240 	if (phy->analog == 0)
5241 		BWN_WRITE_2(mac, 0x03e6, 0x0122);
5242 	else {
5243 		if (phy->analog >= 2)
5244 			BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5245 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5246 		    (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5247 	}
5248 
5249 	reg = BWN_RF_READ(mac, 0x60);
5250 	index = (reg & 0x001e) >> 1;
5251 	rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5252 
5253 	if (phy->type == BWN_PHYTYPE_B)
5254 		BWN_RF_WRITE(mac, 0x78, 0x26);
5255 	if (phy->gmode || phy->rev >= 2) {
5256 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5257 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5258 			BWN_LPD(0, 1, 1)));
5259 	}
5260 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5261 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5262 	if (phy->gmode || phy->rev >= 2) {
5263 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5264 		    bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5265 			BWN_LPD(0, 0, 1)));
5266 	}
5267 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5268 	BWN_RF_SET(mac, 0x51, 0x0004);
5269 	if (phy->rf_rev == 8)
5270 		BWN_RF_WRITE(mac, 0x43, 0x1f);
5271 	else {
5272 		BWN_RF_WRITE(mac, 0x52, 0);
5273 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5274 	}
5275 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5276 
5277 	for (i = 0; i < 16; i++) {
5278 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5279 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5280 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5281 		if (phy->gmode || phy->rev >= 2) {
5282 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5283 			    bwn_rf_2050_rfoverval(mac,
5284 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5285 		}
5286 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5287 		DELAY(10);
5288 		if (phy->gmode || phy->rev >= 2) {
5289 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5290 			    bwn_rf_2050_rfoverval(mac,
5291 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5292 		}
5293 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5294 		DELAY(10);
5295 		if (phy->gmode || phy->rev >= 2) {
5296 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5297 			    bwn_rf_2050_rfoverval(mac,
5298 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5299 		}
5300 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5301 		DELAY(20);
5302 		tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5303 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5304 		if (phy->gmode || phy->rev >= 2) {
5305 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5306 			    bwn_rf_2050_rfoverval(mac,
5307 				BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5308 		}
5309 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5310 	}
5311 	DELAY(10);
5312 
5313 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5314 	tmp1++;
5315 	tmp1 >>= 9;
5316 
5317 	for (i = 0; i < 16; i++) {
5318 		radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5319 		BWN_RF_WRITE(mac, 0x78, radio78);
5320 		DELAY(10);
5321 		for (j = 0; j < 16; j++) {
5322 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5323 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5324 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5325 			if (phy->gmode || phy->rev >= 2) {
5326 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5327 				    bwn_rf_2050_rfoverval(mac,
5328 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5329 			}
5330 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5331 			DELAY(10);
5332 			if (phy->gmode || phy->rev >= 2) {
5333 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5334 				    bwn_rf_2050_rfoverval(mac,
5335 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5336 			}
5337 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5338 			DELAY(10);
5339 			if (phy->gmode || phy->rev >= 2) {
5340 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5341 				    bwn_rf_2050_rfoverval(mac,
5342 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5343 			}
5344 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5345 			DELAY(10);
5346 			tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5347 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5348 			if (phy->gmode || phy->rev >= 2) {
5349 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5350 				    bwn_rf_2050_rfoverval(mac,
5351 					BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5352 			}
5353 			BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5354 		}
5355 		tmp2++;
5356 		tmp2 >>= 8;
5357 		if (tmp1 < tmp2)
5358 			break;
5359 	}
5360 
5361 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5362 	BWN_RF_WRITE(mac, 0x51, radio1);
5363 	BWN_RF_WRITE(mac, 0x52, radio2);
5364 	BWN_RF_WRITE(mac, 0x43, radio0);
5365 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5366 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5367 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5368 	BWN_WRITE_2(mac, 0x3e6, reg1);
5369 	if (phy->analog != 0)
5370 		BWN_WRITE_2(mac, 0x3f4, reg2);
5371 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5372 	bwn_spu_workaround(mac, phy->chan);
5373 	if (phy->type == BWN_PHYTYPE_B) {
5374 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5375 		BWN_WRITE_2(mac, 0x3ec, reg0);
5376 	} else if (phy->gmode) {
5377 		BWN_WRITE_2(mac, BWN_PHY_RADIO,
5378 			    BWN_READ_2(mac, BWN_PHY_RADIO)
5379 			    & 0x7fff);
5380 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5381 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5382 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5383 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5384 			      analogoverval);
5385 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5386 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5387 		if (BWN_HAS_LOOPBACK(phy)) {
5388 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5389 			BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5390 		}
5391 	}
5392 
5393 	return ((i > 15) ? radio78 : rcc);
5394 }
5395 
5396 static void
5397 bwn_phy_init_b6(struct bwn_mac *mac)
5398 {
5399 	struct bwn_phy *phy = &mac->mac_phy;
5400 	struct bwn_phy_g *pg = &phy->phy_g;
5401 	uint16_t offset, val;
5402 	uint8_t old_channel;
5403 
5404 	KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5405 	    ("%s:%d: fail", __func__, __LINE__));
5406 
5407 	BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5408 	BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5409 	if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5410 		BWN_RF_WRITE(mac, 0x51, 0x37);
5411 		BWN_RF_WRITE(mac, 0x52, 0x70);
5412 		BWN_RF_WRITE(mac, 0x53, 0xb3);
5413 		BWN_RF_WRITE(mac, 0x54, 0x9b);
5414 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5415 		BWN_RF_WRITE(mac, 0x5b, 0x88);
5416 		BWN_RF_WRITE(mac, 0x5d, 0x88);
5417 		BWN_RF_WRITE(mac, 0x5e, 0x88);
5418 		BWN_RF_WRITE(mac, 0x7d, 0x88);
5419 		bwn_hf_write(mac,
5420 		    bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5421 	}
5422 	if (phy->rf_rev == 8) {
5423 		BWN_RF_WRITE(mac, 0x51, 0);
5424 		BWN_RF_WRITE(mac, 0x52, 0x40);
5425 		BWN_RF_WRITE(mac, 0x53, 0xb7);
5426 		BWN_RF_WRITE(mac, 0x54, 0x98);
5427 		BWN_RF_WRITE(mac, 0x5a, 0x88);
5428 		BWN_RF_WRITE(mac, 0x5b, 0x6b);
5429 		BWN_RF_WRITE(mac, 0x5c, 0x0f);
5430 		if (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_ALTIQ) {
5431 			BWN_RF_WRITE(mac, 0x5d, 0xfa);
5432 			BWN_RF_WRITE(mac, 0x5e, 0xd8);
5433 		} else {
5434 			BWN_RF_WRITE(mac, 0x5d, 0xf5);
5435 			BWN_RF_WRITE(mac, 0x5e, 0xb8);
5436 		}
5437 		BWN_RF_WRITE(mac, 0x0073, 0x0003);
5438 		BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5439 		BWN_RF_WRITE(mac, 0x007c, 0x0001);
5440 		BWN_RF_WRITE(mac, 0x007e, 0x0008);
5441 	}
5442 	for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5443 		BWN_PHY_WRITE(mac, offset, val);
5444 		val -= 0x0202;
5445 	}
5446 	for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5447 		BWN_PHY_WRITE(mac, offset, val);
5448 		val -= 0x0202;
5449 	}
5450 	for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5451 		BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5452 		val += 0x0202;
5453 	}
5454 	if (phy->type == BWN_PHYTYPE_G) {
5455 		BWN_RF_SET(mac, 0x007a, 0x0020);
5456 		BWN_RF_SET(mac, 0x0051, 0x0004);
5457 		BWN_PHY_SET(mac, 0x0802, 0x0100);
5458 		BWN_PHY_SET(mac, 0x042b, 0x2000);
5459 		BWN_PHY_WRITE(mac, 0x5b, 0);
5460 		BWN_PHY_WRITE(mac, 0x5c, 0);
5461 	}
5462 
5463 	old_channel = phy->chan;
5464 	bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5465 
5466 	BWN_RF_WRITE(mac, 0x0050, 0x0020);
5467 	BWN_RF_WRITE(mac, 0x0050, 0x0023);
5468 	DELAY(40);
5469 	if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5470 		BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5471 		BWN_RF_WRITE(mac, 0x50, 0x20);
5472 	}
5473 	if (phy->rf_rev <= 2) {
5474 		BWN_RF_WRITE(mac, 0x7c, 0x20);
5475 		BWN_RF_WRITE(mac, 0x5a, 0x70);
5476 		BWN_RF_WRITE(mac, 0x5b, 0x7b);
5477 		BWN_RF_WRITE(mac, 0x5c, 0xb0);
5478 	}
5479 	BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5480 
5481 	bwn_phy_g_switch_chan(mac, old_channel, 0);
5482 
5483 	BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5484 	if (phy->rf_rev >= 6)
5485 		BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5486 	else
5487 		BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5488 	BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5489 	bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5490 	    pg->pg_txctl);
5491 	if (phy->rf_rev <= 5)
5492 		BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5493 	if (phy->rf_rev <= 2)
5494 		BWN_RF_WRITE(mac, 0x005d, 0x000d);
5495 
5496 	if (phy->analog == 4) {
5497 		BWN_WRITE_2(mac, 0x3e4, 9);
5498 		BWN_PHY_MASK(mac, 0x61, 0x0fff);
5499 	} else
5500 		BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5501 	if (phy->type == BWN_PHYTYPE_B)
5502 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5503 	else if (phy->type == BWN_PHYTYPE_G)
5504 		BWN_WRITE_2(mac, 0x03e6, 0x0);
5505 }
5506 
5507 static void
5508 bwn_phy_init_a(struct bwn_mac *mac)
5509 {
5510 	struct bwn_phy *phy = &mac->mac_phy;
5511 
5512 	KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5513 	    ("%s:%d: fail", __func__, __LINE__));
5514 
5515 	if (phy->rev >= 6) {
5516 		if (phy->type == BWN_PHYTYPE_A)
5517 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5518 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5519 			BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5520 		else
5521 			BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5522 	}
5523 
5524 	bwn_wa_init(mac);
5525 
5526 	if (phy->type == BWN_PHYTYPE_G &&
5527 	    (mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_PACTRL))
5528 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5529 }
5530 
5531 static void
5532 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5533 {
5534 	int i;
5535 
5536 	for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5537 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5538 }
5539 
5540 static void
5541 bwn_wa_agc(struct bwn_mac *mac)
5542 {
5543 	struct bwn_phy *phy = &mac->mac_phy;
5544 
5545 	if (phy->rev == 1) {
5546 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5547 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5548 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5549 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5550 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5551 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5552 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5553 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5554 		BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5555 	} else {
5556 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5557 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5558 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5559 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5560 	}
5561 
5562 	BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5563 	    0x5700);
5564 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5565 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5566 	BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5567 	BWN_RF_SET(mac, 0x7a, 0x0008);
5568 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5569 	BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5570 	BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5571 	BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5572 	if (phy->rev == 1)
5573 		BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5574 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5575 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5576 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5577 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5578 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5579 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5580 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5581 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5582 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5583 	if (phy->rev == 1) {
5584 		BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5585 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5586 	} else {
5587 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5588 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5589 		BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5590 		if (phy->rev >= 6) {
5591 			BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5592 			BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5593 			    (uint16_t)~0xf000, 0x3000);
5594 		}
5595 	}
5596 	BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5597 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5598 	if (phy->rev == 1) {
5599 		BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5600 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5601 		BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5602 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5603 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5604 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5605 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5606 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5607 	} else {
5608 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5609 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5610 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5611 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5612 	}
5613 	if (phy->rev >= 6) {
5614 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5615 		BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5616 	}
5617 	BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5618 }
5619 
5620 static void
5621 bwn_wa_grev1(struct bwn_mac *mac)
5622 {
5623 	struct bwn_phy *phy = &mac->mac_phy;
5624 	int i;
5625 	static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5626 	static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5627 	static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5628 
5629 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5630 
5631 	/* init CRSTHRES and ANTDWELL */
5632 	if (phy->rev == 1) {
5633 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5634 	} else if (phy->rev == 2) {
5635 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5636 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5637 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5638 	} else {
5639 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5640 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5641 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5642 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5643 	}
5644 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5645 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5646 	BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5647 
5648 	/* XXX support PHY-A??? */
5649 	for (i = 0; i < N(bwn_tab_finefreqg); i++)
5650 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5651 		    bwn_tab_finefreqg[i]);
5652 
5653 	/* XXX support PHY-A??? */
5654 	if (phy->rev == 1)
5655 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5656 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5657 			    bwn_tab_noise_g1[i]);
5658 	else
5659 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5660 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5661 			    bwn_tab_noise_g2[i]);
5662 
5663 
5664 	for (i = 0; i < N(bwn_tab_rotor); i++)
5665 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5666 		    bwn_tab_rotor[i]);
5667 
5668 	/* XXX support PHY-A??? */
5669 	if (phy->rev >= 6) {
5670 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5671 		    BWN_PHY_ENCORE_EN)
5672 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5673 		else
5674 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5675 	} else
5676 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5677 
5678 	for (i = 0; i < N(bwn_tab_retard); i++)
5679 		bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5680 		    bwn_tab_retard[i]);
5681 
5682 	if (phy->rev == 1) {
5683 		for (i = 0; i < 16; i++)
5684 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5685 			    i, 0x0020);
5686 	} else {
5687 		for (i = 0; i < 32; i++)
5688 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5689 	}
5690 
5691 	bwn_wa_agc(mac);
5692 }
5693 
5694 static void
5695 bwn_wa_grev26789(struct bwn_mac *mac)
5696 {
5697 	struct bwn_phy *phy = &mac->mac_phy;
5698 	int i;
5699 	static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5700 	uint16_t ofdmrev;
5701 
5702 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5703 
5704 	bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5705 
5706 	/* init CRSTHRES and ANTDWELL */
5707 	if (phy->rev == 1)
5708 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5709 	else if (phy->rev == 2) {
5710 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5711 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5712 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5713 	} else {
5714 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5715 		BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5716 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5717 		BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5718 	}
5719 
5720 	for (i = 0; i < 64; i++)
5721 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5722 
5723 	/* XXX support PHY-A??? */
5724 	if (phy->rev == 1)
5725 		for (i = 0; i < N(bwn_tab_noise_g1); i++)
5726 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5727 			    bwn_tab_noise_g1[i]);
5728 	else
5729 		for (i = 0; i < N(bwn_tab_noise_g2); i++)
5730 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5731 			    bwn_tab_noise_g2[i]);
5732 
5733 	/* XXX support PHY-A??? */
5734 	if (phy->rev >= 6) {
5735 		if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5736 		    BWN_PHY_ENCORE_EN)
5737 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5738 		else
5739 			bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5740 	} else
5741 		bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5742 
5743 	for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5744 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5745 		    bwn_tab_sigmasqr2[i]);
5746 
5747 	if (phy->rev == 1) {
5748 		for (i = 0; i < 16; i++)
5749 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5750 			    0x0020);
5751 	} else {
5752 		for (i = 0; i < 32; i++)
5753 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5754 	}
5755 
5756 	bwn_wa_agc(mac);
5757 
5758 	ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5759 	if (ofdmrev > 2) {
5760 		if (phy->type == BWN_PHYTYPE_A)
5761 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5762 		else
5763 			BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5764 	} else {
5765 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5766 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5767 		bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5768 	}
5769 
5770 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5771 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5772 }
5773 
5774 static void
5775 bwn_wa_init(struct bwn_mac *mac)
5776 {
5777 	struct bwn_phy *phy = &mac->mac_phy;
5778 	struct siba_softc *bus = mac->mac_sd->sd_bus;
5779 
5780 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5781 
5782 	switch (phy->rev) {
5783 	case 1:
5784 		bwn_wa_grev1(mac);
5785 		break;
5786 	case 2:
5787 	case 6:
5788 	case 7:
5789 	case 8:
5790 	case 9:
5791 		bwn_wa_grev26789(mac);
5792 		break;
5793 	default:
5794 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5795 	}
5796 
5797 	if (bus->siba_board_vendor != SIBA_BOARDVENDOR_BCM ||
5798 	    bus->siba_board_type != SIBA_BOARD_BU4306 ||
5799 	    bus->siba_board_rev != 0x17) {
5800 		if (phy->rev < 2) {
5801 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5802 			    0x0002);
5803 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5804 			    0x0001);
5805 		} else {
5806 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5807 			bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5808 			if ((bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA) &&
5809 			    (phy->rev >= 7)) {
5810 				BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5811 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5812 				    0x0020, 0x0001);
5813 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5814 				    0x0021, 0x0001);
5815 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5816 				    0x0022, 0x0001);
5817 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5818 				    0x0023, 0x0000);
5819 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5820 				    0x0000, 0x0000);
5821 				bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5822 				    0x0003, 0x0002);
5823 			}
5824 		}
5825 	}
5826 	if (bus->siba_sprom.bf_lo & BWN_BFL_FEM) {
5827 		BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5828 		BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5829 	}
5830 
5831 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5832 	bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5833 }
5834 
5835 static void
5836 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5837     uint16_t value)
5838 {
5839 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5840 	uint16_t addr;
5841 
5842 	addr = table + offset;
5843 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5844 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5845 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5846 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5847 	}
5848 	pg->pg_ofdmtab_addr = addr;
5849 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5850 }
5851 
5852 static void
5853 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5854     uint32_t value)
5855 {
5856 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5857 	uint16_t addr;
5858 
5859 	addr = table + offset;
5860 	if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5861 	    (addr - 1 != pg->pg_ofdmtab_addr)) {
5862 		BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5863 		pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5864 	}
5865 	pg->pg_ofdmtab_addr = addr;
5866 
5867 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5868 	BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5869 }
5870 
5871 static void
5872 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5873     uint16_t value)
5874 {
5875 
5876 	BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5877 	BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5878 }
5879 
5880 static void
5881 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5882 {
5883 	struct bwn_phy *phy = &mac->mac_phy;
5884 	unsigned int i, max_loop;
5885 	uint16_t value;
5886 	uint32_t buffer[5] = {
5887 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5888 	};
5889 
5890 	if (ofdm) {
5891 		max_loop = 0x1e;
5892 		buffer[0] = 0x000201cc;
5893 	} else {
5894 		max_loop = 0xfa;
5895 		buffer[0] = 0x000b846e;
5896 	}
5897 
5898 	BWN_ASSERT_LOCKED(mac->mac_sc);
5899 
5900 	for (i = 0; i < 5; i++)
5901 		bwn_ram_write(mac, i * 4, buffer[i]);
5902 
5903 	BWN_WRITE_2(mac, 0x0568, 0x0000);
5904 	BWN_WRITE_2(mac, 0x07c0,
5905 	    (mac->mac_sd->sd_id.sd_rev < 11) ? 0x0000 : 0x0100);
5906 	value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5907 	BWN_WRITE_2(mac, 0x050c, value);
5908 	if (phy->type == BWN_PHYTYPE_LP)
5909 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
5910 	BWN_WRITE_2(mac, 0x0508, 0x0000);
5911 	BWN_WRITE_2(mac, 0x050a, 0x0000);
5912 	BWN_WRITE_2(mac, 0x054c, 0x0000);
5913 	BWN_WRITE_2(mac, 0x056a, 0x0014);
5914 	BWN_WRITE_2(mac, 0x0568, 0x0826);
5915 	BWN_WRITE_2(mac, 0x0500, 0x0000);
5916 	if (phy->type == BWN_PHYTYPE_LP)
5917 		BWN_WRITE_2(mac, 0x0502, 0x0050);
5918 	else
5919 		BWN_WRITE_2(mac, 0x0502, 0x0030);
5920 
5921 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5922 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
5923 	for (i = 0x00; i < max_loop; i++) {
5924 		value = BWN_READ_2(mac, 0x050e);
5925 		if (value & 0x0080)
5926 			break;
5927 		DELAY(10);
5928 	}
5929 	for (i = 0x00; i < 0x0a; i++) {
5930 		value = BWN_READ_2(mac, 0x050e);
5931 		if (value & 0x0400)
5932 			break;
5933 		DELAY(10);
5934 	}
5935 	for (i = 0x00; i < 0x19; i++) {
5936 		value = BWN_READ_2(mac, 0x0690);
5937 		if (!(value & 0x0100))
5938 			break;
5939 		DELAY(10);
5940 	}
5941 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5942 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
5943 }
5944 
5945 static void
5946 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5947 {
5948 	uint32_t macctl;
5949 
5950 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5951 
5952 	macctl = BWN_READ_4(mac, BWN_MACCTL);
5953 	if (macctl & BWN_MACCTL_BIGENDIAN)
5954 		printf("TODO: need swap\n");
5955 
5956 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5957 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5958 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5959 }
5960 
5961 static void
5962 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5963 {
5964 	uint16_t value;
5965 
5966 	KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5967 	    ("%s:%d: fail", __func__, __LINE__));
5968 
5969 	value = (uint8_t) (ctl->q);
5970 	value |= ((uint8_t) (ctl->i)) << 8;
5971 	BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5972 }
5973 
5974 static uint16_t
5975 bwn_lo_calcfeed(struct bwn_mac *mac,
5976     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5977 {
5978 	struct bwn_phy *phy = &mac->mac_phy;
5979 	uint16_t rfover;
5980 	uint16_t feedthrough;
5981 
5982 	if (phy->gmode) {
5983 		lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5984 		pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5985 
5986 		KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5987 		    ("%s:%d: fail", __func__, __LINE__));
5988 		KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5989 		    ("%s:%d: fail", __func__, __LINE__));
5990 
5991 		trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5992 
5993 		rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5994 		if ((mac->mac_sd->sd_bus->siba_sprom.bf_lo & BWN_BFL_EXTLNA)
5995 		    && phy->rev > 6)
5996 			rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5997 
5998 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5999 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
6000 		DELAY(10);
6001 		rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
6002 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
6003 		DELAY(10);
6004 		rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
6005 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
6006 		DELAY(10);
6007 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
6008 	} else {
6009 		pga |= BWN_PHY_PGACTL_UNKNOWN;
6010 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
6011 		DELAY(10);
6012 		pga |= BWN_PHY_PGACTL_LOWBANDW;
6013 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
6014 		DELAY(10);
6015 		pga |= BWN_PHY_PGACTL_LPF;
6016 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
6017 	}
6018 	DELAY(21);
6019 	feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
6020 
6021 	return (feedthrough);
6022 }
6023 
6024 static uint16_t
6025 bwn_lo_txctl_regtable(struct bwn_mac *mac,
6026     uint16_t *value, uint16_t *pad_mix_gain)
6027 {
6028 	struct bwn_phy *phy = &mac->mac_phy;
6029 	uint16_t reg, v, padmix;
6030 
6031 	if (phy->type == BWN_PHYTYPE_B) {
6032 		v = 0x30;
6033 		if (phy->rf_rev <= 5) {
6034 			reg = 0x43;
6035 			padmix = 0;
6036 		} else {
6037 			reg = 0x52;
6038 			padmix = 5;
6039 		}
6040 	} else {
6041 		if (phy->rev >= 2 && phy->rf_rev == 8) {
6042 			reg = 0x43;
6043 			v = 0x10;
6044 			padmix = 2;
6045 		} else {
6046 			reg = 0x52;
6047 			v = 0x30;
6048 			padmix = 5;
6049 		}
6050 	}
6051 	if (value)
6052 		*value = v;
6053 	if (pad_mix_gain)
6054 		*pad_mix_gain = padmix;
6055 
6056 	return (reg);
6057 }
6058 
6059 static void
6060 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
6061 {
6062 	struct bwn_phy *phy = &mac->mac_phy;
6063 	struct bwn_phy_g *pg = &phy->phy_g;
6064 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6065 	uint16_t reg, mask;
6066 	uint16_t trsw_rx, pga;
6067 	uint16_t rf_pctl_reg;
6068 
6069 	static const uint8_t tx_bias_values[] = {
6070 		0x09, 0x08, 0x0a, 0x01, 0x00,
6071 		0x02, 0x05, 0x04, 0x06,
6072 	};
6073 	static const uint8_t tx_magn_values[] = {
6074 		0x70, 0x40,
6075 	};
6076 
6077 	if (!BWN_HAS_LOOPBACK(phy)) {
6078 		rf_pctl_reg = 6;
6079 		trsw_rx = 2;
6080 		pga = 0;
6081 	} else {
6082 		int lb_gain;
6083 
6084 		trsw_rx = 0;
6085 		lb_gain = pg->pg_max_lb_gain / 2;
6086 		if (lb_gain > 10) {
6087 			rf_pctl_reg = 0;
6088 			pga = abs(10 - lb_gain) / 6;
6089 			pga = MIN(MAX(pga, 0), 15);
6090 		} else {
6091 			int cmp_val;
6092 			int tmp;
6093 
6094 			pga = 0;
6095 			cmp_val = 0x24;
6096 			if ((phy->rev >= 2) &&
6097 			    (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6098 				cmp_val = 0x3c;
6099 			tmp = lb_gain;
6100 			if ((10 - lb_gain) < cmp_val)
6101 				tmp = (10 - lb_gain);
6102 			if (tmp < 0)
6103 				tmp += 6;
6104 			else
6105 				tmp += 3;
6106 			cmp_val /= 4;
6107 			tmp /= 4;
6108 			if (tmp >= cmp_val)
6109 				rf_pctl_reg = cmp_val;
6110 			else
6111 				rf_pctl_reg = tmp;
6112 		}
6113 	}
6114 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6115 	bwn_phy_g_set_bbatt(mac, 2);
6116 
6117 	reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6118 	mask = ~mask;
6119 	BWN_RF_MASK(mac, reg, mask);
6120 
6121 	if (BWN_HAS_TXMAG(phy)) {
6122 		int i, j;
6123 		int feedthrough;
6124 		int min_feedth = 0xffff;
6125 		uint8_t tx_magn, tx_bias;
6126 
6127 		for (i = 0; i < N(tx_magn_values); i++) {
6128 			tx_magn = tx_magn_values[i];
6129 			BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6130 			for (j = 0; j < N(tx_bias_values); j++) {
6131 				tx_bias = tx_bias_values[j];
6132 				BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6133 				feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6134 				    trsw_rx);
6135 				if (feedthrough < min_feedth) {
6136 					lo->tx_bias = tx_bias;
6137 					lo->tx_magn = tx_magn;
6138 					min_feedth = feedthrough;
6139 				}
6140 				if (lo->tx_bias == 0)
6141 					break;
6142 			}
6143 			BWN_RF_WRITE(mac, 0x52,
6144 					  (BWN_RF_READ(mac, 0x52)
6145 					   & 0xff00) | lo->tx_bias | lo->
6146 					  tx_magn);
6147 		}
6148 	} else {
6149 		lo->tx_magn = 0;
6150 		lo->tx_bias = 0;
6151 		BWN_RF_MASK(mac, 0x52, 0xfff0);
6152 	}
6153 
6154 	BWN_GETTIME(lo->txctl_measured_time);
6155 }
6156 
6157 static void
6158 bwn_lo_get_powervector(struct bwn_mac *mac)
6159 {
6160 	struct bwn_phy *phy = &mac->mac_phy;
6161 	struct bwn_phy_g *pg = &phy->phy_g;
6162 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6163 	int i;
6164 	uint64_t tmp;
6165 	uint64_t power_vector = 0;
6166 
6167 	for (i = 0; i < 8; i += 2) {
6168 		tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6169 		power_vector |= (tmp << (i * 8));
6170 		bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6171 	}
6172 	if (power_vector)
6173 		lo->power_vector = power_vector;
6174 
6175 	BWN_GETTIME(lo->pwr_vec_read_time);
6176 }
6177 
6178 static void
6179 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6180     int use_trsw_rx)
6181 {
6182 	struct bwn_phy *phy = &mac->mac_phy;
6183 	struct bwn_phy_g *pg = &phy->phy_g;
6184 	uint16_t tmp;
6185 
6186 	if (max_rx_gain < 0)
6187 		max_rx_gain = 0;
6188 
6189 	if (BWN_HAS_LOOPBACK(phy)) {
6190 		int trsw_rx = 0;
6191 		int trsw_rx_gain;
6192 
6193 		if (use_trsw_rx) {
6194 			trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6195 			if (max_rx_gain >= trsw_rx_gain) {
6196 				trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6197 				trsw_rx = 0x20;
6198 			}
6199 		} else
6200 			trsw_rx_gain = max_rx_gain;
6201 		if (trsw_rx_gain < 9) {
6202 			pg->pg_lna_lod_gain = 0;
6203 		} else {
6204 			pg->pg_lna_lod_gain = 1;
6205 			trsw_rx_gain -= 8;
6206 		}
6207 		trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6208 		pg->pg_pga_gain = trsw_rx_gain / 3;
6209 		if (pg->pg_pga_gain >= 5) {
6210 			pg->pg_pga_gain -= 5;
6211 			pg->pg_lna_gain = 2;
6212 		} else
6213 			pg->pg_lna_gain = 0;
6214 	} else {
6215 		pg->pg_lna_gain = 0;
6216 		pg->pg_trsw_rx_gain = 0x20;
6217 		if (max_rx_gain >= 0x14) {
6218 			pg->pg_lna_lod_gain = 1;
6219 			pg->pg_pga_gain = 2;
6220 		} else if (max_rx_gain >= 0x12) {
6221 			pg->pg_lna_lod_gain = 1;
6222 			pg->pg_pga_gain = 1;
6223 		} else if (max_rx_gain >= 0xf) {
6224 			pg->pg_lna_lod_gain = 1;
6225 			pg->pg_pga_gain = 0;
6226 		} else {
6227 			pg->pg_lna_lod_gain = 0;
6228 			pg->pg_pga_gain = 0;
6229 		}
6230 	}
6231 
6232 	tmp = BWN_RF_READ(mac, 0x7a);
6233 	if (pg->pg_lna_lod_gain == 0)
6234 		tmp &= ~0x0008;
6235 	else
6236 		tmp |= 0x0008;
6237 	BWN_RF_WRITE(mac, 0x7a, tmp);
6238 }
6239 
6240 static void
6241 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6242 {
6243 	struct siba_sprom *sprom = &mac->mac_sd->sd_bus->siba_sprom;
6244 	struct bwn_phy *phy = &mac->mac_phy;
6245 	struct bwn_phy_g *pg = &phy->phy_g;
6246 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6247 	struct timespec ts;
6248 	uint16_t tmp;
6249 
6250 	if (bwn_has_hwpctl(mac)) {
6251 		sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6252 		sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6253 		sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6254 		sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6255 		sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6256 
6257 		BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6258 		BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6259 		BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6260 		BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6261 	}
6262 	if (phy->type == BWN_PHYTYPE_B &&
6263 	    phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6264 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6265 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6266 	}
6267 	if (phy->rev >= 2) {
6268 		sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6269 		sav->phy_analogoverval =
6270 		    BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6271 		sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6272 		sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6273 		sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6274 		sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6275 		sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6276 
6277 		BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6278 		BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6279 		BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6280 		BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6281 		if (phy->type == BWN_PHYTYPE_G) {
6282 			if ((phy->rev >= 7) &&
6283 			    (sprom->bf_lo & BWN_BFL_EXTLNA)) {
6284 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6285 			} else {
6286 				BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6287 			}
6288 		} else {
6289 			BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6290 		}
6291 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6292 	}
6293 	sav->reg0 = BWN_READ_2(mac, 0x3f4);
6294 	sav->reg1 = BWN_READ_2(mac, 0x3e2);
6295 	sav->rf0 = BWN_RF_READ(mac, 0x43);
6296 	sav->rf1 = BWN_RF_READ(mac, 0x7a);
6297 	sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6298 	sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6299 	sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6300 	sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6301 
6302 	if (!BWN_HAS_TXMAG(phy)) {
6303 		sav->rf2 = BWN_RF_READ(mac, 0x52);
6304 		sav->rf2 &= 0x00f0;
6305 	}
6306 	if (phy->type == BWN_PHYTYPE_B) {
6307 		sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6308 		sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6309 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6310 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6311 	} else {
6312 		BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6313 			    | 0x8000);
6314 	}
6315 	BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6316 		    & 0xf000);
6317 
6318 	tmp =
6319 	    (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6320 	BWN_PHY_WRITE(mac, tmp, 0x007f);
6321 
6322 	tmp = sav->phy_syncctl;
6323 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6324 	tmp = sav->rf1;
6325 	BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6326 
6327 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6328 	if (phy->type == BWN_PHYTYPE_G ||
6329 	    (phy->type == BWN_PHYTYPE_B &&
6330 	     phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6331 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6332 	} else
6333 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6334 	if (phy->rev >= 2)
6335 		bwn_dummy_transmission(mac, 0, 1);
6336 	bwn_phy_g_switch_chan(mac, 6, 0);
6337 	BWN_RF_READ(mac, 0x51);
6338 	if (phy->type == BWN_PHYTYPE_G)
6339 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6340 
6341 	nanouptime(&ts);
6342 	if (time_before(lo->txctl_measured_time,
6343 	    (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6344 		bwn_lo_measure_txctl_values(mac);
6345 
6346 	if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6347 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6348 	else {
6349 		if (phy->type == BWN_PHYTYPE_B)
6350 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6351 		else
6352 			BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6353 	}
6354 }
6355 
6356 static void
6357 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6358 {
6359 	struct bwn_phy *phy = &mac->mac_phy;
6360 	struct bwn_phy_g *pg = &phy->phy_g;
6361 	uint16_t tmp;
6362 
6363 	if (phy->rev >= 2) {
6364 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6365 		tmp = (pg->pg_pga_gain << 8);
6366 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6367 		DELAY(5);
6368 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6369 		DELAY(2);
6370 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6371 	} else {
6372 		tmp = (pg->pg_pga_gain | 0xefa0);
6373 		BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6374 	}
6375 	if (phy->type == BWN_PHYTYPE_G) {
6376 		if (phy->rev >= 3)
6377 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6378 		else
6379 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6380 		if (phy->rev >= 2)
6381 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6382 		else
6383 			BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6384 	}
6385 	BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6386 	BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6387 	BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6388 	BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6389 	BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6390 	BWN_RF_WRITE(mac, 0x43, sav->rf0);
6391 	BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6392 	if (!BWN_HAS_TXMAG(phy)) {
6393 		tmp = sav->rf2;
6394 		BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6395 	}
6396 	BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6397 	if (phy->type == BWN_PHYTYPE_B &&
6398 	    phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6399 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6400 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6401 	}
6402 	if (phy->rev >= 2) {
6403 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6404 		BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6405 			      sav->phy_analogoverval);
6406 		BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6407 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6408 		BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6409 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6410 		BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6411 	}
6412 	if (bwn_has_hwpctl(mac)) {
6413 		tmp = (sav->phy_lomask & 0xbfff);
6414 		BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6415 		BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6416 		BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6417 		BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6418 		BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6419 	}
6420 	bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6421 }
6422 
6423 static int
6424 bwn_lo_probe_loctl(struct bwn_mac *mac,
6425     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6426 {
6427 	struct bwn_phy *phy = &mac->mac_phy;
6428 	struct bwn_phy_g *pg = &phy->phy_g;
6429 	struct bwn_loctl orig, test;
6430 	struct bwn_loctl prev = { -100, -100 };
6431 	static const struct bwn_loctl modifiers[] = {
6432 		{  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6433 		{ -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6434 	};
6435 	int begin, end, lower = 0, i;
6436 	uint16_t feedth;
6437 
6438 	if (d->curstate == 0) {
6439 		begin = 1;
6440 		end = 8;
6441 	} else if (d->curstate % 2 == 0) {
6442 		begin = d->curstate - 1;
6443 		end = d->curstate + 1;
6444 	} else {
6445 		begin = d->curstate - 2;
6446 		end = d->curstate + 2;
6447 	}
6448 	if (begin < 1)
6449 		begin += 8;
6450 	if (end > 8)
6451 		end -= 8;
6452 
6453 	memcpy(&orig, probe, sizeof(struct bwn_loctl));
6454 	i = begin;
6455 	d->curstate = i;
6456 	while (1) {
6457 		KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6458 		memcpy(&test, &orig, sizeof(struct bwn_loctl));
6459 		test.i += modifiers[i - 1].i * d->multipler;
6460 		test.q += modifiers[i - 1].q * d->multipler;
6461 		if ((test.i != prev.i || test.q != prev.q) &&
6462 		    (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6463 			bwn_lo_write(mac, &test);
6464 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6465 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6466 			if (feedth < d->feedth) {
6467 				memcpy(probe, &test,
6468 				    sizeof(struct bwn_loctl));
6469 				lower = 1;
6470 				d->feedth = feedth;
6471 				if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6472 					break;
6473 			}
6474 		}
6475 		memcpy(&prev, &test, sizeof(prev));
6476 		if (i == end)
6477 			break;
6478 		if (i == 8)
6479 			i = 1;
6480 		else
6481 			i++;
6482 		d->curstate = i;
6483 	}
6484 
6485 	return (lower);
6486 }
6487 
6488 static void
6489 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6490 {
6491 	struct bwn_phy *phy = &mac->mac_phy;
6492 	struct bwn_phy_g *pg = &phy->phy_g;
6493 	struct bwn_lo_g_sm d;
6494 	struct bwn_loctl probe;
6495 	int lower, repeat, cnt = 0;
6496 	uint16_t feedth;
6497 
6498 	d.nmeasure = 0;
6499 	d.multipler = 1;
6500 	if (BWN_HAS_LOOPBACK(phy))
6501 		d.multipler = 3;
6502 
6503 	memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6504 	repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6505 
6506 	do {
6507 		bwn_lo_write(mac, &d.loctl);
6508 		feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6509 		    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6510 		if (feedth < 0x258) {
6511 			if (feedth >= 0x12c)
6512 				*rxgain += 6;
6513 			else
6514 				*rxgain += 3;
6515 			feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6516 			    pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6517 		}
6518 		d.feedth = feedth;
6519 		d.curstate = 0;
6520 		do {
6521 			KASSERT(d.curstate >= 0 && d.curstate <= 8,
6522 			    ("%s:%d: fail", __func__, __LINE__));
6523 			memcpy(&probe, &d.loctl,
6524 			       sizeof(struct bwn_loctl));
6525 			lower = bwn_lo_probe_loctl(mac, &probe, &d);
6526 			if (!lower)
6527 				break;
6528 			if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6529 				break;
6530 			memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6531 			d.nmeasure++;
6532 		} while (d.nmeasure < 24);
6533 		memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6534 
6535 		if (BWN_HAS_LOOPBACK(phy)) {
6536 			if (d.feedth > 0x1194)
6537 				*rxgain -= 6;
6538 			else if (d.feedth < 0x5dc)
6539 				*rxgain += 3;
6540 			if (cnt == 0) {
6541 				if (d.feedth <= 0x5dc) {
6542 					d.multipler = 1;
6543 					cnt++;
6544 				} else
6545 					d.multipler = 2;
6546 			} else if (cnt == 2)
6547 				d.multipler = 1;
6548 		}
6549 		bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6550 	} while (++cnt < repeat);
6551 }
6552 
6553 static struct bwn_lo_calib *
6554 bwn_lo_calibset(struct bwn_mac *mac,
6555     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6556 {
6557 	struct bwn_phy *phy = &mac->mac_phy;
6558 	struct bwn_phy_g *pg = &phy->phy_g;
6559 	struct bwn_loctl loctl = { 0, 0 };
6560 	struct bwn_lo_calib *cal;
6561 	struct bwn_lo_g_value sval = { 0 };
6562 	int rxgain;
6563 	uint16_t pad, reg, value;
6564 
6565 	sval.old_channel = phy->chan;
6566 	bwn_mac_suspend(mac);
6567 	bwn_lo_save(mac, &sval);
6568 
6569 	reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6570 	BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6571 	BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6572 
6573 	rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6574 	if (rfatt->padmix)
6575 		rxgain -= pad;
6576 	if (BWN_HAS_LOOPBACK(phy))
6577 		rxgain += pg->pg_max_lb_gain;
6578 	bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6579 	bwn_phy_g_set_bbatt(mac, bbatt->att);
6580 	bwn_lo_probe_sm(mac, &loctl, &rxgain);
6581 
6582 	bwn_lo_restore(mac, &sval);
6583 	bwn_mac_enable(mac);
6584 
6585 	cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6586 	if (!cal) {
6587 		device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6588 		return (NULL);
6589 	}
6590 	memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6591 	memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6592 	memcpy(&cal->ctl, &loctl, sizeof(loctl));
6593 
6594 	BWN_GETTIME(cal->calib_time);
6595 
6596 	return (cal);
6597 }
6598 
6599 static struct bwn_lo_calib *
6600 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6601     const struct bwn_rfatt *rfatt)
6602 {
6603 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6604 	struct bwn_lo_calib *c;
6605 
6606 	TAILQ_FOREACH(c, &lo->calib_list, list) {
6607 		if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6608 			continue;
6609 		if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6610 			continue;
6611 		return (c);
6612 	}
6613 
6614 	c = bwn_lo_calibset(mac, bbatt, rfatt);
6615 	if (!c)
6616 		return (NULL);
6617 	TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6618 
6619 	return (c);
6620 }
6621 
6622 static void
6623 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6624 {
6625 	struct bwn_phy *phy = &mac->mac_phy;
6626 	struct bwn_phy_g *pg = &phy->phy_g;
6627 	struct bwn_softc *sc = mac->mac_sc;
6628 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6629 	const struct bwn_rfatt *rfatt;
6630 	const struct bwn_bbatt *bbatt;
6631 	uint64_t pvector;
6632 	int i;
6633 	int rf_offset, bb_offset;
6634 	uint8_t changed = 0;
6635 
6636 	KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6637 	KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6638 	    ("%s:%d: fail", __func__, __LINE__));
6639 
6640 	pvector = lo->power_vector;
6641 	if (!update && !pvector)
6642 		return;
6643 
6644 	bwn_mac_suspend(mac);
6645 
6646 	for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6647 		struct bwn_lo_calib *cal;
6648 		int idx;
6649 		uint16_t val;
6650 
6651 		if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6652 			continue;
6653 		bb_offset = i / lo->rfatt.len;
6654 		rf_offset = i % lo->rfatt.len;
6655 		bbatt = &(lo->bbatt.array[bb_offset]);
6656 		rfatt = &(lo->rfatt.array[rf_offset]);
6657 
6658 		cal = bwn_lo_calibset(mac, bbatt, rfatt);
6659 		if (!cal) {
6660 			device_printf(sc->sc_dev, "LO: Could not "
6661 			    "calibrate DC table entry\n");
6662 			continue;
6663 		}
6664 		val = (uint8_t)(cal->ctl.q);
6665 		val |= ((uint8_t)(cal->ctl.i)) << 4;
6666 		free(cal, M_DEVBUF);
6667 
6668 		idx = i / 2;
6669 		if (i % 2)
6670 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6671 			    | ((val & 0x00ff) << 8);
6672 		else
6673 			lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6674 			    | (val & 0x00ff);
6675 		changed = 1;
6676 	}
6677 	if (changed) {
6678 		for (i = 0; i < BWN_DC_LT_SIZE; i++)
6679 			BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6680 	}
6681 	bwn_mac_enable(mac);
6682 }
6683 
6684 static void
6685 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6686 {
6687 
6688 	if (!rf->padmix)
6689 		return;
6690 	if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6691 		rf->att = 4;
6692 }
6693 
6694 static void
6695 bwn_lo_g_adjust(struct bwn_mac *mac)
6696 {
6697 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6698 	struct bwn_lo_calib *cal;
6699 	struct bwn_rfatt rf;
6700 
6701 	memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6702 	bwn_lo_fixup_rfatt(&rf);
6703 
6704 	cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6705 	if (!cal)
6706 		return;
6707 	bwn_lo_write(mac, &cal->ctl);
6708 }
6709 
6710 static void
6711 bwn_lo_g_init(struct bwn_mac *mac)
6712 {
6713 
6714 	if (!bwn_has_hwpctl(mac))
6715 		return;
6716 
6717 	bwn_lo_get_powervector(mac);
6718 	bwn_phy_g_dc_lookup_init(mac, 1);
6719 }
6720 
6721 static void
6722 bwn_mac_suspend(struct bwn_mac *mac)
6723 {
6724 	struct bwn_softc *sc = mac->mac_sc;
6725 	int i;
6726 	uint32_t tmp;
6727 
6728 	KASSERT(mac->mac_suspended >= 0,
6729 	    ("%s:%d: fail", __func__, __LINE__));
6730 
6731 	if (mac->mac_suspended == 0) {
6732 		bwn_psctl(mac, BWN_PS_AWAKE);
6733 		BWN_WRITE_4(mac, BWN_MACCTL,
6734 			    BWN_READ_4(mac, BWN_MACCTL)
6735 			    & ~BWN_MACCTL_ON);
6736 		BWN_READ_4(mac, BWN_MACCTL);
6737 		for (i = 35; i; i--) {
6738 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6739 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6740 				goto out;
6741 			DELAY(10);
6742 		}
6743 		for (i = 40; i; i--) {
6744 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6745 			if (tmp & BWN_INTR_MAC_SUSPENDED)
6746 				goto out;
6747 			DELAY(1000);
6748 		}
6749 		device_printf(sc->sc_dev, "MAC suspend failed\n");
6750 	}
6751 out:
6752 	mac->mac_suspended++;
6753 }
6754 
6755 static void
6756 bwn_mac_enable(struct bwn_mac *mac)
6757 {
6758 	struct bwn_softc *sc = mac->mac_sc;
6759 	uint16_t state;
6760 
6761 	state = bwn_shm_read_2(mac, BWN_SHARED,
6762 	    BWN_SHARED_UCODESTAT);
6763 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6764 	    state != BWN_SHARED_UCODESTAT_SLEEP)
6765 		device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6766 
6767 	mac->mac_suspended--;
6768 	KASSERT(mac->mac_suspended >= 0,
6769 	    ("%s:%d: fail", __func__, __LINE__));
6770 	if (mac->mac_suspended == 0) {
6771 		BWN_WRITE_4(mac, BWN_MACCTL,
6772 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6773 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6774 		BWN_READ_4(mac, BWN_MACCTL);
6775 		BWN_READ_4(mac, BWN_INTR_REASON);
6776 		bwn_psctl(mac, 0);
6777 	}
6778 }
6779 
6780 static void
6781 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6782 {
6783 	int i;
6784 	uint16_t ucstat;
6785 
6786 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6787 	    ("%s:%d: fail", __func__, __LINE__));
6788 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6789 	    ("%s:%d: fail", __func__, __LINE__));
6790 
6791 	/* XXX forcibly awake and hwps-off */
6792 
6793 	BWN_WRITE_4(mac, BWN_MACCTL,
6794 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6795 	    ~BWN_MACCTL_HWPS);
6796 	BWN_READ_4(mac, BWN_MACCTL);
6797 	if (mac->mac_sd->sd_id.sd_rev >= 5) {
6798 		for (i = 0; i < 100; i++) {
6799 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6800 			    BWN_SHARED_UCODESTAT);
6801 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6802 				break;
6803 			DELAY(10);
6804 		}
6805 	}
6806 }
6807 
6808 static int16_t
6809 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6810 {
6811 
6812 	BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6813 	return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6814 }
6815 
6816 static void
6817 bwn_nrssi_threshold(struct bwn_mac *mac)
6818 {
6819 	struct bwn_phy *phy = &mac->mac_phy;
6820 	struct bwn_phy_g *pg = &phy->phy_g;
6821 	struct siba_softc *siba = mac->mac_sd->sd_bus;
6822 	int32_t a, b;
6823 	int16_t tmp16;
6824 	uint16_t tmpu16;
6825 
6826 	KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6827 
6828 	if (phy->gmode && (siba->siba_sprom.bf_lo & BWN_BFL_RSSI)) {
6829 		if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6830 			a = 0x13;
6831 			b = 0x12;
6832 		} else {
6833 			a = 0xe;
6834 			b = 0x11;
6835 		}
6836 
6837 		a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6838 		a += (pg->pg_nrssi[0] << 6);
6839 		a += (a < 32) ? 31 : 32;
6840 		a = a >> 6;
6841 		a = MIN(MAX(a, -31), 31);
6842 
6843 		b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6844 		b += (pg->pg_nrssi[0] << 6);
6845 		if (b < 32)
6846 			b += 31;
6847 		else
6848 			b += 32;
6849 		b = b >> 6;
6850 		b = MIN(MAX(b, -31), 31);
6851 
6852 		tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6853 		tmpu16 |= ((uint32_t)b & 0x0000003f);
6854 		tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6855 		BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6856 		return;
6857 	}
6858 
6859 	tmp16 = bwn_nrssi_read(mac, 0x20);
6860 	if (tmp16 >= 0x20)
6861 		tmp16 -= 0x40;
6862 	BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6863 }
6864 
6865 static void
6866 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6867 {
6868 #define	SAVE_RF_MAX		3
6869 #define	SAVE_PHY_COMM_MAX	4
6870 #define	SAVE_PHY3_MAX		8
6871 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6872 		{ 0x7a, 0x52, 0x43 };
6873 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6874 		{ 0x15, 0x5a, 0x59, 0x58 };
6875 	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6876 		0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6877 		0x0801, 0x0060, 0x0014, 0x0478
6878 	};
6879 	struct bwn_phy *phy = &mac->mac_phy;
6880 	struct bwn_phy_g *pg = &phy->phy_g;
6881 	int32_t i, tmp32, phy3_idx = 0;
6882 	uint16_t delta, tmp;
6883 	uint16_t save_rf[SAVE_RF_MAX];
6884 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6885 	uint16_t save_phy3[SAVE_PHY3_MAX];
6886 	uint16_t ant_div, phy0, chan_ex;
6887 	int16_t nrssi0, nrssi1;
6888 
6889 	KASSERT(phy->type == BWN_PHYTYPE_G,
6890 	    ("%s:%d: fail", __func__, __LINE__));
6891 
6892 	if (phy->rf_rev >= 9)
6893 		return;
6894 	if (phy->rf_rev == 8)
6895 		bwn_nrssi_offset(mac);
6896 
6897 	BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6898 	BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6899 
6900 	/*
6901 	 * Save RF/PHY registers for later restoration
6902 	 */
6903 	ant_div = BWN_READ_2(mac, 0x03e2);
6904 	BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6905 	for (i = 0; i < SAVE_RF_MAX; ++i)
6906 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6907 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6908 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6909 
6910 	phy0 = BWN_READ_2(mac, BWN_PHY0);
6911 	chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6912 	if (phy->rev >= 3) {
6913 		for (i = 0; i < SAVE_PHY3_MAX; ++i)
6914 			save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6915 		BWN_PHY_WRITE(mac, 0x002e, 0);
6916 		BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6917 		switch (phy->rev) {
6918 		case 4:
6919 		case 6:
6920 		case 7:
6921 			BWN_PHY_SET(mac, 0x0478, 0x0100);
6922 			BWN_PHY_SET(mac, 0x0801, 0x0040);
6923 			break;
6924 		case 3:
6925 		case 5:
6926 			BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6927 			break;
6928 		}
6929 		BWN_PHY_SET(mac, 0x0060, 0x0040);
6930 		BWN_PHY_SET(mac, 0x0014, 0x0200);
6931 	}
6932 	/*
6933 	 * Calculate nrssi0
6934 	 */
6935 	BWN_RF_SET(mac, 0x007a, 0x0070);
6936 	bwn_set_all_gains(mac, 0, 8, 0);
6937 	BWN_RF_MASK(mac, 0x007a, 0x00f7);
6938 	if (phy->rev >= 2) {
6939 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6940 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6941 	}
6942 	BWN_RF_SET(mac, 0x007a, 0x0080);
6943 	DELAY(20);
6944 
6945 	nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6946 	if (nrssi0 >= 0x0020)
6947 		nrssi0 -= 0x0040;
6948 
6949 	/*
6950 	 * Calculate nrssi1
6951 	 */
6952 	BWN_RF_MASK(mac, 0x007a, 0x007f);
6953 	if (phy->rev >= 2)
6954 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6955 
6956 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6957 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6958 	BWN_RF_SET(mac, 0x007a, 0x000f);
6959 	BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6960 	if (phy->rev >= 2) {
6961 		BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6962 		BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6963 	}
6964 
6965 	bwn_set_all_gains(mac, 3, 0, 1);
6966 	if (phy->rf_rev == 8) {
6967 		BWN_RF_WRITE(mac, 0x0043, 0x001f);
6968 	} else {
6969 		tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6970 		BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6971 		tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6972 		BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6973 	}
6974 	BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6975 	BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6976 	BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6977 	DELAY(20);
6978 	nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6979 
6980 	/*
6981 	 * Install calculated narrow RSSI values
6982 	 */
6983 	if (nrssi1 >= 0x0020)
6984 		nrssi1 -= 0x0040;
6985 	if (nrssi0 == nrssi1)
6986 		pg->pg_nrssi_slope = 0x00010000;
6987 	else
6988 		pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6989 	if (nrssi0 >= -4) {
6990 		pg->pg_nrssi[0] = nrssi1;
6991 		pg->pg_nrssi[1] = nrssi0;
6992 	}
6993 
6994 	/*
6995 	 * Restore saved RF/PHY registers
6996 	 */
6997 	if (phy->rev >= 3) {
6998 		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6999 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
7000 			    save_phy3[phy3_idx]);
7001 		}
7002 	}
7003 	if (phy->rev >= 2) {
7004 		BWN_PHY_MASK(mac, 0x0812, 0xffcf);
7005 		BWN_PHY_MASK(mac, 0x0811, 0xffcf);
7006 	}
7007 
7008 	for (i = 0; i < SAVE_RF_MAX; ++i)
7009 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7010 
7011 	BWN_WRITE_2(mac, 0x03e2, ant_div);
7012 	BWN_WRITE_2(mac, 0x03e6, phy0);
7013 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
7014 
7015 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
7016 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7017 
7018 	bwn_spu_workaround(mac, phy->chan);
7019 	BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
7020 	bwn_set_original_gains(mac);
7021 	BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
7022 	if (phy->rev >= 3) {
7023 		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
7024 			BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
7025 			    save_phy3[phy3_idx]);
7026 		}
7027 	}
7028 
7029 	delta = 0x1f - pg->pg_nrssi[0];
7030 	for (i = 0; i < 64; i++) {
7031 		tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
7032 		tmp32 = MIN(MAX(tmp32, 0), 0x3f);
7033 		pg->pg_nrssi_lt[i] = tmp32;
7034 	}
7035 
7036 	bwn_nrssi_threshold(mac);
7037 #undef SAVE_RF_MAX
7038 #undef SAVE_PHY_COMM_MAX
7039 #undef SAVE_PHY3_MAX
7040 }
7041 
7042 static void
7043 bwn_nrssi_offset(struct bwn_mac *mac)
7044 {
7045 #define	SAVE_RF_MAX		2
7046 #define	SAVE_PHY_COMM_MAX	10
7047 #define	SAVE_PHY6_MAX		8
7048 	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
7049 		{ 0x7a, 0x43 };
7050 	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
7051 		0x0001, 0x0811, 0x0812, 0x0814,
7052 		0x0815, 0x005a, 0x0059, 0x0058,
7053 		0x000a, 0x0003
7054 	};
7055 	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
7056 		0x002e, 0x002f, 0x080f, 0x0810,
7057 		0x0801, 0x0060, 0x0014, 0x0478
7058 	};
7059 	struct bwn_phy *phy = &mac->mac_phy;
7060 	int i, phy6_idx = 0;
7061 	uint16_t save_rf[SAVE_RF_MAX];
7062 	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
7063 	uint16_t save_phy6[SAVE_PHY6_MAX];
7064 	int16_t nrssi;
7065 	uint16_t saved = 0xffff;
7066 
7067 	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
7068 		save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
7069 	for (i = 0; i < SAVE_RF_MAX; ++i)
7070 		save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
7071 
7072 	BWN_PHY_MASK(mac, 0x0429, 0x7fff);
7073 	BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
7074 	BWN_PHY_SET(mac, 0x0811, 0x000c);
7075 	BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
7076 	BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
7077 	if (phy->rev >= 6) {
7078 		for (i = 0; i < SAVE_PHY6_MAX; ++i)
7079 			save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
7080 
7081 		BWN_PHY_WRITE(mac, 0x002e, 0);
7082 		BWN_PHY_WRITE(mac, 0x002f, 0);
7083 		BWN_PHY_WRITE(mac, 0x080f, 0);
7084 		BWN_PHY_WRITE(mac, 0x0810, 0);
7085 		BWN_PHY_SET(mac, 0x0478, 0x0100);
7086 		BWN_PHY_SET(mac, 0x0801, 0x0040);
7087 		BWN_PHY_SET(mac, 0x0060, 0x0040);
7088 		BWN_PHY_SET(mac, 0x0014, 0x0200);
7089 	}
7090 	BWN_RF_SET(mac, 0x007a, 0x0070);
7091 	BWN_RF_SET(mac, 0x007a, 0x0080);
7092 	DELAY(30);
7093 
7094 	nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7095 	if (nrssi >= 0x20)
7096 		nrssi -= 0x40;
7097 	if (nrssi == 31) {
7098 		for (i = 7; i >= 4; i--) {
7099 			BWN_RF_WRITE(mac, 0x007b, i);
7100 			DELAY(20);
7101 			nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7102 			    0x003f);
7103 			if (nrssi >= 0x20)
7104 				nrssi -= 0x40;
7105 			if (nrssi < 31 && saved == 0xffff)
7106 				saved = i;
7107 		}
7108 		if (saved == 0xffff)
7109 			saved = 4;
7110 	} else {
7111 		BWN_RF_MASK(mac, 0x007a, 0x007f);
7112 		if (phy->rev != 1) {
7113 			BWN_PHY_SET(mac, 0x0814, 0x0001);
7114 			BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7115 		}
7116 		BWN_PHY_SET(mac, 0x0811, 0x000c);
7117 		BWN_PHY_SET(mac, 0x0812, 0x000c);
7118 		BWN_PHY_SET(mac, 0x0811, 0x0030);
7119 		BWN_PHY_SET(mac, 0x0812, 0x0030);
7120 		BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7121 		BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7122 		BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7123 		if (phy->rev == 0)
7124 			BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7125 		else
7126 			BWN_PHY_SET(mac, 0x000a, 0x2000);
7127 		if (phy->rev != 1) {
7128 			BWN_PHY_SET(mac, 0x0814, 0x0004);
7129 			BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7130 		}
7131 		BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7132 		BWN_RF_SET(mac, 0x007a, 0x000f);
7133 		bwn_set_all_gains(mac, 3, 0, 1);
7134 		BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7135 		DELAY(30);
7136 		nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7137 		if (nrssi >= 0x20)
7138 			nrssi -= 0x40;
7139 		if (nrssi == -32) {
7140 			for (i = 0; i < 4; i++) {
7141 				BWN_RF_WRITE(mac, 0x007b, i);
7142 				DELAY(20);
7143 				nrssi = (int16_t)((BWN_PHY_READ(mac,
7144 				    0x047f) >> 8) & 0x003f);
7145 				if (nrssi >= 0x20)
7146 					nrssi -= 0x40;
7147 				if (nrssi > -31 && saved == 0xffff)
7148 					saved = i;
7149 			}
7150 			if (saved == 0xffff)
7151 				saved = 3;
7152 		} else
7153 			saved = 0;
7154 	}
7155 	BWN_RF_WRITE(mac, 0x007b, saved);
7156 
7157 	/*
7158 	 * Restore saved RF/PHY registers
7159 	 */
7160 	if (phy->rev >= 6) {
7161 		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7162 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7163 			    save_phy6[phy6_idx]);
7164 		}
7165 	}
7166 	if (phy->rev != 1) {
7167 		for (i = 3; i < 5; i++)
7168 			BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7169 			    save_phy_comm[i]);
7170 	}
7171 	for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7172 		BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7173 
7174 	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7175 		BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7176 
7177 	BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7178 	BWN_PHY_SET(mac, 0x0429, 0x8000);
7179 	bwn_set_original_gains(mac);
7180 	if (phy->rev >= 6) {
7181 		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7182 			BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7183 			    save_phy6[phy6_idx]);
7184 		}
7185 	}
7186 
7187 	BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7188 	BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7189 	BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7190 }
7191 
7192 static void
7193 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7194     int16_t third)
7195 {
7196 	struct bwn_phy *phy = &mac->mac_phy;
7197 	uint16_t i;
7198 	uint16_t start = 0x08, end = 0x18;
7199 	uint16_t tmp;
7200 	uint16_t table;
7201 
7202 	if (phy->rev <= 1) {
7203 		start = 0x10;
7204 		end = 0x20;
7205 	}
7206 
7207 	table = BWN_OFDMTAB_GAINX;
7208 	if (phy->rev <= 1)
7209 		table = BWN_OFDMTAB_GAINX_R1;
7210 	for (i = 0; i < 4; i++)
7211 		bwn_ofdmtab_write_2(mac, table, i, first);
7212 
7213 	for (i = start; i < end; i++)
7214 		bwn_ofdmtab_write_2(mac, table, i, second);
7215 
7216 	if (third != -1) {
7217 		tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7218 		BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7219 		BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7220 		BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7221 	}
7222 	bwn_dummy_transmission(mac, 0, 1);
7223 }
7224 
7225 static void
7226 bwn_set_original_gains(struct bwn_mac *mac)
7227 {
7228 	struct bwn_phy *phy = &mac->mac_phy;
7229 	uint16_t i, tmp;
7230 	uint16_t table;
7231 	uint16_t start = 0x0008, end = 0x0018;
7232 
7233 	if (phy->rev <= 1) {
7234 		start = 0x0010;
7235 		end = 0x0020;
7236 	}
7237 
7238 	table = BWN_OFDMTAB_GAINX;
7239 	if (phy->rev <= 1)
7240 		table = BWN_OFDMTAB_GAINX_R1;
7241 	for (i = 0; i < 4; i++) {
7242 		tmp = (i & 0xfffc);
7243 		tmp |= (i & 0x0001) << 1;
7244 		tmp |= (i & 0x0002) >> 1;
7245 
7246 		bwn_ofdmtab_write_2(mac, table, i, tmp);
7247 	}
7248 
7249 	for (i = start; i < end; i++)
7250 		bwn_ofdmtab_write_2(mac, table, i, i - start);
7251 
7252 	BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7253 	BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7254 	BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7255 	bwn_dummy_transmission(mac, 0, 1);
7256 }
7257 
7258 static void
7259 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7260 {
7261 	struct siba_softc *bus = mac->mac_sd->sd_bus;
7262 	struct bwn_phy *phy = &mac->mac_phy;
7263 	struct bwn_phy_g *pg = &phy->phy_g;
7264 	struct bwn_rfatt old_rfatt, rfatt;
7265 	struct bwn_bbatt old_bbatt, bbatt;
7266 	uint8_t old_txctl = 0;
7267 
7268 	KASSERT(phy->type == BWN_PHYTYPE_G,
7269 	    ("%s:%d: fail", __func__, __LINE__));
7270 
7271 	if ((bus->siba_board_vendor == SIBA_BOARDVENDOR_BCM) &&
7272 	    (bus->siba_board_type == SIBA_BOARD_BU4306))
7273 		return;
7274 
7275 	BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7276 
7277 	BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7278 
7279 	if (!phy->gmode)
7280 		return;
7281 	bwn_hwpctl_early_init(mac);
7282 	if (pg->pg_curtssi == 0) {
7283 		if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7284 			BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7285 		} else {
7286 			memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7287 			memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7288 			old_txctl = pg->pg_txctl;
7289 
7290 			bbatt.att = 11;
7291 			if (phy->rf_rev == 8) {
7292 				rfatt.att = 15;
7293 				rfatt.padmix = 1;
7294 			} else {
7295 				rfatt.att = 9;
7296 				rfatt.padmix = 0;
7297 			}
7298 			bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7299 		}
7300 		bwn_dummy_transmission(mac, 0, 1);
7301 		pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7302 		if (phy->rf_ver == 0x2050 && phy->analog == 0)
7303 			BWN_RF_MASK(mac, 0x0076, 0xff7b);
7304 		else
7305 			bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7306 			    &old_rfatt, old_txctl);
7307 	}
7308 	bwn_hwpctl_init_gphy(mac);
7309 
7310 	/* clear TSSI */
7311 	bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7312 	bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7313 	bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7314 	bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7315 }
7316 
7317 static void
7318 bwn_hwpctl_early_init(struct bwn_mac *mac)
7319 {
7320 	struct bwn_phy *phy = &mac->mac_phy;
7321 
7322 	if (!bwn_has_hwpctl(mac)) {
7323 		BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7324 		return;
7325 	}
7326 
7327 	BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7328 	BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7329 	BWN_PHY_SET(mac, 0x047c, 0x0002);
7330 	BWN_PHY_SET(mac, 0x047a, 0xf000);
7331 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7332 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7333 		BWN_PHY_SET(mac, 0x005d, 0x8000);
7334 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7335 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7336 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7337 	} else {
7338 		BWN_PHY_SET(mac, 0x0036, 0x0200);
7339 		BWN_PHY_SET(mac, 0x0036, 0x0400);
7340 		BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7341 		BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7342 		BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7343 		BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7344 		BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7345 	}
7346 }
7347 
7348 static void
7349 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7350 {
7351 	struct bwn_phy *phy = &mac->mac_phy;
7352 	struct bwn_phy_g *pg = &phy->phy_g;
7353 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7354 	int i;
7355 	uint16_t nr_written = 0, tmp, value;
7356 	uint8_t rf, bb;
7357 
7358 	if (!bwn_has_hwpctl(mac)) {
7359 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7360 		return;
7361 	}
7362 
7363 	BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7364 	    (pg->pg_idletssi - pg->pg_curtssi));
7365 	BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7366 	    (pg->pg_idletssi - pg->pg_curtssi));
7367 
7368 	for (i = 0; i < 32; i++)
7369 		bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7370 	for (i = 32; i < 64; i++)
7371 		bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7372 	for (i = 0; i < 64; i += 2) {
7373 		value = (uint16_t) pg->pg_tssi2dbm[i];
7374 		value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7375 		BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7376 	}
7377 
7378 	for (rf = 0; rf < lo->rfatt.len; rf++) {
7379 		for (bb = 0; bb < lo->bbatt.len; bb++) {
7380 			if (nr_written >= 0x40)
7381 				return;
7382 			tmp = lo->bbatt.array[bb].att;
7383 			tmp <<= 8;
7384 			if (phy->rf_rev == 8)
7385 				tmp |= 0x50;
7386 			else
7387 				tmp |= 0x40;
7388 			tmp |= lo->rfatt.array[rf].att;
7389 			BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7390 			nr_written++;
7391 		}
7392 	}
7393 
7394 	BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7395 	BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7396 
7397 	KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7398 	BWN_PHY_SET(mac, 0x0478, 0x0800);
7399 	BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7400 	BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7401 
7402 	bwn_phy_g_dc_lookup_init(mac, 1);
7403 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7404 }
7405 
7406 static void
7407 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7408 {
7409 	struct siba_softc *siba = mac->mac_sd->sd_bus;
7410 
7411 	if (spu != 0)
7412 		bwn_spu_workaround(mac, channel);
7413 
7414 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7415 
7416 	if (channel == 14) {
7417 		if (siba->siba_sprom.ccode == SIBA_CCODE_JAPAN)
7418 			bwn_hf_write(mac,
7419 			    bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7420 		else
7421 			bwn_hf_write(mac,
7422 			    bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7423 		BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7424 		    BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7425 		return;
7426 	}
7427 
7428 	BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7429 	    BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7430 }
7431 
7432 static uint16_t
7433 bwn_phy_g_chan2freq(uint8_t channel)
7434 {
7435 	static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7436 
7437 	KASSERT(channel >= 1 && channel <= 14,
7438 	    ("%s:%d: fail", __func__, __LINE__));
7439 
7440 	return (bwn_phy_g_rf_channels[channel - 1]);
7441 }
7442 
7443 static void
7444 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7445     const struct bwn_rfatt *rfatt, uint8_t txctl)
7446 {
7447 	struct bwn_phy *phy = &mac->mac_phy;
7448 	struct bwn_phy_g *pg = &phy->phy_g;
7449 	struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7450 	uint16_t bb, rf;
7451 	uint16_t tx_bias, tx_magn;
7452 
7453 	bb = bbatt->att;
7454 	rf = rfatt->att;
7455 	tx_bias = lo->tx_bias;
7456 	tx_magn = lo->tx_magn;
7457 	if (tx_bias == 0xff)
7458 		tx_bias = 0;
7459 
7460 	pg->pg_txctl = txctl;
7461 	memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7462 	pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7463 	memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7464 	bwn_phy_g_set_bbatt(mac, bb);
7465 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7466 	if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7467 		BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7468 	else {
7469 		BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7470 		BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7471 	}
7472 	if (BWN_HAS_TXMAG(phy))
7473 		BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7474 	else
7475 		BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7476 	bwn_lo_g_adjust(mac);
7477 }
7478 
7479 static void
7480 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7481     uint16_t bbatt)
7482 {
7483 	struct bwn_phy *phy = &mac->mac_phy;
7484 
7485 	if (phy->analog == 0) {
7486 		BWN_WRITE_2(mac, BWN_PHY0,
7487 		    (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7488 		return;
7489 	}
7490 	if (phy->analog > 1) {
7491 		BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7492 		return;
7493 	}
7494 	BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7495 }
7496 
7497 static uint16_t
7498 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7499 {
7500 	struct bwn_phy *phy = &mac->mac_phy;
7501 	struct bwn_phy_g *pg = &phy->phy_g;
7502 	struct siba_sprom *sprom = &(mac->mac_sd->sd_bus->siba_sprom);
7503 	int max_lb_gain;
7504 	uint16_t extlna;
7505 	uint16_t i;
7506 
7507 	if (phy->gmode == 0)
7508 		return (0);
7509 
7510 	if (BWN_HAS_LOOPBACK(phy)) {
7511 		max_lb_gain = pg->pg_max_lb_gain;
7512 		max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7513 		if (max_lb_gain >= 0x46) {
7514 			extlna = 0x3000;
7515 			max_lb_gain -= 0x46;
7516 		} else if (max_lb_gain >= 0x3a) {
7517 			extlna = 0x1000;
7518 			max_lb_gain -= 0x3a;
7519 		} else if (max_lb_gain >= 0x2e) {
7520 			extlna = 0x2000;
7521 			max_lb_gain -= 0x2e;
7522 		} else {
7523 			extlna = 0;
7524 			max_lb_gain -= 0x10;
7525 		}
7526 
7527 		for (i = 0; i < 16; i++) {
7528 			max_lb_gain -= (i * 6);
7529 			if (max_lb_gain < 6)
7530 				break;
7531 		}
7532 
7533 		if ((phy->rev < 7) || !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
7534 			if (reg == BWN_PHY_RFOVER) {
7535 				return (0x1b3);
7536 			} else if (reg == BWN_PHY_RFOVERVAL) {
7537 				extlna |= (i << 8);
7538 				switch (lpd) {
7539 				case BWN_LPD(0, 1, 1):
7540 					return (0x0f92);
7541 				case BWN_LPD(0, 0, 1):
7542 				case BWN_LPD(1, 0, 1):
7543 					return (0x0092 | extlna);
7544 				case BWN_LPD(1, 0, 0):
7545 					return (0x0093 | extlna);
7546 				}
7547 				KASSERT(0 == 1,
7548 				    ("%s:%d: fail", __func__, __LINE__));
7549 			}
7550 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7551 		} else {
7552 			if (reg == BWN_PHY_RFOVER)
7553 				return (0x9b3);
7554 			if (reg == BWN_PHY_RFOVERVAL) {
7555 				if (extlna)
7556 					extlna |= 0x8000;
7557 				extlna |= (i << 8);
7558 				switch (lpd) {
7559 				case BWN_LPD(0, 1, 1):
7560 					return (0x8f92);
7561 				case BWN_LPD(0, 0, 1):
7562 					return (0x8092 | extlna);
7563 				case BWN_LPD(1, 0, 1):
7564 					return (0x2092 | extlna);
7565 				case BWN_LPD(1, 0, 0):
7566 					return (0x2093 | extlna);
7567 				}
7568 				KASSERT(0 == 1,
7569 				    ("%s:%d: fail", __func__, __LINE__));
7570 			}
7571 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7572 		}
7573 		return (0);
7574 	}
7575 
7576 	if ((phy->rev < 7) ||
7577 	    !(sprom->bf_lo & BWN_BFL_EXTLNA)) {
7578 		if (reg == BWN_PHY_RFOVER) {
7579 			return (0x1b3);
7580 		} else if (reg == BWN_PHY_RFOVERVAL) {
7581 			switch (lpd) {
7582 			case BWN_LPD(0, 1, 1):
7583 				return (0x0fb2);
7584 			case BWN_LPD(0, 0, 1):
7585 				return (0x00b2);
7586 			case BWN_LPD(1, 0, 1):
7587 				return (0x30b2);
7588 			case BWN_LPD(1, 0, 0):
7589 				return (0x30b3);
7590 			}
7591 			KASSERT(0 == 1,
7592 			    ("%s:%d: fail", __func__, __LINE__));
7593 		}
7594 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7595 	} else {
7596 		if (reg == BWN_PHY_RFOVER) {
7597 			return (0x9b3);
7598 		} else if (reg == BWN_PHY_RFOVERVAL) {
7599 			switch (lpd) {
7600 			case BWN_LPD(0, 1, 1):
7601 				return (0x8fb2);
7602 			case BWN_LPD(0, 0, 1):
7603 				return (0x80b2);
7604 			case BWN_LPD(1, 0, 1):
7605 				return (0x20b2);
7606 			case BWN_LPD(1, 0, 0):
7607 				return (0x20b3);
7608 			}
7609 			KASSERT(0 == 1,
7610 			    ("%s:%d: fail", __func__, __LINE__));
7611 		}
7612 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7613 	}
7614 	return (0);
7615 }
7616 
7617 static void
7618 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7619 {
7620 
7621 	if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7622 		return;
7623 	BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7624 	    bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7625 	DELAY(1000);
7626 	BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7627 }
7628 
7629 static int
7630 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7631 {
7632 	struct bwn_softc *sc = mac->mac_sc;
7633 	struct bwn_fw *fw = &mac->mac_fw;
7634 	const uint8_t rev = mac->mac_sd->sd_id.sd_rev;
7635 	const char *filename;
7636 	uint32_t high;
7637 	int error;
7638 
7639 	/* microcode */
7640 	if (rev >= 5 && rev <= 10)
7641 		filename = "ucode5";
7642 	else if (rev >= 11 && rev <= 12)
7643 		filename = "ucode11";
7644 	else if (rev == 13)
7645 		filename = "ucode13";
7646 	else if (rev == 14)
7647 		filename = "ucode14";
7648 	else if (rev >= 15)
7649 		filename = "ucode15";
7650 	else {
7651 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7652 		bwn_release_firmware(mac);
7653 		return (EOPNOTSUPP);
7654 	}
7655 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
7656 	if (error) {
7657 		bwn_release_firmware(mac);
7658 		return (error);
7659 	}
7660 
7661 	/* PCM */
7662 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7663 	if (rev >= 5 && rev <= 10) {
7664 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7665 		if (error == ENOENT)
7666 			fw->no_pcmfile = 1;
7667 		else if (error) {
7668 			bwn_release_firmware(mac);
7669 			return (error);
7670 		}
7671 	} else if (rev < 11) {
7672 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7673 		return (EOPNOTSUPP);
7674 	}
7675 
7676 	/* initvals */
7677 	high = siba_read_4(mac->mac_sd, SIBA_TGSHIGH);
7678 	switch (mac->mac_phy.type) {
7679 	case BWN_PHYTYPE_A:
7680 		if (rev < 5 || rev > 10)
7681 			goto fail1;
7682 		if (high & BWN_TGSHIGH_HAVE_2GHZ)
7683 			filename = "a0g1initvals5";
7684 		else
7685 			filename = "a0g0initvals5";
7686 		break;
7687 	case BWN_PHYTYPE_G:
7688 		if (rev >= 5 && rev <= 10)
7689 			filename = "b0g0initvals5";
7690 		else if (rev >= 13)
7691 			filename = "b0g0initvals13";
7692 		else
7693 			goto fail1;
7694 		break;
7695 	case BWN_PHYTYPE_LP:
7696 		if (rev == 13)
7697 			filename = "lp0initvals13";
7698 		else if (rev == 14)
7699 			filename = "lp0initvals14";
7700 		else if (rev >= 15)
7701 			filename = "lp0initvals15";
7702 		else
7703 			goto fail1;
7704 		break;
7705 	case BWN_PHYTYPE_N:
7706 		if (rev >= 11 && rev <= 12)
7707 			filename = "n0initvals11";
7708 		else
7709 			goto fail1;
7710 		break;
7711 	default:
7712 		goto fail1;
7713 	}
7714 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
7715 	if (error) {
7716 		bwn_release_firmware(mac);
7717 		return (error);
7718 	}
7719 
7720 	/* bandswitch initvals */
7721 	switch (mac->mac_phy.type) {
7722 	case BWN_PHYTYPE_A:
7723 		if (rev >= 5 && rev <= 10) {
7724 			if (high & BWN_TGSHIGH_HAVE_2GHZ)
7725 				filename = "a0g1bsinitvals5";
7726 			else
7727 				filename = "a0g0bsinitvals5";
7728 		} else if (rev >= 11)
7729 			filename = NULL;
7730 		else
7731 			goto fail1;
7732 		break;
7733 	case BWN_PHYTYPE_G:
7734 		if (rev >= 5 && rev <= 10)
7735 			filename = "b0g0bsinitvals5";
7736 		else if (rev >= 11)
7737 			filename = NULL;
7738 		else
7739 			goto fail1;
7740 		break;
7741 	case BWN_PHYTYPE_LP:
7742 		if (rev == 13)
7743 			filename = "lp0bsinitvals13";
7744 		else if (rev == 14)
7745 			filename = "lp0bsinitvals14";
7746 		else if (rev >= 15)
7747 			filename = "lp0bsinitvals15";
7748 		else
7749 			goto fail1;
7750 		break;
7751 	case BWN_PHYTYPE_N:
7752 		if (rev >= 11 && rev <= 12)
7753 			filename = "n0bsinitvals11";
7754 		else
7755 			goto fail1;
7756 		break;
7757 	default:
7758 		goto fail1;
7759 	}
7760 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7761 	if (error) {
7762 		bwn_release_firmware(mac);
7763 		return (error);
7764 	}
7765 	return (0);
7766 fail1:
7767 	device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7768 	bwn_release_firmware(mac);
7769 	return (EOPNOTSUPP);
7770 }
7771 
7772 static int
7773 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7774     const char *name, struct bwn_fwfile *bfw)
7775 {
7776 	const struct bwn_fwhdr *hdr;
7777 	struct bwn_softc *sc = mac->mac_sc;
7778 	const struct firmware *fw;
7779 	char namebuf[64];
7780 
7781 	if (name == NULL) {
7782 		bwn_do_release_fw(bfw);
7783 		return (0);
7784 	}
7785 	if (bfw->filename != NULL) {
7786 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7787 			return (0);
7788 		bwn_do_release_fw(bfw);
7789 	}
7790 
7791 	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s",
7792 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "", name);
7793 	/* XXX Sleeping on "fwload" with the non-sleepable locks held */
7794 	fw = firmware_get(namebuf);
7795 	if (fw == NULL) {
7796 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7797 		    namebuf);
7798 		return (ENOENT);
7799 	}
7800 	if (fw->datasize < sizeof(struct bwn_fwhdr))
7801 		goto fail;
7802 	hdr = (const struct bwn_fwhdr *)(fw->data);
7803 	switch (hdr->type) {
7804 	case BWN_FWTYPE_UCODE:
7805 	case BWN_FWTYPE_PCM:
7806 		if (be32toh(hdr->size) !=
7807 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
7808 			goto fail;
7809 		/* FALLTHROUGH */
7810 	case BWN_FWTYPE_IV:
7811 		if (hdr->ver != 1)
7812 			goto fail;
7813 		break;
7814 	default:
7815 		goto fail;
7816 	}
7817 	bfw->filename = name;
7818 	bfw->fw = fw;
7819 	bfw->type = type;
7820 	return (0);
7821 fail:
7822 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7823 	if (fw != NULL)
7824 		firmware_put(fw, FIRMWARE_UNLOAD);
7825 	return (EPROTO);
7826 }
7827 
7828 static void
7829 bwn_release_firmware(struct bwn_mac *mac)
7830 {
7831 
7832 	bwn_do_release_fw(&mac->mac_fw.ucode);
7833 	bwn_do_release_fw(&mac->mac_fw.pcm);
7834 	bwn_do_release_fw(&mac->mac_fw.initvals);
7835 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
7836 }
7837 
7838 static void
7839 bwn_do_release_fw(struct bwn_fwfile *bfw)
7840 {
7841 
7842 	if (bfw->fw != NULL)
7843 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7844 	bfw->fw = NULL;
7845 	bfw->filename = NULL;
7846 }
7847 
7848 static int
7849 bwn_fw_loaducode(struct bwn_mac *mac)
7850 {
7851 #define	GETFWOFFSET(fwp, offset)	\
7852 	((const uint32_t *)((const char *)fwp.fw->data + offset))
7853 #define	GETFWSIZE(fwp, offset)	\
7854 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
7855 	struct bwn_softc *sc = mac->mac_sc;
7856 	const uint32_t *data;
7857 	unsigned int i;
7858 	uint32_t ctl;
7859 	uint16_t date, fwcaps, time;
7860 	int error = 0;
7861 
7862 	ctl = BWN_READ_4(mac, BWN_MACCTL);
7863 	ctl |= BWN_MACCTL_MCODE_JMP0;
7864 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7865 	    __LINE__));
7866 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7867 	for (i = 0; i < 64; i++)
7868 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7869 	for (i = 0; i < 4096; i += 2)
7870 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7871 
7872 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7873 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7874 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7875 	     i++) {
7876 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7877 		DELAY(10);
7878 	}
7879 
7880 	if (mac->mac_fw.pcm.fw) {
7881 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7882 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7883 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7884 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7885 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7886 		    sizeof(struct bwn_fwhdr)); i++) {
7887 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7888 			DELAY(10);
7889 		}
7890 	}
7891 
7892 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7893 	BWN_WRITE_4(mac, BWN_MACCTL,
7894 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7895 	    BWN_MACCTL_MCODE_RUN);
7896 
7897 	for (i = 0; i < 21; i++) {
7898 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7899 			break;
7900 		if (i >= 20) {
7901 			device_printf(sc->sc_dev, "ucode timeout\n");
7902 			error = ENXIO;
7903 			goto error;
7904 		}
7905 		DELAY(50000);
7906 	}
7907 	BWN_READ_4(mac, BWN_INTR_REASON);
7908 
7909 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7910 	if (mac->mac_fw.rev <= 0x128) {
7911 		device_printf(sc->sc_dev, "the firmware is too old\n");
7912 		error = EOPNOTSUPP;
7913 		goto error;
7914 	}
7915 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7916 	    BWN_SHARED_UCODE_PATCH);
7917 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7918 	mac->mac_fw.opensource = (date == 0xffff);
7919 	if (bwn_wme != 0)
7920 		mac->mac_flags |= BWN_MAC_FLAG_WME;
7921 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7922 
7923 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7924 	if (mac->mac_fw.opensource == 0) {
7925 		device_printf(sc->sc_dev,
7926 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
7927 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7928 		if (mac->mac_fw.no_pcmfile)
7929 			device_printf(sc->sc_dev,
7930 			    "no HW crypto acceleration due to pcm5\n");
7931 	} else {
7932 		mac->mac_fw.patch = time;
7933 		fwcaps = bwn_fwcaps_read(mac);
7934 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7935 			device_printf(sc->sc_dev,
7936 			    "disabling HW crypto acceleration\n");
7937 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7938 		}
7939 		if (!(fwcaps & BWN_FWCAPS_WME)) {
7940 			device_printf(sc->sc_dev, "disabling WME support\n");
7941 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7942 		}
7943 	}
7944 
7945 	if (BWN_ISOLDFMT(mac))
7946 		device_printf(sc->sc_dev, "using old firmware image\n");
7947 
7948 	return (0);
7949 
7950 error:
7951 	BWN_WRITE_4(mac, BWN_MACCTL,
7952 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7953 	    BWN_MACCTL_MCODE_JMP0);
7954 
7955 	return (error);
7956 #undef GETFWSIZE
7957 #undef GETFWOFFSET
7958 }
7959 
7960 /* OpenFirmware only */
7961 static uint16_t
7962 bwn_fwcaps_read(struct bwn_mac *mac)
7963 {
7964 
7965 	KASSERT(mac->mac_fw.opensource == 1,
7966 	    ("%s:%d: fail", __func__, __LINE__));
7967 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7968 }
7969 
7970 static int
7971 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7972     size_t count, size_t array_size)
7973 {
7974 #define	GET_NEXTIV16(iv)						\
7975 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7976 	    sizeof(uint16_t) + sizeof(uint16_t)))
7977 #define	GET_NEXTIV32(iv)						\
7978 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
7979 	    sizeof(uint16_t) + sizeof(uint32_t)))
7980 	struct bwn_softc *sc = mac->mac_sc;
7981 	const struct bwn_fwinitvals *iv;
7982 	uint16_t offset;
7983 	size_t i;
7984 	uint8_t bit32;
7985 
7986 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7987 	    ("%s:%d: fail", __func__, __LINE__));
7988 	iv = ivals;
7989 	for (i = 0; i < count; i++) {
7990 		if (array_size < sizeof(iv->offset_size))
7991 			goto fail;
7992 		array_size -= sizeof(iv->offset_size);
7993 		offset = be16toh(iv->offset_size);
7994 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7995 		offset &= BWN_FWINITVALS_OFFSET_MASK;
7996 		if (offset >= 0x1000)
7997 			goto fail;
7998 		if (bit32) {
7999 			if (array_size < sizeof(iv->data.d32))
8000 				goto fail;
8001 			array_size -= sizeof(iv->data.d32);
8002 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
8003 			iv = GET_NEXTIV32(iv);
8004 		} else {
8005 
8006 			if (array_size < sizeof(iv->data.d16))
8007 				goto fail;
8008 			array_size -= sizeof(iv->data.d16);
8009 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
8010 
8011 			iv = GET_NEXTIV16(iv);
8012 		}
8013 	}
8014 	if (array_size != 0)
8015 		goto fail;
8016 	return (0);
8017 fail:
8018 	device_printf(sc->sc_dev, "initvals: invalid format\n");
8019 	return (EPROTO);
8020 #undef GET_NEXTIV16
8021 #undef GET_NEXTIV32
8022 }
8023 
8024 static int
8025 bwn_switch_channel(struct bwn_mac *mac, int chan)
8026 {
8027 	struct bwn_phy *phy = &(mac->mac_phy);
8028 	struct bwn_softc *sc = mac->mac_sc;
8029 	struct ifnet *ifp = sc->sc_ifp;
8030 	struct ieee80211com *ic = ifp->if_l2com;
8031 	uint16_t channelcookie, savedcookie;
8032 	int error;
8033 
8034 	if (chan == 0xffff)
8035 		chan = phy->get_default_chan(mac);
8036 
8037 	channelcookie = chan;
8038 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
8039 		channelcookie |= 0x100;
8040 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
8041 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
8042 	error = phy->switch_channel(mac, chan);
8043 	if (error)
8044 		goto fail;
8045 
8046 	mac->mac_phy.chan = chan;
8047 	DELAY(8000);
8048 	return (0);
8049 fail:
8050 	device_printf(sc->sc_dev, "failed to switch channel\n");
8051 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
8052 	return (error);
8053 }
8054 
8055 static uint16_t
8056 bwn_ant2phy(int antenna)
8057 {
8058 
8059 	switch (antenna) {
8060 	case BWN_ANT0:
8061 		return (BWN_TX_PHY_ANT0);
8062 	case BWN_ANT1:
8063 		return (BWN_TX_PHY_ANT1);
8064 	case BWN_ANT2:
8065 		return (BWN_TX_PHY_ANT2);
8066 	case BWN_ANT3:
8067 		return (BWN_TX_PHY_ANT3);
8068 	case BWN_ANTAUTO:
8069 		return (BWN_TX_PHY_ANT01AUTO);
8070 	}
8071 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8072 	return (0);
8073 }
8074 
8075 static void
8076 bwn_wme_load(struct bwn_mac *mac)
8077 {
8078 	struct bwn_softc *sc = mac->mac_sc;
8079 	int i;
8080 
8081 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8082 	    ("%s:%d: fail", __func__, __LINE__));
8083 
8084 	bwn_mac_suspend(mac);
8085 	for (i = 0; i < N(sc->sc_wmeParams); i++)
8086 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8087 		    bwn_wme_shm_offsets[i]);
8088 	bwn_mac_enable(mac);
8089 }
8090 
8091 static void
8092 bwn_wme_loadparams(struct bwn_mac *mac,
8093     const struct wmeParams *p, uint16_t shm_offset)
8094 {
8095 #define	SM(_v, _f)      (((_v) << _f##_S) & _f)
8096 	struct bwn_softc *sc = mac->mac_sc;
8097 	uint16_t params[BWN_NR_WMEPARAMS];
8098 	int slot, tmp;
8099 	unsigned int i;
8100 
8101 	slot = BWN_READ_2(mac, BWN_RNG) &
8102 	    SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8103 
8104 	memset(&params, 0, sizeof(params));
8105 
8106 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8107 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8108 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8109 
8110 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8111 	params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8112 	params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8113 	params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8114 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8115 	params[BWN_WMEPARAM_BSLOTS] = slot;
8116 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8117 
8118 	for (i = 0; i < N(params); i++) {
8119 		if (i == BWN_WMEPARAM_STATUS) {
8120 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
8121 			    shm_offset + (i * 2));
8122 			tmp |= 0x100;
8123 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8124 			    tmp);
8125 		} else {
8126 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8127 			    params[i]);
8128 		}
8129 	}
8130 }
8131 
8132 static void
8133 bwn_mac_write_bssid(struct bwn_mac *mac)
8134 {
8135 	struct bwn_softc *sc = mac->mac_sc;
8136 	uint32_t tmp;
8137 	int i;
8138 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8139 
8140 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8141 	memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8142 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8143 	    IEEE80211_ADDR_LEN);
8144 
8145 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8146 		tmp = (uint32_t) (mac_bssid[i + 0]);
8147 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8148 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8149 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8150 		bwn_ram_write(mac, 0x20 + i, tmp);
8151 	}
8152 }
8153 
8154 static void
8155 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8156     const uint8_t *macaddr)
8157 {
8158 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8159 	uint16_t data;
8160 
8161 	if (!mac)
8162 		macaddr = zero;
8163 
8164 	offset |= 0x0020;
8165 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8166 
8167 	data = macaddr[0];
8168 	data |= macaddr[1] << 8;
8169 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8170 	data = macaddr[2];
8171 	data |= macaddr[3] << 8;
8172 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8173 	data = macaddr[4];
8174 	data |= macaddr[5] << 8;
8175 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8176 }
8177 
8178 static void
8179 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8180     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8181 {
8182 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8183 	uint8_t per_sta_keys_start = 8;
8184 
8185 	if (BWN_SEC_NEWAPI(mac))
8186 		per_sta_keys_start = 4;
8187 
8188 	KASSERT(index < mac->mac_max_nr_keys,
8189 	    ("%s:%d: fail", __func__, __LINE__));
8190 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
8191 	    ("%s:%d: fail", __func__, __LINE__));
8192 
8193 	if (index >= per_sta_keys_start)
8194 		bwn_key_macwrite(mac, index, NULL);
8195 	if (key)
8196 		memcpy(buf, key, key_len);
8197 	bwn_key_write(mac, index, algorithm, buf);
8198 	if (index >= per_sta_keys_start)
8199 		bwn_key_macwrite(mac, index, mac_addr);
8200 
8201 	mac->mac_key[index].algorithm = algorithm;
8202 }
8203 
8204 static void
8205 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8206 {
8207 	uint32_t addrtmp[2] = { 0, 0 };
8208 	uint8_t start = 8;
8209 
8210 	if (BWN_SEC_NEWAPI(mac))
8211 		start = 4;
8212 
8213 	KASSERT(index >= start,
8214 	    ("%s:%d: fail", __func__, __LINE__));
8215 	index -= start;
8216 
8217 	if (addr) {
8218 		addrtmp[0] = addr[0];
8219 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8220 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8221 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8222 		addrtmp[1] = addr[4];
8223 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8224 	}
8225 
8226 	if (mac->mac_sd->sd_id.sd_rev >= 5) {
8227 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8228 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8229 	} else {
8230 		if (index >= 8) {
8231 			bwn_shm_write_4(mac, BWN_SHARED,
8232 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8233 			bwn_shm_write_2(mac, BWN_SHARED,
8234 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8235 		}
8236 	}
8237 }
8238 
8239 static void
8240 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8241     const uint8_t *key)
8242 {
8243 	unsigned int i;
8244 	uint32_t offset;
8245 	uint16_t kidx, value;
8246 
8247 	kidx = BWN_SEC_KEY2FW(mac, index);
8248 	bwn_shm_write_2(mac, BWN_SHARED,
8249 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8250 
8251 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8252 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8253 		value = key[i];
8254 		value |= (uint16_t)(key[i + 1]) << 8;
8255 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8256 	}
8257 }
8258 
8259 static void
8260 bwn_phy_exit(struct bwn_mac *mac)
8261 {
8262 
8263 	mac->mac_phy.rf_onoff(mac, 0);
8264 	if (mac->mac_phy.exit != NULL)
8265 		mac->mac_phy.exit(mac);
8266 }
8267 
8268 static void
8269 bwn_dma_free(struct bwn_mac *mac)
8270 {
8271 	struct bwn_dma *dma;
8272 
8273 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8274 		return;
8275 	dma = &mac->mac_method.dma;
8276 
8277 	bwn_dma_ringfree(&dma->rx);
8278 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8279 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8280 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8281 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8282 	bwn_dma_ringfree(&dma->mcast);
8283 }
8284 
8285 static void
8286 bwn_core_stop(struct bwn_mac *mac)
8287 {
8288 	struct bwn_softc *sc = mac->mac_sc;
8289 
8290 	BWN_ASSERT_LOCKED(sc);
8291 
8292 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8293 		return;
8294 
8295 	callout_stop(&sc->sc_rfswitch_ch);
8296 	callout_stop(&sc->sc_task_ch);
8297 	callout_stop(&sc->sc_watchdog_ch);
8298 	sc->sc_watchdog_timer = 0;
8299 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8300 	BWN_READ_4(mac, BWN_INTR_MASK);
8301 	bwn_mac_suspend(mac);
8302 
8303 	mac->mac_status = BWN_MAC_STATUS_INITED;
8304 }
8305 
8306 static int
8307 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8308 {
8309 	struct bwn_mac *up_dev = NULL;
8310 	struct bwn_mac *down_dev;
8311 	struct bwn_mac *mac;
8312 	int err, status;
8313 	uint8_t gmode;
8314 
8315 	BWN_ASSERT_LOCKED(sc);
8316 
8317 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8318 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8319 		    mac->mac_phy.supports_2ghz) {
8320 			up_dev = mac;
8321 			gmode = 1;
8322 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8323 		    mac->mac_phy.supports_5ghz) {
8324 			up_dev = mac;
8325 			gmode = 0;
8326 		} else {
8327 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8328 			return (EINVAL);
8329 		}
8330 		if (up_dev != NULL)
8331 			break;
8332 	}
8333 	if (up_dev == NULL) {
8334 		device_printf(sc->sc_dev, "Could not find a device\n");
8335 		return (ENODEV);
8336 	}
8337 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8338 		return (0);
8339 
8340 	device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8341 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8342 
8343 	down_dev = sc->sc_curmac;;
8344 	status = down_dev->mac_status;
8345 	if (status >= BWN_MAC_STATUS_STARTED)
8346 		bwn_core_stop(down_dev);
8347 	if (status >= BWN_MAC_STATUS_INITED)
8348 		bwn_core_exit(down_dev);
8349 
8350 	if (down_dev != up_dev)
8351 		bwn_phy_reset(down_dev);
8352 
8353 	up_dev->mac_phy.gmode = gmode;
8354 	if (status >= BWN_MAC_STATUS_INITED) {
8355 		err = bwn_core_init(up_dev);
8356 		if (err) {
8357 			device_printf(sc->sc_dev,
8358 			    "fatal: failed to initialize for %s-GHz\n",
8359 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8360 			goto fail;
8361 		}
8362 	}
8363 	if (status >= BWN_MAC_STATUS_STARTED)
8364 		bwn_core_start(up_dev);
8365 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8366 	sc->sc_curmac = up_dev;
8367 
8368 	return (0);
8369 fail:
8370 	sc->sc_curmac = NULL;
8371 	return (err);
8372 }
8373 
8374 static void
8375 bwn_rf_turnon(struct bwn_mac *mac)
8376 {
8377 
8378 	bwn_mac_suspend(mac);
8379 	mac->mac_phy.rf_onoff(mac, 1);
8380 	mac->mac_phy.rf_on = 1;
8381 	bwn_mac_enable(mac);
8382 }
8383 
8384 static void
8385 bwn_rf_turnoff(struct bwn_mac *mac)
8386 {
8387 
8388 	bwn_mac_suspend(mac);
8389 	mac->mac_phy.rf_onoff(mac, 0);
8390 	mac->mac_phy.rf_on = 0;
8391 	bwn_mac_enable(mac);
8392 }
8393 
8394 static void
8395 bwn_phy_reset(struct bwn_mac *mac)
8396 {
8397 	struct siba_dev_softc *sd = mac->mac_sd;
8398 
8399 	siba_write_4(sd, SIBA_TGSLOW,
8400 	    ((siba_read_4(sd, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8401 	     BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8402 	DELAY(1000);
8403 	siba_write_4(sd, SIBA_TGSLOW,
8404 	    (siba_read_4(sd, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8405 	    BWN_TGSLOW_PHYRESET);
8406 	DELAY(1000);
8407 }
8408 
8409 static int
8410 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8411 {
8412 	struct bwn_vap *bvp = BWN_VAP(vap);
8413 	struct ieee80211com *ic= vap->iv_ic;
8414 	struct ifnet *ifp = ic->ic_ifp;
8415 	enum ieee80211_state ostate = vap->iv_state;
8416 	struct bwn_softc *sc = ifp->if_softc;
8417 	struct bwn_mac *mac = sc->sc_curmac;
8418 	int error;
8419 
8420 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8421 	    ieee80211_state_name[vap->iv_state],
8422 	    ieee80211_state_name[nstate]);
8423 
8424 	error = bvp->bv_newstate(vap, nstate, arg);
8425 	if (error != 0)
8426 		return (error);
8427 
8428 	BWN_LOCK(sc);
8429 
8430 	bwn_led_newstate(mac, nstate);
8431 
8432 	/*
8433 	 * Clear the BSSID when we stop a STA
8434 	 */
8435 	if (vap->iv_opmode == IEEE80211_M_STA) {
8436 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8437 			/*
8438 			 * Clear out the BSSID.  If we reassociate to
8439 			 * the same AP, this will reinialize things
8440 			 * correctly...
8441 			 */
8442 			if (ic->ic_opmode == IEEE80211_M_STA &&
8443 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8444 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8445 				bwn_set_macaddr(mac);
8446 			}
8447 		}
8448 	}
8449 
8450 	if (vap->iv_opmode == IEEE80211_M_MONITOR) {
8451 		/* XXX nothing to do? */
8452 	} else if (nstate == IEEE80211_S_RUN) {
8453 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8454 		memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8455 		bwn_set_opmode(mac);
8456 		bwn_set_pretbtt(mac);
8457 		bwn_spu_setdelay(mac, 0);
8458 		bwn_set_macaddr(mac);
8459 	}
8460 
8461 	BWN_UNLOCK(sc);
8462 
8463 	return (error);
8464 }
8465 
8466 static void
8467 bwn_set_pretbtt(struct bwn_mac *mac)
8468 {
8469 	struct bwn_softc *sc = mac->mac_sc;
8470 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8471 	uint16_t pretbtt;
8472 
8473 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8474 		pretbtt = 2;
8475 	else
8476 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8477 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8478 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8479 }
8480 
8481 static int
8482 bwn_intr(void *arg)
8483 {
8484 	struct bwn_mac *mac = arg;
8485 	struct bwn_softc *sc = mac->mac_sc;
8486 	struct siba_softc *siba = mac->mac_sd->sd_bus;
8487 	uint32_t reason;
8488 
8489 	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid)
8490 		return (FILTER_STRAY);
8491 
8492 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
8493 	if (reason == 0xffffffff)	/* shared IRQ */
8494 		return (FILTER_STRAY);
8495 	reason &= mac->mac_intr_mask;
8496 	if (reason == 0)
8497 		return (FILTER_HANDLED);
8498 
8499 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8500 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8501 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8502 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8503 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8504 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8505 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8506 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8507 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8508 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8509 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8510 
8511 	/* Disable interrupts. */
8512 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8513 
8514 	mac->mac_reason_intr = reason;
8515 
8516 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8517 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8518 
8519 	taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8520 	return (FILTER_HANDLED);
8521 }
8522 
8523 static void
8524 bwn_intrtask(void *arg, int npending)
8525 {
8526 	struct bwn_mac *mac = arg;
8527 	struct bwn_softc *sc = mac->mac_sc;
8528 	struct ifnet *ifp = sc->sc_ifp;
8529 	struct siba_softc *siba = mac->mac_sd->sd_bus;
8530 	uint32_t merged = 0;
8531 	int i, tx = 0, rx = 0;
8532 
8533 	BWN_LOCK(sc);
8534 	if (mac->mac_status < BWN_MAC_STATUS_STARTED || siba->siba_invalid) {
8535 		BWN_UNLOCK(sc);
8536 		return;
8537 	}
8538 
8539 	for (i = 0; i < N(mac->mac_reason); i++)
8540 		merged |= mac->mac_reason[i];
8541 
8542 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8543 		device_printf(sc->sc_dev, "MAC trans error\n");
8544 
8545 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8546 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8547 		mac->mac_phy.txerrors--;
8548 		if (mac->mac_phy.txerrors == 0) {
8549 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8550 			bwn_restart(mac, "PHY TX errors");
8551 		}
8552 	}
8553 
8554 	if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8555 		if (merged & BWN_DMAINTR_FATALMASK) {
8556 			device_printf(sc->sc_dev,
8557 			    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8558 			    mac->mac_reason[0], mac->mac_reason[1],
8559 			    mac->mac_reason[2], mac->mac_reason[3],
8560 			    mac->mac_reason[4], mac->mac_reason[5]);
8561 			bwn_restart(mac, "DMA error");
8562 			BWN_UNLOCK(sc);
8563 			return;
8564 		}
8565 		if (merged & BWN_DMAINTR_NONFATALMASK) {
8566 			device_printf(sc->sc_dev,
8567 			    "DMA error: %#x %#x %#x %#x %#x %#x\n",
8568 			    mac->mac_reason[0], mac->mac_reason[1],
8569 			    mac->mac_reason[2], mac->mac_reason[3],
8570 			    mac->mac_reason[4], mac->mac_reason[5]);
8571 		}
8572 	}
8573 
8574 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8575 		bwn_intr_ucode_debug(mac);
8576 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8577 		bwn_intr_tbtt_indication(mac);
8578 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8579 		bwn_intr_atim_end(mac);
8580 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
8581 		bwn_intr_beacon(mac);
8582 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
8583 		bwn_intr_pmq(mac);
8584 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8585 		bwn_intr_noise(mac);
8586 
8587 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8588 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8589 			bwn_dma_rx(mac->mac_method.dma.rx);
8590 			rx = 1;
8591 		}
8592 	} else
8593 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8594 
8595 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8596 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8597 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8598 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8599 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8600 
8601 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8602 		bwn_intr_txeof(mac);
8603 		tx = 1;
8604 	}
8605 
8606 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8607 
8608 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8609 		int evt = BWN_LED_EVENT_NONE;
8610 
8611 		if (tx && rx) {
8612 			if (sc->sc_rx_rate > sc->sc_tx_rate)
8613 				evt = BWN_LED_EVENT_RX;
8614 			else
8615 				evt = BWN_LED_EVENT_TX;
8616 		} else if (tx) {
8617 			evt = BWN_LED_EVENT_TX;
8618 		} else if (rx) {
8619 			evt = BWN_LED_EVENT_RX;
8620 		} else if (rx == 0) {
8621 			evt = BWN_LED_EVENT_POLL;
8622 		}
8623 
8624 		if (evt != BWN_LED_EVENT_NONE)
8625 			bwn_led_event(mac, evt);
8626        }
8627 
8628 	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8629 		if (!IFQ_IS_EMPTY(&ifp->if_snd))
8630 			bwn_start_locked(ifp);
8631 	}
8632 
8633 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8634 	BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8635 
8636 	BWN_UNLOCK(sc);
8637 }
8638 
8639 static void
8640 bwn_restart(struct bwn_mac *mac, const char *msg)
8641 {
8642 	struct bwn_softc *sc = mac->mac_sc;
8643 	struct ifnet *ifp = sc->sc_ifp;
8644 	struct ieee80211com *ic = ifp->if_l2com;
8645 
8646 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
8647 		return;
8648 
8649 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8650 	ieee80211_runtask(ic, &mac->mac_hwreset);
8651 }
8652 
8653 static void
8654 bwn_intr_ucode_debug(struct bwn_mac *mac)
8655 {
8656 	struct bwn_softc *sc = mac->mac_sc;
8657 	uint16_t reason;
8658 
8659 	if (mac->mac_fw.opensource == 0)
8660 		return;
8661 
8662 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8663 	switch (reason) {
8664 	case BWN_DEBUGINTR_PANIC:
8665 		bwn_handle_fwpanic(mac);
8666 		break;
8667 	case BWN_DEBUGINTR_DUMP_SHM:
8668 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8669 		break;
8670 	case BWN_DEBUGINTR_DUMP_REGS:
8671 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8672 		break;
8673 	case BWN_DEBUGINTR_MARKER:
8674 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8675 		break;
8676 	default:
8677 		device_printf(sc->sc_dev,
8678 		    "ucode debug unknown reason: %#x\n", reason);
8679 	}
8680 
8681 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8682 	    BWN_DEBUGINTR_ACK);
8683 }
8684 
8685 static void
8686 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8687 {
8688 	struct bwn_softc *sc = mac->mac_sc;
8689 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8690 
8691 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8692 		bwn_psctl(mac, 0);
8693 	if (ic->ic_opmode == IEEE80211_M_IBSS)
8694 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8695 }
8696 
8697 static void
8698 bwn_intr_atim_end(struct bwn_mac *mac)
8699 {
8700 
8701 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8702 		BWN_WRITE_4(mac, BWN_MACCMD,
8703 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8704 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8705 	}
8706 }
8707 
8708 static void
8709 bwn_intr_beacon(struct bwn_mac *mac)
8710 {
8711 	struct bwn_softc *sc = mac->mac_sc;
8712 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8713 	uint32_t cmd, beacon0, beacon1;
8714 
8715 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8716 	    ic->ic_opmode == IEEE80211_M_MBSS)
8717 		return;
8718 
8719 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8720 
8721 	cmd = BWN_READ_4(mac, BWN_MACCMD);
8722 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8723 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8724 
8725 	if (beacon0 && beacon1) {
8726 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8727 		mac->mac_intr_mask |= BWN_INTR_BEACON;
8728 		return;
8729 	}
8730 
8731 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8732 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8733 		bwn_load_beacon0(mac);
8734 		bwn_load_beacon1(mac);
8735 		cmd = BWN_READ_4(mac, BWN_MACCMD);
8736 		cmd |= BWN_MACCMD_BEACON0_VALID;
8737 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8738 	} else {
8739 		if (!beacon0) {
8740 			bwn_load_beacon0(mac);
8741 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8742 			cmd |= BWN_MACCMD_BEACON0_VALID;
8743 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8744 		} else if (!beacon1) {
8745 			bwn_load_beacon1(mac);
8746 			cmd = BWN_READ_4(mac, BWN_MACCMD);
8747 			cmd |= BWN_MACCMD_BEACON1_VALID;
8748 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8749 		}
8750 	}
8751 }
8752 
8753 static void
8754 bwn_intr_pmq(struct bwn_mac *mac)
8755 {
8756 	uint32_t tmp;
8757 
8758 	while (1) {
8759 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8760 		if (!(tmp & 0x00000008))
8761 			break;
8762 	}
8763 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8764 }
8765 
8766 static void
8767 bwn_intr_noise(struct bwn_mac *mac)
8768 {
8769 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8770 	uint16_t tmp;
8771 	uint8_t noise[4];
8772 	uint8_t i, j;
8773 	int32_t average;
8774 
8775 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
8776 		return;
8777 
8778 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8779 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8780 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8781 	    noise[3] == 0x7f)
8782 		goto new;
8783 
8784 	KASSERT(mac->mac_noise.noi_nsamples < 8,
8785 	    ("%s:%d: fail", __func__, __LINE__));
8786 	i = mac->mac_noise.noi_nsamples;
8787 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8788 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8789 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8790 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8791 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8792 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8793 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8794 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8795 	mac->mac_noise.noi_nsamples++;
8796 	if (mac->mac_noise.noi_nsamples == 8) {
8797 		average = 0;
8798 		for (i = 0; i < 8; i++) {
8799 			for (j = 0; j < 4; j++)
8800 				average += mac->mac_noise.noi_samples[i][j];
8801 		}
8802 		average = (((average / 32) * 125) + 64) / 128;
8803 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8804 		if (tmp >= 8)
8805 			average += 2;
8806 		else
8807 			average -= 25;
8808 		average -= (tmp == 8) ? 72 : 48;
8809 
8810 		mac->mac_stats.link_noise = average;
8811 		mac->mac_noise.noi_running = 0;
8812 		return;
8813 	}
8814 new:
8815 	bwn_noise_gensample(mac);
8816 }
8817 
8818 static int
8819 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8820 {
8821 	struct bwn_mac *mac = prq->prq_mac;
8822 	struct bwn_softc *sc = mac->mac_sc;
8823 	unsigned int i;
8824 
8825 	BWN_ASSERT_LOCKED(sc);
8826 
8827 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8828 		return (0);
8829 
8830 	for (i = 0; i < 5000; i++) {
8831 		if (bwn_pio_rxeof(prq) == 0)
8832 			break;
8833 	}
8834 	if (i >= 5000)
8835 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8836 	return ((i > 0) ? 1 : 0);
8837 }
8838 
8839 static void
8840 bwn_dma_rx(struct bwn_dma_ring *dr)
8841 {
8842 	int slot, curslot;
8843 
8844 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8845 	curslot = dr->get_curslot(dr);
8846 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8847 	    ("%s:%d: fail", __func__, __LINE__));
8848 
8849 	slot = dr->dr_curslot;
8850 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8851 		bwn_dma_rxeof(dr, &slot);
8852 
8853 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8854 	    BUS_DMASYNC_PREWRITE);
8855 
8856 	dr->set_curslot(dr, slot);
8857 	dr->dr_curslot = slot;
8858 }
8859 
8860 static void
8861 bwn_intr_txeof(struct bwn_mac *mac)
8862 {
8863 	struct bwn_txstatus stat;
8864 	uint32_t stat0, stat1;
8865 	uint16_t tmp;
8866 
8867 	BWN_ASSERT_LOCKED(mac->mac_sc);
8868 
8869 	while (1) {
8870 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8871 		if (!(stat0 & 0x00000001))
8872 			break;
8873 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8874 
8875 		stat.cookie = (stat0 >> 16);
8876 		stat.seq = (stat1 & 0x0000ffff);
8877 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8878 		tmp = (stat0 & 0x0000ffff);
8879 		stat.framecnt = ((tmp & 0xf000) >> 12);
8880 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
8881 		stat.sreason = ((tmp & 0x001c) >> 2);
8882 		stat.pm = (tmp & 0x0080) ? 1 : 0;
8883 		stat.im = (tmp & 0x0040) ? 1 : 0;
8884 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8885 		stat.ack = (tmp & 0x0002) ? 1 : 0;
8886 
8887 		bwn_handle_txeof(mac, &stat);
8888 	}
8889 }
8890 
8891 static void
8892 bwn_hwreset(void *arg, int npending)
8893 {
8894 	struct bwn_mac *mac = arg;
8895 	struct bwn_softc *sc = mac->mac_sc;
8896 	int error = 0;
8897 	int prev_status;
8898 
8899 	BWN_LOCK(sc);
8900 
8901 	prev_status = mac->mac_status;
8902 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8903 		bwn_core_stop(mac);
8904 	if (prev_status >= BWN_MAC_STATUS_INITED)
8905 		bwn_core_exit(mac);
8906 
8907 	if (prev_status >= BWN_MAC_STATUS_INITED) {
8908 		error = bwn_core_init(mac);
8909 		if (error)
8910 			goto out;
8911 	}
8912 	if (prev_status >= BWN_MAC_STATUS_STARTED)
8913 		bwn_core_start(mac);
8914 out:
8915 	if (error) {
8916 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8917 		sc->sc_curmac = NULL;
8918 	}
8919 	BWN_UNLOCK(sc);
8920 }
8921 
8922 static void
8923 bwn_handle_fwpanic(struct bwn_mac *mac)
8924 {
8925 	struct bwn_softc *sc = mac->mac_sc;
8926 	uint16_t reason;
8927 
8928 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8929 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8930 
8931 	if (reason == BWN_FWPANIC_RESTART)
8932 		bwn_restart(mac, "ucode panic");
8933 }
8934 
8935 static void
8936 bwn_load_beacon0(struct bwn_mac *mac)
8937 {
8938 
8939 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8940 }
8941 
8942 static void
8943 bwn_load_beacon1(struct bwn_mac *mac)
8944 {
8945 
8946 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8947 }
8948 
8949 static uint32_t
8950 bwn_jssi_read(struct bwn_mac *mac)
8951 {
8952 	uint32_t val = 0;
8953 
8954 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8955 	val <<= 16;
8956 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8957 
8958 	return (val);
8959 }
8960 
8961 static void
8962 bwn_noise_gensample(struct bwn_mac *mac)
8963 {
8964 	uint32_t jssi = 0x7f7f7f7f;
8965 
8966 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8967 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8968 	BWN_WRITE_4(mac, BWN_MACCMD,
8969 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8970 }
8971 
8972 static int
8973 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8974 {
8975 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8976 
8977 	return (dr->dr_numslots - dr->dr_usedslot);
8978 }
8979 
8980 static int
8981 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8982 {
8983 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8984 
8985 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8986 	    ("%s:%d: fail", __func__, __LINE__));
8987 	if (slot == dr->dr_numslots - 1)
8988 		return (0);
8989 	return (slot + 1);
8990 }
8991 
8992 static void
8993 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8994 {
8995 	struct bwn_mac *mac = dr->dr_mac;
8996 	struct bwn_softc *sc = mac->mac_sc;
8997 	struct bwn_dma *dma = &mac->mac_method.dma;
8998 	struct bwn_dmadesc_generic *desc;
8999 	struct bwn_dmadesc_meta *meta;
9000 	struct bwn_rxhdr4 *rxhdr;
9001 	struct ifnet *ifp = sc->sc_ifp;
9002 	struct mbuf *m;
9003 	uint32_t macstat;
9004 	int32_t tmp;
9005 	int cnt = 0;
9006 	uint16_t len;
9007 
9008 	dr->getdesc(dr, *slot, &desc, &meta);
9009 
9010 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
9011 	m = meta->mt_m;
9012 
9013 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
9014 		ifp->if_ierrors++;
9015 		return;
9016 	}
9017 
9018 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
9019 	len = le16toh(rxhdr->frame_len);
9020 	if (len <= 0) {
9021 		ifp->if_ierrors++;
9022 		return;
9023 	}
9024 	if (bwn_dma_check_redzone(dr, m)) {
9025 		device_printf(sc->sc_dev, "redzone error.\n");
9026 		bwn_dma_set_redzone(dr, m);
9027 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9028 		    BUS_DMASYNC_PREWRITE);
9029 		return;
9030 	}
9031 	if (len > dr->dr_rx_bufsize) {
9032 		tmp = len;
9033 		while (1) {
9034 			dr->getdesc(dr, *slot, &desc, &meta);
9035 			bwn_dma_set_redzone(dr, meta->mt_m);
9036 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9037 			    BUS_DMASYNC_PREWRITE);
9038 			*slot = bwn_dma_nextslot(dr, *slot);
9039 			cnt++;
9040 			tmp -= dr->dr_rx_bufsize;
9041 			if (tmp <= 0)
9042 				break;
9043 		}
9044 		device_printf(sc->sc_dev, "too small buffer "
9045 		       "(len %u buffer %u dropped %d)\n",
9046 		       len, dr->dr_rx_bufsize, cnt);
9047 		return;
9048 	}
9049 	macstat = le32toh(rxhdr->mac_status);
9050 	if (macstat & BWN_RX_MAC_FCSERR) {
9051 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9052 			device_printf(sc->sc_dev, "RX drop\n");
9053 			return;
9054 		}
9055 	}
9056 
9057 	m->m_pkthdr.rcvif = ifp;
9058 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
9059 	m_adj(m, dr->dr_frameoffset);
9060 
9061 	bwn_rxeof(dr->dr_mac, m, rxhdr);
9062 }
9063 
9064 static void
9065 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
9066 {
9067 	struct bwn_dma_ring *dr;
9068 	struct bwn_dmadesc_generic *desc;
9069 	struct bwn_dmadesc_meta *meta;
9070 	struct bwn_node *bn;
9071 	struct bwn_pio_txqueue *tq;
9072 	struct bwn_pio_txpkt *tp = NULL;
9073 	struct bwn_softc *sc = mac->mac_sc;
9074 	struct bwn_stats *stats = &mac->mac_stats;
9075 	struct ieee80211_node *ni;
9076 	int slot;
9077 
9078 	BWN_ASSERT_LOCKED(mac->mac_sc);
9079 
9080 	if (status->im)
9081 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9082 	if (status->ampdu)
9083 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9084 	if (status->rtscnt) {
9085 		if (status->rtscnt == 0xf)
9086 			stats->rtsfail++;
9087 		else
9088 			stats->rts++;
9089 	}
9090 
9091 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9092 		if (status->ack) {
9093 			dr = bwn_dma_parse_cookie(mac, status,
9094 			    status->cookie, &slot);
9095 			if (dr == NULL) {
9096 				device_printf(sc->sc_dev,
9097 				    "failed to parse cookie\n");
9098 				return;
9099 			}
9100 			while (1) {
9101 				dr->getdesc(dr, slot, &desc, &meta);
9102 				if (meta->mt_islast) {
9103 					ni = meta->mt_ni;
9104 					bn = (struct bwn_node *)ni;
9105 					ieee80211_amrr_tx_complete(&bn->bn_amn,
9106 					    status->ack, 0);
9107 					break;
9108 				}
9109 				slot = bwn_dma_nextslot(dr, slot);
9110 			}
9111 		}
9112 		bwn_dma_handle_txeof(mac, status);
9113 	} else {
9114 		if (status->ack) {
9115 			tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9116 			if (tq == NULL) {
9117 				device_printf(sc->sc_dev,
9118 				    "failed to parse cookie\n");
9119 				return;
9120 			}
9121 			ni = tp->tp_ni;
9122 			bn = (struct bwn_node *)ni;
9123 			ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
9124 		}
9125 		bwn_pio_handle_txeof(mac, status);
9126 	}
9127 
9128 	bwn_phy_txpower_check(mac, 0);
9129 }
9130 
9131 static uint8_t
9132 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9133 {
9134 	struct bwn_mac *mac = prq->prq_mac;
9135 	struct bwn_softc *sc = mac->mac_sc;
9136 	struct bwn_rxhdr4 rxhdr;
9137 	struct ifnet *ifp = sc->sc_ifp;
9138 	struct mbuf *m;
9139 	uint32_t ctl32, macstat, v32;
9140 	unsigned int i, padding;
9141 	uint16_t ctl16, len, v16;
9142 	unsigned char *mp;
9143 	char *data;
9144 
9145 	memset(&rxhdr, 0, sizeof(rxhdr));
9146 
9147 	if (prq->prq_rev >= 8) {
9148 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9149 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9150 			return (0);
9151 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9152 		    BWN_PIO8_RXCTL_FRAMEREADY);
9153 		for (i = 0; i < 10; i++) {
9154 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9155 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9156 				goto ready;
9157 			DELAY(10);
9158 		}
9159 	} else {
9160 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9161 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9162 			return (0);
9163 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9164 		    BWN_PIO_RXCTL_FRAMEREADY);
9165 		for (i = 0; i < 10; i++) {
9166 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9167 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9168 				goto ready;
9169 			DELAY(10);
9170 		}
9171 	}
9172 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9173 	return (1);
9174 ready:
9175 	if (prq->prq_rev >= 8)
9176 		siba_read_multi_4(mac->mac_sd, &rxhdr, sizeof(rxhdr),
9177 		    prq->prq_base + BWN_PIO8_RXDATA);
9178 	else
9179 		siba_read_multi_2(mac->mac_sd, &rxhdr, sizeof(rxhdr),
9180 		    prq->prq_base + BWN_PIO_RXDATA);
9181 	len = le16toh(rxhdr.frame_len);
9182 	if (len > 0x700) {
9183 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9184 		goto error;
9185 	}
9186 	if (len == 0) {
9187 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9188 		goto error;
9189 	}
9190 
9191 	macstat = le32toh(rxhdr.mac_status);
9192 	if (macstat & BWN_RX_MAC_FCSERR) {
9193 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9194 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
9195 			goto error;
9196 		}
9197 	}
9198 
9199 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9200 	KASSERT(len + padding <= MCLBYTES, ("too big..\n"));
9201 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9202 	if (m == NULL) {
9203 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
9204 		goto error;
9205 	}
9206 	mp = mtod(m, unsigned char *);
9207 	if (prq->prq_rev >= 8) {
9208 		siba_read_multi_4(mac->mac_sd, mp + padding, (len & ~3),
9209 		    prq->prq_base + BWN_PIO8_RXDATA);
9210 		if (len & 3) {
9211 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9212 			data = &(mp[len + padding - 1]);
9213 			switch (len & 3) {
9214 			case 3:
9215 				*data = (v32 >> 16);
9216 				data--;
9217 			case 2:
9218 				*data = (v32 >> 8);
9219 				data--;
9220 			case 1:
9221 				*data = v32;
9222 			}
9223 		}
9224 	} else {
9225 		siba_read_multi_2(mac->mac_sd, mp + padding, (len & ~1),
9226 		    prq->prq_base + BWN_PIO_RXDATA);
9227 		if (len & 1) {
9228 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9229 			mp[len + padding - 1] = v16;
9230 		}
9231 	}
9232 
9233 	m->m_pkthdr.rcvif = ifp;
9234 	m->m_len = m->m_pkthdr.len = len + padding;
9235 
9236 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
9237 
9238 	return (1);
9239 error:
9240 	if (prq->prq_rev >= 8)
9241 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9242 		    BWN_PIO8_RXCTL_DATAREADY);
9243 	else
9244 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9245 	return (1);
9246 }
9247 
9248 static int
9249 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9250     struct bwn_dmadesc_meta *meta, int init)
9251 {
9252 	struct bwn_mac *mac = dr->dr_mac;
9253 	struct bwn_dma *dma = &mac->mac_method.dma;
9254 	struct bwn_rxhdr4 *hdr;
9255 	bus_dmamap_t map;
9256 	bus_addr_t paddr;
9257 	struct mbuf *m;
9258 	int error;
9259 
9260 	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9261 	if (m == NULL) {
9262 		error = ENOBUFS;
9263 
9264 		/*
9265 		 * If the NIC is up and running, we need to:
9266 		 * - Clear RX buffer's header.
9267 		 * - Restore RX descriptor settings.
9268 		 */
9269 		if (init)
9270 			return (error);
9271 		else
9272 			goto back;
9273 	}
9274 	m->m_len = m->m_pkthdr.len = MCLBYTES;
9275 
9276 	bwn_dma_set_redzone(dr, m);
9277 
9278 	/*
9279 	 * Try to load RX buf into temporary DMA map
9280 	 */
9281 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9282 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9283 	if (error) {
9284 		m_freem(m);
9285 
9286 		/*
9287 		 * See the comment above
9288 		 */
9289 		if (init)
9290 			return (error);
9291 		else
9292 			goto back;
9293 	}
9294 
9295 	if (!init)
9296 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9297 	meta->mt_m = m;
9298 	meta->mt_paddr = paddr;
9299 
9300 	/*
9301 	 * Swap RX buf's DMA map with the loaded temporary one
9302 	 */
9303 	map = meta->mt_dmap;
9304 	meta->mt_dmap = dr->dr_spare_dmap;
9305 	dr->dr_spare_dmap = map;
9306 
9307 back:
9308 	/*
9309 	 * Clear RX buf header
9310 	 */
9311 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9312 	bzero(hdr, sizeof(*hdr));
9313 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9314 	    BUS_DMASYNC_PREWRITE);
9315 
9316 	/*
9317 	 * Setup RX buf descriptor
9318 	 */
9319 	dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9320 	    sizeof(*hdr), 0, 0, 0);
9321 	return (error);
9322 }
9323 
9324 static void
9325 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9326 		 bus_size_t mapsz __unused, int error)
9327 {
9328 
9329 	if (!error) {
9330 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9331 		*((bus_addr_t *)arg) = seg->ds_addr;
9332 	}
9333 }
9334 
9335 static int
9336 bwn_hwrate2ieeerate(int rate)
9337 {
9338 
9339 	switch (rate) {
9340 	case BWN_CCK_RATE_1MB:
9341 		return (2);
9342 	case BWN_CCK_RATE_2MB:
9343 		return (4);
9344 	case BWN_CCK_RATE_5MB:
9345 		return (11);
9346 	case BWN_CCK_RATE_11MB:
9347 		return (22);
9348 	case BWN_OFDM_RATE_6MB:
9349 		return (12);
9350 	case BWN_OFDM_RATE_9MB:
9351 		return (18);
9352 	case BWN_OFDM_RATE_12MB:
9353 		return (24);
9354 	case BWN_OFDM_RATE_18MB:
9355 		return (36);
9356 	case BWN_OFDM_RATE_24MB:
9357 		return (48);
9358 	case BWN_OFDM_RATE_36MB:
9359 		return (72);
9360 	case BWN_OFDM_RATE_48MB:
9361 		return (96);
9362 	case BWN_OFDM_RATE_54MB:
9363 		return (108);
9364 	default:
9365 		printf("Ooops\n");
9366 		return (0);
9367 	}
9368 }
9369 
9370 static void
9371 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9372 {
9373 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9374 	struct bwn_plcp6 *plcp;
9375 	struct bwn_softc *sc = mac->mac_sc;
9376 	struct ieee80211_frame_min *wh;
9377 	struct ieee80211_node *ni;
9378 	struct ifnet *ifp = sc->sc_ifp;
9379 	struct ieee80211com *ic = ifp->if_l2com;
9380 	uint32_t macstat;
9381 	int padding, rate, rssi = 0, noise = 0, type;
9382 	uint16_t phytype, phystat0, phystat3, chanstat;
9383 	unsigned char *mp = mtod(m, unsigned char *);
9384 	static int rx_mac_dec_rpt = 0;
9385 
9386 	BWN_ASSERT_LOCKED(sc);
9387 
9388 	phystat0 = le16toh(rxhdr->phy_status0);
9389 	phystat3 = le16toh(rxhdr->phy_status3);
9390 	macstat = le32toh(rxhdr->mac_status);
9391 	chanstat = le16toh(rxhdr->channel);
9392 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9393 
9394 	if (macstat & BWN_RX_MAC_FCSERR)
9395 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9396 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9397 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9398 	if (phystat0 & BWN_RX_PHYST0_SHORTPRMBL)
9399 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_SHORTPRE\n");
9400 	if (macstat & BWN_RX_MAC_DECERR)
9401 		goto drop;
9402 
9403 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9404 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9405 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9406 		    m->m_pkthdr.len);
9407 		goto drop;
9408 	}
9409 	plcp = (struct bwn_plcp6 *)(mp + padding);
9410 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
9411 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9412 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9413 		    m->m_pkthdr.len);
9414 		goto drop;
9415 	}
9416 	wh = mtod(m, struct ieee80211_frame_min *);
9417 
9418 	if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9419 		device_printf(sc->sc_dev,
9420 		    "RX decryption attempted (old %d keyidx %#x)\n",
9421 		    BWN_ISOLDFMT(mac),
9422 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9423 
9424 	/* XXX calculating RSSI & noise & antenna */
9425 
9426 	if (phystat0 & BWN_RX_PHYST0_OFDM)
9427 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
9428 		    phytype == BWN_PHYTYPE_A);
9429 	else
9430 		rate = bwn_plcp_get_cckrate(mac, plcp);
9431 	if (rate == -1) {
9432 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9433 			goto drop;
9434 	}
9435 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9436 
9437 	/* RX radio tap */
9438 	if (ieee80211_radiotap_active(ic))
9439 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9440 	m_adj(m, -IEEE80211_CRC_LEN);
9441 
9442 	rssi = rxhdr->phy.abg.rssi;	/* XXX incorrect RSSI calculation? */
9443 	noise = mac->mac_stats.link_noise;
9444 
9445 	BWN_UNLOCK(sc);
9446 
9447 	ni = ieee80211_find_rxnode(ic, wh);
9448 	if (ni != NULL) {
9449 		type = ieee80211_input(ni, m, rssi, noise);
9450 		ieee80211_free_node(ni);
9451 	} else
9452 		type = ieee80211_input_all(ic, m, rssi, noise);
9453 
9454 	BWN_LOCK(sc);
9455 	return;
9456 drop:
9457 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9458 }
9459 
9460 static void
9461 bwn_dma_handle_txeof(struct bwn_mac *mac,
9462     const struct bwn_txstatus *status)
9463 {
9464 	struct bwn_dma *dma = &mac->mac_method.dma;
9465 	struct bwn_dma_ring *dr;
9466 	struct bwn_dmadesc_generic *desc;
9467 	struct bwn_dmadesc_meta *meta;
9468 	struct bwn_softc *sc = mac->mac_sc;
9469 	struct ieee80211_node *ni;
9470 	struct ifnet *ifp = sc->sc_ifp;
9471 	struct mbuf *m;
9472 	int slot;
9473 
9474 	BWN_ASSERT_LOCKED(sc);
9475 
9476 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9477 	if (dr == NULL) {
9478 		device_printf(sc->sc_dev, "failed to parse cookie\n");
9479 		return;
9480 	}
9481 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9482 
9483 	while (1) {
9484 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
9485 		    ("%s:%d: fail", __func__, __LINE__));
9486 		dr->getdesc(dr, slot, &desc, &meta);
9487 
9488 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9489 			bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9490 		else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9491 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9492 
9493 		if (meta->mt_islast) {
9494 			KASSERT(meta->mt_m != NULL,
9495 			    ("%s:%d: fail", __func__, __LINE__));
9496 
9497 			ni = meta->mt_ni;
9498 			m = meta->mt_m;
9499 			if (ni != NULL) {
9500 				/*
9501 				 * Do any tx complete callback. Note this must
9502 				 * be done before releasing the node reference.
9503 				 */
9504 				if (m->m_flags & M_TXCB)
9505 					ieee80211_process_callback(ni, m, 0);
9506 				ieee80211_free_node(ni);
9507 				meta->mt_ni = NULL;
9508 			}
9509 			m_freem(m);
9510 			meta->mt_m = NULL;
9511 		} else {
9512 			KASSERT(meta->mt_m == NULL,
9513 			    ("%s:%d: fail", __func__, __LINE__));
9514 		}
9515 
9516 		dr->dr_usedslot--;
9517 		if (meta->mt_islast) {
9518 			ifp->if_opackets++;
9519 			break;
9520 		}
9521 		slot = bwn_dma_nextslot(dr, slot);
9522 	}
9523 	sc->sc_watchdog_timer = 0;
9524 	if (dr->dr_stop) {
9525 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9526 		    ("%s:%d: fail", __func__, __LINE__));
9527 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9528 		dr->dr_stop = 0;
9529 	}
9530 }
9531 
9532 static void
9533 bwn_pio_handle_txeof(struct bwn_mac *mac,
9534     const struct bwn_txstatus *status)
9535 {
9536 	struct bwn_pio_txqueue *tq;
9537 	struct bwn_pio_txpkt *tp = NULL;
9538 	struct bwn_softc *sc = mac->mac_sc;
9539 	struct ifnet *ifp = sc->sc_ifp;
9540 
9541 	BWN_ASSERT_LOCKED(sc);
9542 
9543 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9544 	if (tq == NULL)
9545 		return;
9546 
9547 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9548 	tq->tq_free++;
9549 
9550 	if (tp->tp_ni != NULL) {
9551 		/*
9552 		 * Do any tx complete callback.  Note this must
9553 		 * be done before releasing the node reference.
9554 		 */
9555 		if (tp->tp_m->m_flags & M_TXCB)
9556 			ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9557 		ieee80211_free_node(tp->tp_ni);
9558 		tp->tp_ni = NULL;
9559 	}
9560 	m_freem(tp->tp_m);
9561 	tp->tp_m = NULL;
9562 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9563 
9564 	ifp->if_opackets++;
9565 
9566 	sc->sc_watchdog_timer = 0;
9567 	if (tq->tq_stop) {
9568 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9569 		tq->tq_stop = 0;
9570 	}
9571 }
9572 
9573 static void
9574 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9575 {
9576 	struct bwn_softc *sc = mac->mac_sc;
9577 	struct bwn_phy *phy = &mac->mac_phy;
9578 	struct ifnet *ifp = sc->sc_ifp;
9579 	struct ieee80211com *ic = ifp->if_l2com;
9580 	struct siba_softc *siba = mac->mac_sd->sd_bus;
9581 	unsigned long now;
9582 	int result;
9583 
9584 	BWN_GETTIME(now);
9585 
9586 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9587 		return;
9588 	phy->nexttime = now + 2 * 1000;
9589 
9590 	if (siba->siba_board_vendor == SIBA_BOARDVENDOR_BCM &&
9591 	    siba->siba_board_type == SIBA_BOARD_BU4306)
9592 		return;
9593 
9594 	if (phy->recalc_txpwr != NULL) {
9595 		result = phy->recalc_txpwr(mac,
9596 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9597 		if (result == BWN_TXPWR_RES_DONE)
9598 			return;
9599 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9600 		    ("%s: fail", __func__));
9601 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9602 
9603 		ieee80211_runtask(ic, &mac->mac_txpower);
9604 	}
9605 }
9606 
9607 static uint16_t
9608 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9609 {
9610 
9611 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9612 }
9613 
9614 static uint32_t
9615 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9616 {
9617 
9618 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9619 }
9620 
9621 static void
9622 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9623 {
9624 
9625 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9626 }
9627 
9628 static void
9629 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9630 {
9631 
9632 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9633 }
9634 
9635 static int
9636 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9637 {
9638 
9639 	switch (rate) {
9640 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9641 	case 12:
9642 		return (BWN_OFDM_RATE_6MB);
9643 	case 18:
9644 		return (BWN_OFDM_RATE_9MB);
9645 	case 24:
9646 		return (BWN_OFDM_RATE_12MB);
9647 	case 36:
9648 		return (BWN_OFDM_RATE_18MB);
9649 	case 48:
9650 		return (BWN_OFDM_RATE_24MB);
9651 	case 72:
9652 		return (BWN_OFDM_RATE_36MB);
9653 	case 96:
9654 		return (BWN_OFDM_RATE_48MB);
9655 	case 108:
9656 		return (BWN_OFDM_RATE_54MB);
9657 	/* CCK rates (NB: not IEEE std, device-specific) */
9658 	case 2:
9659 		return (BWN_CCK_RATE_1MB);
9660 	case 4:
9661 		return (BWN_CCK_RATE_2MB);
9662 	case 11:
9663 		return (BWN_CCK_RATE_5MB);
9664 	case 22:
9665 		return (BWN_CCK_RATE_11MB);
9666 	}
9667 
9668 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9669 	return (BWN_CCK_RATE_1MB);
9670 }
9671 
9672 static int
9673 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9674     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9675 {
9676 	const struct bwn_phy *phy = &mac->mac_phy;
9677 	struct bwn_softc *sc = mac->mac_sc;
9678 	struct ieee80211_frame *wh;
9679 	struct ieee80211_frame *protwh;
9680 	struct ieee80211_frame_cts *cts;
9681 	struct ieee80211_frame_rts *rts;
9682 	const struct ieee80211_txparam *tp;
9683 	struct ieee80211vap *vap = ni->ni_vap;
9684 	struct ifnet *ifp = sc->sc_ifp;
9685 	struct ieee80211com *ic = ifp->if_l2com;
9686 	struct mbuf *mprot;
9687 	unsigned int len;
9688 	uint32_t macctl = 0;
9689 	int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9690 	uint16_t phyctl = 0;
9691 	uint8_t rate, rate_fb;
9692 
9693 	wh = mtod(m, struct ieee80211_frame *);
9694 	memset(txhdr, 0, sizeof(*txhdr));
9695 
9696 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9697 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9698 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9699 
9700 	/*
9701 	 * Find TX rate
9702 	 */
9703 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9704 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9705 		rate = rate_fb = tp->mgmtrate;
9706 	else if (ismcast)
9707 		rate = rate_fb = tp->mcastrate;
9708 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9709 		rate = rate_fb = tp->ucastrate;
9710 	else {
9711 		rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
9712 		rate = ni->ni_txrate;
9713 
9714 		if (rix > 0)
9715 			rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9716 			    IEEE80211_RATE_VAL;
9717 		else
9718 			rate_fb = rate;
9719 	}
9720 
9721 	sc->sc_tx_rate = rate;
9722 
9723 	rate = bwn_ieeerate2hwrate(sc, rate);
9724 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9725 
9726 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9727 	    bwn_plcp_getcck(rate);
9728 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9729 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9730 
9731 	if ((rate_fb == rate) ||
9732 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9733 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
9734 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9735 	else
9736 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9737 		    m->m_pkthdr.len, rate, isshort);
9738 
9739 	/* XXX TX encryption */
9740 	bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9741 	    (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9742 	    (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9743 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9744 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9745 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9746 
9747 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9748 	    BWN_TX_EFT_FB_CCK;
9749 	txhdr->chan = phy->chan;
9750 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9751 	    BWN_TX_PHY_ENC_CCK;
9752 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9753 	     rate == BWN_CCK_RATE_11MB))
9754 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
9755 
9756 	/* XXX TX antenna selection */
9757 
9758 	switch (bwn_antenna_sanitize(mac, 0)) {
9759 	case 0:
9760 		phyctl |= BWN_TX_PHY_ANT01AUTO;
9761 		break;
9762 	case 1:
9763 		phyctl |= BWN_TX_PHY_ANT0;
9764 		break;
9765 	case 2:
9766 		phyctl |= BWN_TX_PHY_ANT1;
9767 		break;
9768 	case 3:
9769 		phyctl |= BWN_TX_PHY_ANT2;
9770 		break;
9771 	case 4:
9772 		phyctl |= BWN_TX_PHY_ANT3;
9773 		break;
9774 	default:
9775 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9776 	}
9777 
9778 	if (!ismcast)
9779 		macctl |= BWN_TX_MAC_ACK;
9780 
9781 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9782 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9783 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9784 		macctl |= BWN_TX_MAC_LONGFRAME;
9785 
9786 	if (ic->ic_flags & IEEE80211_F_USEPROT) {
9787 		/* XXX RTS rate is always 1MB??? */
9788 		rts_rate = BWN_CCK_RATE_1MB;
9789 		rts_rate_fb = bwn_get_fbrate(rts_rate);
9790 
9791 		protdur = ieee80211_compute_duration(ic->ic_rt,
9792 		    m->m_pkthdr.len, rate, isshort) +
9793 		    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9794 
9795 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9796 			cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9797 			    (txhdr->body.old.rts_frame) :
9798 			    (txhdr->body.new.rts_frame));
9799 			mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9800 			    protdur);
9801 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9802 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9803 			    mprot->m_pkthdr.len);
9804 			m_freem(mprot);
9805 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9806 			len = sizeof(struct ieee80211_frame_cts);
9807 		} else {
9808 			rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9809 			    (txhdr->body.old.rts_frame) :
9810 			    (txhdr->body.new.rts_frame));
9811 			protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9812 			    isshort);
9813 			mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9814 			    wh->i_addr2, protdur);
9815 			KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9816 			bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9817 			    mprot->m_pkthdr.len);
9818 			m_freem(mprot);
9819 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
9820 			len = sizeof(struct ieee80211_frame_rts);
9821 		}
9822 		len += IEEE80211_CRC_LEN;
9823 		bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9824 		    &txhdr->body.old.rts_plcp :
9825 		    &txhdr->body.new.rts_plcp), len, rts_rate);
9826 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9827 		    rts_rate_fb);
9828 
9829 		protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9830 		    (&txhdr->body.old.rts_frame) :
9831 		    (&txhdr->body.new.rts_frame));
9832 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9833 
9834 		if (BWN_ISOFDMRATE(rts_rate)) {
9835 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9836 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9837 		} else {
9838 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9839 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9840 		}
9841 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9842 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9843 	}
9844 
9845 	if (BWN_ISOLDFMT(mac))
9846 		txhdr->body.old.cookie = htole16(cookie);
9847 	else
9848 		txhdr->body.new.cookie = htole16(cookie);
9849 
9850 	txhdr->macctl = htole32(macctl);
9851 	txhdr->phyctl = htole16(phyctl);
9852 
9853 	/*
9854 	 * TX radio tap
9855 	 */
9856 	if (ieee80211_radiotap_active_vap(vap)) {
9857 		sc->sc_tx_th.wt_flags = 0;
9858 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9859 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9860 		if (isshort &&
9861 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9862 		     rate == BWN_CCK_RATE_11MB))
9863 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9864 		sc->sc_tx_th.wt_rate = rate;
9865 
9866 		ieee80211_radiotap_tx(vap, m);
9867 	}
9868 
9869 	return (0);
9870 }
9871 
9872 static void
9873 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9874     const uint8_t rate)
9875 {
9876 	uint32_t d, plen;
9877 	uint8_t *raw = plcp->o.raw;
9878 
9879 	if (BWN_ISOFDMRATE(rate)) {
9880 		d = bwn_plcp_getofdm(rate);
9881 		KASSERT(!(octets & 0xf000),
9882 		    ("%s:%d: fail", __func__, __LINE__));
9883 		d |= (octets << 5);
9884 		plcp->o.data = htole32(d);
9885 	} else {
9886 		plen = octets * 16 / rate;
9887 		if ((octets * 16 % rate) > 0) {
9888 			plen++;
9889 			if ((rate == BWN_CCK_RATE_11MB)
9890 			    && ((octets * 8 % 11) < 4)) {
9891 				raw[1] = 0x84;
9892 			} else
9893 				raw[1] = 0x04;
9894 		} else
9895 			raw[1] = 0x04;
9896 		plcp->o.data |= htole32(plen << 16);
9897 		raw[0] = bwn_plcp_getcck(rate);
9898 	}
9899 }
9900 
9901 static uint8_t
9902 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9903 {
9904 	uint8_t mask;
9905 
9906 	if (n == 0)
9907 		return (0);
9908 	if (mac->mac_phy.gmode)
9909 		mask = mac->mac_sd->sd_bus->siba_sprom.ant_bg;
9910 	else
9911 		mask = mac->mac_sd->sd_bus->siba_sprom.ant_a;
9912 	if (!(mask & (1 << (n - 1))))
9913 		return (0);
9914 	return (n);
9915 }
9916 
9917 static uint8_t
9918 bwn_get_fbrate(uint8_t bitrate)
9919 {
9920 	switch (bitrate) {
9921 	case BWN_CCK_RATE_1MB:
9922 		return (BWN_CCK_RATE_1MB);
9923 	case BWN_CCK_RATE_2MB:
9924 		return (BWN_CCK_RATE_1MB);
9925 	case BWN_CCK_RATE_5MB:
9926 		return (BWN_CCK_RATE_2MB);
9927 	case BWN_CCK_RATE_11MB:
9928 		return (BWN_CCK_RATE_5MB);
9929 	case BWN_OFDM_RATE_6MB:
9930 		return (BWN_CCK_RATE_5MB);
9931 	case BWN_OFDM_RATE_9MB:
9932 		return (BWN_OFDM_RATE_6MB);
9933 	case BWN_OFDM_RATE_12MB:
9934 		return (BWN_OFDM_RATE_9MB);
9935 	case BWN_OFDM_RATE_18MB:
9936 		return (BWN_OFDM_RATE_12MB);
9937 	case BWN_OFDM_RATE_24MB:
9938 		return (BWN_OFDM_RATE_18MB);
9939 	case BWN_OFDM_RATE_36MB:
9940 		return (BWN_OFDM_RATE_24MB);
9941 	case BWN_OFDM_RATE_48MB:
9942 		return (BWN_OFDM_RATE_36MB);
9943 	case BWN_OFDM_RATE_54MB:
9944 		return (BWN_OFDM_RATE_48MB);
9945 	}
9946 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9947 	return (0);
9948 }
9949 
9950 static uint32_t
9951 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9952     uint32_t ctl, const void *_data, int len)
9953 {
9954 	uint32_t value = 0;
9955 	const uint8_t *data = _data;
9956 
9957 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9958 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9959 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9960 
9961 	siba_write_multi_4(mac->mac_sd, data, (len & ~3),
9962 	    tq->tq_base + BWN_PIO8_TXDATA);
9963 	if (len & 3) {
9964 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9965 		    BWN_PIO8_TXCTL_24_31);
9966 		data = &(data[len - 1]);
9967 		switch (len & 3) {
9968 		case 3:
9969 			ctl |= BWN_PIO8_TXCTL_16_23;
9970 			value |= (uint32_t)(*data) << 16;
9971 			data--;
9972 		case 2:
9973 			ctl |= BWN_PIO8_TXCTL_8_15;
9974 			value |= (uint32_t)(*data) << 8;
9975 			data--;
9976 		case 1:
9977 			value |= (uint32_t)(*data);
9978 		}
9979 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9980 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9981 	}
9982 
9983 	return (ctl);
9984 }
9985 
9986 static void
9987 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9988     uint16_t offset, uint32_t value)
9989 {
9990 
9991 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
9992 }
9993 
9994 static uint16_t
9995 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9996     uint16_t ctl, const void *_data, int len)
9997 {
9998 	const uint8_t *data = _data;
9999 
10000 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
10001 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10002 
10003 	siba_write_multi_2(mac->mac_sd, data, (len & ~1),
10004 	    tq->tq_base + BWN_PIO_TXDATA);
10005 	if (len & 1) {
10006 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
10007 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10008 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
10009 	}
10010 
10011 	return (ctl);
10012 }
10013 
10014 static uint16_t
10015 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
10016     uint16_t ctl, struct mbuf *m0)
10017 {
10018 	int i, j = 0;
10019 	uint16_t data = 0;
10020 	const uint8_t *buf;
10021 	struct mbuf *m = m0;
10022 
10023 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
10024 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10025 
10026 	for (; m != NULL; m = m->m_next) {
10027 		buf = mtod(m, const uint8_t *);
10028 		for (i = 0; i < m->m_len; i++) {
10029 			if (!((j++) % 2))
10030 				data |= buf[i];
10031 			else {
10032 				data |= (buf[i] << 8);
10033 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10034 				data = 0;
10035 			}
10036 		}
10037 	}
10038 	if (m0->m_pkthdr.len % 2) {
10039 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
10040 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10041 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10042 	}
10043 
10044 	return (ctl);
10045 }
10046 
10047 static void
10048 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
10049 {
10050 
10051 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
10052 		return;
10053 	BWN_WRITE_2(mac, 0x684, 510 + time);
10054 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
10055 }
10056 
10057 static struct bwn_dma_ring *
10058 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
10059 {
10060 
10061 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
10062 		return (mac->mac_method.dma.wme[WME_AC_BE]);
10063 
10064 	switch (prio) {
10065 	case 3:
10066 		return (mac->mac_method.dma.wme[WME_AC_VO]);
10067 	case 2:
10068 		return (mac->mac_method.dma.wme[WME_AC_VI]);
10069 	case 0:
10070 		return (mac->mac_method.dma.wme[WME_AC_BE]);
10071 	case 1:
10072 		return (mac->mac_method.dma.wme[WME_AC_BK]);
10073 	}
10074 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10075 	return (NULL);
10076 }
10077 
10078 static int
10079 bwn_dma_getslot(struct bwn_dma_ring *dr)
10080 {
10081 	int slot;
10082 
10083 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10084 
10085 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10086 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10087 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10088 
10089 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10090 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10091 	dr->dr_curslot = slot;
10092 	dr->dr_usedslot++;
10093 
10094 	return (slot);
10095 }
10096 
10097 static int
10098 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10099 {
10100 	const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10101 	unsigned int a, b, c, d;
10102 	unsigned int avg;
10103 	uint32_t tmp;
10104 
10105 	tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10106 	a = tmp & 0xff;
10107 	b = (tmp >> 8) & 0xff;
10108 	c = (tmp >> 16) & 0xff;
10109 	d = (tmp >> 24) & 0xff;
10110 	if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10111 	    c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10112 		return (ENOENT);
10113 	bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10114 	    BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10115 	    (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10116 
10117 	if (ofdm) {
10118 		a = (a + 32) & 0x3f;
10119 		b = (b + 32) & 0x3f;
10120 		c = (c + 32) & 0x3f;
10121 		d = (d + 32) & 0x3f;
10122 	}
10123 
10124 	avg = (a + b + c + d + 2) / 4;
10125 	if (ofdm) {
10126 		if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10127 		    & BWN_HF_4DB_CCK_POWERBOOST)
10128 			avg = (avg >= 13) ? (avg - 13) : 0;
10129 	}
10130 	return (avg);
10131 }
10132 
10133 static void
10134 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10135 {
10136 	struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10137 	int rfatt = *rfattp;
10138 	int bbatt = *bbattp;
10139 
10140 	while (1) {
10141 		if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10142 			break;
10143 		if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10144 			break;
10145 		if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10146 			break;
10147 		if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10148 			break;
10149 		if (bbatt > lo->bbatt.max) {
10150 			bbatt -= 4;
10151 			rfatt += 1;
10152 			continue;
10153 		}
10154 		if (bbatt < lo->bbatt.min) {
10155 			bbatt += 4;
10156 			rfatt -= 1;
10157 			continue;
10158 		}
10159 		if (rfatt > lo->rfatt.max) {
10160 			rfatt -= 1;
10161 			bbatt += 4;
10162 			continue;
10163 		}
10164 		if (rfatt < lo->rfatt.min) {
10165 			rfatt += 1;
10166 			bbatt -= 4;
10167 			continue;
10168 		}
10169 		break;
10170 	}
10171 
10172 	*rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10173 	*bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10174 }
10175 
10176 static void
10177 bwn_phy_lock(struct bwn_mac *mac)
10178 {
10179 	struct bwn_softc *sc = mac->mac_sc;
10180 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10181 
10182 	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
10183 	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
10184 
10185 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10186 		bwn_psctl(mac, BWN_PS_AWAKE);
10187 }
10188 
10189 static void
10190 bwn_phy_unlock(struct bwn_mac *mac)
10191 {
10192 	struct bwn_softc *sc = mac->mac_sc;
10193 	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10194 
10195 	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
10196 	    ("%s: unsupported rev %d", __func__, mac->mac_sd->sd_id.sd_rev));
10197 
10198 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10199 		bwn_psctl(mac, 0);
10200 }
10201 
10202 static void
10203 bwn_rf_lock(struct bwn_mac *mac)
10204 {
10205 
10206 	BWN_WRITE_4(mac, BWN_MACCTL,
10207 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10208 	BWN_READ_4(mac, BWN_MACCTL);
10209 	DELAY(10);
10210 }
10211 
10212 static void
10213 bwn_rf_unlock(struct bwn_mac *mac)
10214 {
10215 
10216 	BWN_READ_2(mac, BWN_PHYVER);
10217 	BWN_WRITE_4(mac, BWN_MACCTL,
10218 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10219 }
10220 
10221 static struct bwn_pio_txqueue *
10222 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10223     struct bwn_pio_txpkt **pack)
10224 {
10225 	struct bwn_pio *pio = &mac->mac_method.pio;
10226 	struct bwn_pio_txqueue *tq = NULL;
10227 	unsigned int index;
10228 
10229 	switch (cookie & 0xf000) {
10230 	case 0x1000:
10231 		tq = &pio->wme[WME_AC_BK];
10232 		break;
10233 	case 0x2000:
10234 		tq = &pio->wme[WME_AC_BE];
10235 		break;
10236 	case 0x3000:
10237 		tq = &pio->wme[WME_AC_VI];
10238 		break;
10239 	case 0x4000:
10240 		tq = &pio->wme[WME_AC_VO];
10241 		break;
10242 	case 0x5000:
10243 		tq = &pio->mcast;
10244 		break;
10245 	}
10246 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10247 	if (tq == NULL)
10248 		return (NULL);
10249 	index = (cookie & 0x0fff);
10250 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10251 	if (index >= N(tq->tq_pkts))
10252 		return (NULL);
10253 	*pack = &tq->tq_pkts[index];
10254 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10255 	return (tq);
10256 }
10257 
10258 static void
10259 bwn_txpwr(void *arg, int npending)
10260 {
10261 	struct bwn_mac *mac = arg;
10262 	struct bwn_softc *sc = mac->mac_sc;
10263 
10264 	BWN_LOCK(sc);
10265 	if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10266 	    mac->mac_phy.set_txpwr != NULL)
10267 		mac->mac_phy.set_txpwr(mac);
10268 	BWN_UNLOCK(sc);
10269 }
10270 
10271 static void
10272 bwn_task_15s(struct bwn_mac *mac)
10273 {
10274 	uint16_t reg;
10275 
10276 	if (mac->mac_fw.opensource) {
10277 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10278 		if (reg) {
10279 			bwn_restart(mac, "fw watchdog");
10280 			return;
10281 		}
10282 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10283 	}
10284 	if (mac->mac_phy.task_15s)
10285 		mac->mac_phy.task_15s(mac);
10286 
10287 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10288 }
10289 
10290 static void
10291 bwn_task_30s(struct bwn_mac *mac)
10292 {
10293 
10294 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10295 		return;
10296 	mac->mac_noise.noi_running = 1;
10297 	mac->mac_noise.noi_nsamples = 0;
10298 
10299 	bwn_noise_gensample(mac);
10300 }
10301 
10302 static void
10303 bwn_task_60s(struct bwn_mac *mac)
10304 {
10305 
10306 	if (mac->mac_phy.task_60s)
10307 		mac->mac_phy.task_60s(mac);
10308 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10309 }
10310 
10311 static void
10312 bwn_tasks(void *arg)
10313 {
10314 	struct bwn_mac *mac = arg;
10315 	struct bwn_softc *sc = mac->mac_sc;
10316 
10317 	BWN_ASSERT_LOCKED(sc);
10318 	if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10319 		return;
10320 
10321 	if (mac->mac_task_state % 4 == 0)
10322 		bwn_task_60s(mac);
10323 	if (mac->mac_task_state % 2 == 0)
10324 		bwn_task_30s(mac);
10325 	bwn_task_15s(mac);
10326 
10327 	mac->mac_task_state++;
10328 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10329 }
10330 
10331 static int
10332 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10333 {
10334 	struct bwn_softc *sc = mac->mac_sc;
10335 
10336 	KASSERT(a == 0, ("not support APHY\n"));
10337 
10338 	switch (plcp->o.raw[0] & 0xf) {
10339 	case 0xb:
10340 		return (BWN_OFDM_RATE_6MB);
10341 	case 0xf:
10342 		return (BWN_OFDM_RATE_9MB);
10343 	case 0xa:
10344 		return (BWN_OFDM_RATE_12MB);
10345 	case 0xe:
10346 		return (BWN_OFDM_RATE_18MB);
10347 	case 0x9:
10348 		return (BWN_OFDM_RATE_24MB);
10349 	case 0xd:
10350 		return (BWN_OFDM_RATE_36MB);
10351 	case 0x8:
10352 		return (BWN_OFDM_RATE_48MB);
10353 	case 0xc:
10354 		return (BWN_OFDM_RATE_54MB);
10355 	}
10356 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10357 	    plcp->o.raw[0] & 0xf);
10358 	return (-1);
10359 }
10360 
10361 static int
10362 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10363 {
10364 	struct bwn_softc *sc = mac->mac_sc;
10365 
10366 	switch (plcp->o.raw[0]) {
10367 	case 0x0a:
10368 		return (BWN_CCK_RATE_1MB);
10369 	case 0x14:
10370 		return (BWN_CCK_RATE_2MB);
10371 	case 0x37:
10372 		return (BWN_CCK_RATE_5MB);
10373 	case 0x6e:
10374 		return (BWN_CCK_RATE_11MB);
10375 	}
10376 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10377 	return (-1);
10378 }
10379 
10380 static void
10381 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10382     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10383     int rssi, int noise)
10384 {
10385 	struct bwn_softc *sc = mac->mac_sc;
10386 	const struct ieee80211_frame_min *wh;
10387 	uint64_t tsf;
10388 	uint16_t low_mactime_now;
10389 
10390 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10391 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10392 
10393 	wh = mtod(m, const struct ieee80211_frame_min *);
10394 	if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10395 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10396 
10397 	bwn_tsf_read(mac, &tsf);
10398 	low_mactime_now = tsf;
10399 	tsf = tsf & ~0xffffULL;
10400 	tsf += le16toh(rxhdr->mac_time);
10401 	if (low_mactime_now < le16toh(rxhdr->mac_time))
10402 		tsf -= 0x10000;
10403 
10404 	sc->sc_rx_th.wr_tsf = tsf;
10405 	sc->sc_rx_th.wr_rate = rate;
10406 	sc->sc_rx_th.wr_antsignal = rssi;
10407 	sc->sc_rx_th.wr_antnoise = noise;
10408 }
10409 
10410 static void
10411 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10412 {
10413 	uint32_t low, high;
10414 
10415 	KASSERT(mac->mac_sd->sd_id.sd_rev >= 3,
10416 	    ("%s:%d: fail", __func__, __LINE__));
10417 
10418 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10419 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10420 	*tsf = high;
10421 	*tsf <<= 32;
10422 	*tsf |= low;
10423 }
10424 
10425 static int
10426 bwn_dma_attach(struct bwn_mac *mac)
10427 {
10428 	struct bwn_dma *dma = &mac->mac_method.dma;
10429 	struct bwn_softc *sc = mac->mac_sc;
10430 	struct siba_dev_softc *sd = mac->mac_sd;
10431 	struct siba_softc *siba = sd->sd_bus;
10432 	bus_addr_t lowaddr = 0;
10433 	int error;
10434 
10435 	if (siba->siba_type == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10436 		return (0);
10437 
10438 	KASSERT(mac->mac_sd->sd_id.sd_rev >= 5, ("%s: fail", __func__));
10439 
10440 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
10441 
10442 	dma->dmatype = bwn_dma_gettype(mac);
10443 	if (dma->dmatype == BWN_DMA_30BIT)
10444 		lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10445 	else if (dma->dmatype == BWN_DMA_32BIT)
10446 		lowaddr = BUS_SPACE_MAXADDR_32BIT;
10447 	else
10448 		lowaddr = BUS_SPACE_MAXADDR;
10449 
10450 	/*
10451 	 * Create top level DMA tag
10452 	 */
10453 	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),	/* parent */
10454 			       BWN_ALIGN, 0,		/* alignment, bounds */
10455 			       lowaddr,			/* lowaddr */
10456 			       BUS_SPACE_MAXADDR,	/* highaddr */
10457 			       NULL, NULL,		/* filter, filterarg */
10458 			       MAXBSIZE,		/* maxsize */
10459 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
10460 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
10461 			       0,			/* flags */
10462 			       NULL, NULL,		/* lockfunc, lockarg */
10463 			       &dma->parent_dtag);
10464 	if (error) {
10465 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10466 		return (error);
10467 	}
10468 
10469 	/*
10470 	 * Create TX/RX mbuf DMA tag
10471 	 */
10472 	error = bus_dma_tag_create(dma->parent_dtag,
10473 				1,
10474 				0,
10475 				BUS_SPACE_MAXADDR,
10476 				BUS_SPACE_MAXADDR,
10477 				NULL, NULL,
10478 				MCLBYTES,
10479 				1,
10480 				BUS_SPACE_MAXSIZE_32BIT,
10481 				0,
10482 				NULL, NULL,
10483 				&dma->rxbuf_dtag);
10484 	if (error) {
10485 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10486 		goto fail0;
10487 	}
10488 	error = bus_dma_tag_create(dma->parent_dtag,
10489 				1,
10490 				0,
10491 				BUS_SPACE_MAXADDR,
10492 				BUS_SPACE_MAXADDR,
10493 				NULL, NULL,
10494 				MCLBYTES,
10495 				1,
10496 				BUS_SPACE_MAXSIZE_32BIT,
10497 				0,
10498 				NULL, NULL,
10499 				&dma->txbuf_dtag);
10500 	if (error) {
10501 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10502 		goto fail1;
10503 	}
10504 
10505 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10506 	if (!dma->wme[WME_AC_BK])
10507 		goto fail2;
10508 
10509 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10510 	if (!dma->wme[WME_AC_BE])
10511 		goto fail3;
10512 
10513 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10514 	if (!dma->wme[WME_AC_VI])
10515 		goto fail4;
10516 
10517 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10518 	if (!dma->wme[WME_AC_VO])
10519 		goto fail5;
10520 
10521 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10522 	if (!dma->mcast)
10523 		goto fail6;
10524 	dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10525 	if (!dma->rx)
10526 		goto fail7;
10527 
10528 	return (error);
10529 
10530 fail7:	bwn_dma_ringfree(&dma->mcast);
10531 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10532 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10533 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10534 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10535 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
10536 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
10537 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
10538 	return (error);
10539 }
10540 
10541 static struct bwn_dma_ring *
10542 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10543     uint16_t cookie, int *slot)
10544 {
10545 	struct bwn_dma *dma = &mac->mac_method.dma;
10546 	struct bwn_dma_ring *dr;
10547 	struct bwn_softc *sc = mac->mac_sc;
10548 
10549 	BWN_ASSERT_LOCKED(mac->mac_sc);
10550 
10551 	switch (cookie & 0xf000) {
10552 	case 0x1000:
10553 		dr = dma->wme[WME_AC_BK];
10554 		break;
10555 	case 0x2000:
10556 		dr = dma->wme[WME_AC_BE];
10557 		break;
10558 	case 0x3000:
10559 		dr = dma->wme[WME_AC_VI];
10560 		break;
10561 	case 0x4000:
10562 		dr = dma->wme[WME_AC_VO];
10563 		break;
10564 	case 0x5000:
10565 		dr = dma->mcast;
10566 		break;
10567 	default:
10568 		dr = NULL;
10569 		KASSERT(0 == 1,
10570 		    ("invalid cookie value %d", cookie & 0xf000));
10571 	}
10572 	*slot = (cookie & 0x0fff);
10573 	if (*slot < 0 || *slot >= dr->dr_numslots) {
10574 		/*
10575 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10576 		 * that it occurs events which have same H/W sequence numbers.
10577 		 * When it's occurred just prints a WARNING msgs and ignores.
10578 		 */
10579 		KASSERT(status->seq == dma->lastseq,
10580 		    ("%s:%d: fail", __func__, __LINE__));
10581 		device_printf(sc->sc_dev,
10582 		    "out of slot ranges (0 < %d < %d)\n", *slot,
10583 		    dr->dr_numslots);
10584 		return (NULL);
10585 	}
10586 	dma->lastseq = status->seq;
10587 	return (dr);
10588 }
10589 
10590 static void
10591 bwn_dma_stop(struct bwn_mac *mac)
10592 {
10593 	struct bwn_dma *dma;
10594 
10595 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10596 		return;
10597 	dma = &mac->mac_method.dma;
10598 
10599 	bwn_dma_ringstop(&dma->rx);
10600 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10601 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10602 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10603 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10604 	bwn_dma_ringstop(&dma->mcast);
10605 }
10606 
10607 static void
10608 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10609 {
10610 
10611 	if (dr == NULL)
10612 		return;
10613 
10614 	bwn_dma_cleanup(*dr);
10615 }
10616 
10617 static void
10618 bwn_pio_stop(struct bwn_mac *mac)
10619 {
10620 	struct bwn_pio *pio;
10621 
10622 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10623 		return;
10624 	pio = &mac->mac_method.pio;
10625 
10626 	bwn_destroy_queue_tx(&pio->mcast);
10627 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10628 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10629 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10630 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10631 }
10632 
10633 static void
10634 bwn_led_attach(struct bwn_mac *mac)
10635 {
10636 	struct bwn_softc *sc = mac->mac_sc;
10637 	struct siba_softc *siba = mac->mac_sd->sd_bus;
10638 	const uint8_t *led_act = NULL;
10639 	uint16_t val[BWN_LED_MAX];
10640 	int i;
10641 
10642 	sc->sc_led_idle = (2350 * hz) / 1000;
10643 	sc->sc_led_blink = 1;
10644 
10645 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10646 		if (siba->siba_pci_subvid == bwn_vendor_led_act[i].vid) {
10647 			led_act = bwn_vendor_led_act[i].led_act;
10648 			break;
10649 		}
10650 	}
10651 	if (led_act == NULL)
10652 		led_act = bwn_default_led_act;
10653 
10654 	val[0] = siba->siba_sprom.gpio0;
10655 	val[1] = siba->siba_sprom.gpio1;
10656 	val[2] = siba->siba_sprom.gpio2;
10657 	val[3] = siba->siba_sprom.gpio3;
10658 
10659 	for (i = 0; i < BWN_LED_MAX; ++i) {
10660 		struct bwn_led *led = &sc->sc_leds[i];
10661 
10662 		if (val[i] == 0xff) {
10663 			led->led_act = led_act[i];
10664 		} else {
10665 			if (val[i] & BWN_LED_ACT_LOW)
10666 				led->led_flags |= BWN_LED_F_ACTLOW;
10667 			led->led_act = val[i] & BWN_LED_ACT_MASK;
10668 		}
10669 		led->led_mask = (1 << i);
10670 
10671 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10672 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
10673 		    led->led_act == BWN_LED_ACT_BLINK) {
10674 			led->led_flags |= BWN_LED_F_BLINK;
10675 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10676 				led->led_flags |= BWN_LED_F_POLLABLE;
10677 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10678 				led->led_flags |= BWN_LED_F_SLOW;
10679 
10680 			if (sc->sc_blink_led == NULL) {
10681 				sc->sc_blink_led = led;
10682 				if (led->led_flags & BWN_LED_F_SLOW)
10683 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
10684 			}
10685 		}
10686 
10687 		DPRINTF(sc, BWN_DEBUG_LED,
10688 		    "%dth led, act %d, lowact %d\n", i,
10689 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10690 	}
10691 	callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10692 }
10693 
10694 static __inline uint16_t
10695 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10696 {
10697 
10698 	if (led->led_flags & BWN_LED_F_ACTLOW)
10699 		on = !on;
10700 	if (on)
10701 		val |= led->led_mask;
10702 	else
10703 		val &= ~led->led_mask;
10704 	return val;
10705 }
10706 
10707 static void
10708 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10709 {
10710 	struct bwn_softc *sc = mac->mac_sc;
10711 	struct ifnet *ifp = sc->sc_ifp;
10712 	struct ieee80211com *ic = ifp->if_l2com;
10713 	uint16_t val;
10714 	int i;
10715 
10716 	if (nstate == IEEE80211_S_INIT) {
10717 		callout_stop(&sc->sc_led_blink_ch);
10718 		sc->sc_led_blinking = 0;
10719 	}
10720 
10721 	if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10722 		return;
10723 
10724 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10725 	for (i = 0; i < BWN_LED_MAX; ++i) {
10726 		struct bwn_led *led = &sc->sc_leds[i];
10727 		int on;
10728 
10729 		if (led->led_act == BWN_LED_ACT_UNKN ||
10730 		    led->led_act == BWN_LED_ACT_NULL)
10731 			continue;
10732 
10733 		if ((led->led_flags & BWN_LED_F_BLINK) &&
10734 		    nstate != IEEE80211_S_INIT)
10735 			continue;
10736 
10737 		switch (led->led_act) {
10738 		case BWN_LED_ACT_ON:    /* Always on */
10739 			on = 1;
10740 			break;
10741 		case BWN_LED_ACT_OFF:   /* Always off */
10742 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10743 			on = 0;
10744 			break;
10745 		default:
10746 			on = 1;
10747 			switch (nstate) {
10748 			case IEEE80211_S_INIT:
10749 				on = 0;
10750 				break;
10751 			case IEEE80211_S_RUN:
10752 				if (led->led_act == BWN_LED_ACT_11G &&
10753 				    ic->ic_curmode != IEEE80211_MODE_11G)
10754 					on = 0;
10755 				break;
10756 			default:
10757 				if (led->led_act == BWN_LED_ACT_ASSOC)
10758 					on = 0;
10759 				break;
10760 			}
10761 			break;
10762 		}
10763 
10764 		val = bwn_led_onoff(led, val, on);
10765 	}
10766 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10767 }
10768 
10769 static void
10770 bwn_led_event(struct bwn_mac *mac, int event)
10771 {
10772 	struct bwn_softc *sc = mac->mac_sc;
10773         struct bwn_led *led = sc->sc_blink_led;
10774         int rate;
10775 
10776         if (event == BWN_LED_EVENT_POLL) {
10777                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10778                         return;
10779                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10780                         return;
10781         }
10782 
10783         sc->sc_led_ticks = ticks;
10784         if (sc->sc_led_blinking)
10785                 return;
10786 
10787         switch (event) {
10788         case BWN_LED_EVENT_RX:
10789                 rate = sc->sc_rx_rate;
10790                 break;
10791         case BWN_LED_EVENT_TX:
10792                 rate = sc->sc_tx_rate;
10793                 break;
10794         case BWN_LED_EVENT_POLL:
10795                 rate = 0;
10796                 break;
10797         default:
10798                 panic("unknown LED event %d\n", event);
10799                 break;
10800         }
10801         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10802             bwn_led_duration[rate].off_dur);
10803 }
10804 
10805 static void
10806 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10807 {
10808 	struct bwn_softc *sc = mac->mac_sc;
10809         struct bwn_led *led = sc->sc_blink_led;
10810         uint16_t val;
10811 
10812         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10813         val = bwn_led_onoff(led, val, 1);
10814         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10815 
10816         if (led->led_flags & BWN_LED_F_SLOW) {
10817                 BWN_LED_SLOWDOWN(on_dur);
10818                 BWN_LED_SLOWDOWN(off_dur);
10819         }
10820 
10821         sc->sc_led_blinking = 1;
10822         sc->sc_led_blink_offdur = off_dur;
10823 
10824         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10825 }
10826 
10827 static void
10828 bwn_led_blink_next(void *arg)
10829 {
10830 	struct bwn_mac *mac = arg;
10831         struct bwn_softc *sc = mac->mac_sc;
10832         uint16_t val;
10833 
10834         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10835         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10836         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10837 
10838         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10839             bwn_led_blink_end, mac);
10840 }
10841 
10842 static void
10843 bwn_led_blink_end(void *arg)
10844 {
10845 	struct bwn_mac *mac = arg;
10846         struct bwn_softc *sc = mac->mac_sc;
10847 
10848         sc->sc_led_blinking = 0;
10849 }
10850 
10851 static int
10852 bwn_suspend(device_t dev)
10853 {
10854 	struct bwn_softc *sc = device_get_softc(dev);
10855 
10856 	bwn_stop(sc, 1);
10857 	return (0);
10858 }
10859 
10860 static int
10861 bwn_resume(device_t dev)
10862 {
10863 	struct bwn_softc *sc = device_get_softc(dev);
10864 	struct ifnet *ifp = sc->sc_ifp;
10865 
10866 	if (ifp->if_flags & IFF_UP)
10867 		bwn_init(sc);
10868 	return (0);
10869 }
10870 
10871 static void
10872 bwn_rfswitch(void *arg)
10873 {
10874 	struct bwn_softc *sc = arg;
10875 	struct bwn_mac *mac = sc->sc_curmac;
10876 	int cur = 0, prev = 0;
10877 
10878 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10879 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
10880 
10881 	if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10882 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10883 			& BWN_RF_HWENABLED_HI_MASK))
10884 			cur = 1;
10885 	} else {
10886 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10887 		    & BWN_RF_HWENABLED_LO_MASK)
10888 			cur = 1;
10889 	}
10890 
10891 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10892 		prev = 1;
10893 
10894 	if (cur != prev) {
10895 		if (cur)
10896 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10897 		else
10898 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10899 
10900 		device_printf(sc->sc_dev,
10901 		    "status of RF switch is changed to %s\n",
10902 		    cur ? "ON" : "OFF");
10903 		if (cur != mac->mac_phy.rf_on) {
10904 			if (cur)
10905 				bwn_rf_turnon(mac);
10906 			else
10907 				bwn_rf_turnoff(mac);
10908 		}
10909 	}
10910 
10911 	callout_schedule(&sc->sc_rfswitch_ch, hz);
10912 }
10913 
10914 static void
10915 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10916 {
10917 	struct bwn_phy *phy = &mac->mac_phy;
10918 	struct bwn_phy_lp *plp = &phy->phy_lp;
10919 
10920 	plp->plp_antenna = BWN_ANT_DEFAULT;
10921 }
10922 
10923 static int
10924 bwn_phy_lp_init(struct bwn_mac *mac)
10925 {
10926 	static const struct bwn_stxtable tables[] = {
10927 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10928 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10929 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10930 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10931 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10932 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10933 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10934 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10935 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10936 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10937 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10938 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10939 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10940 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10941 		{ 2, 11, 0x40, 0, 0x0f }
10942 	};
10943 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10944 	struct bwn_softc *sc = mac->mac_sc;
10945 	const struct bwn_stxtable *st;
10946 	struct ifnet *ifp = sc->sc_ifp;
10947 	struct ieee80211com *ic = ifp->if_l2com;
10948 	int i, error;
10949 	uint16_t tmp;
10950 
10951 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
10952 	bwn_phy_lp_bbinit(mac);
10953 
10954 	/* initialize RF */
10955 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10956 	DELAY(1);
10957 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10958 	DELAY(1);
10959 
10960 	if (mac->mac_phy.rf_ver == 0x2062)
10961 		bwn_phy_lp_b2062_init(mac);
10962 	else {
10963 		bwn_phy_lp_b2063_init(mac);
10964 
10965 		/* synchronize stx table. */
10966 		for (i = 0; i < N(tables); i++) {
10967 			st = &tables[i];
10968 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
10969 			tmp >>= st->st_rfshift;
10970 			tmp <<= st->st_physhift;
10971 			BWN_PHY_SETMASK(mac,
10972 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10973 			    ~(st->st_mask << st->st_physhift), tmp);
10974 		}
10975 
10976 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10977 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10978 	}
10979 
10980 	/* calibrate RC */
10981 	if (mac->mac_phy.rev >= 2)
10982 		bwn_phy_lp_rxcal_r2(mac);
10983 	else if (!plp->plp_rccap) {
10984 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10985 			bwn_phy_lp_rccal_r12(mac);
10986 	} else
10987 		bwn_phy_lp_set_rccap(mac);
10988 
10989 	error = bwn_phy_lp_switch_channel(mac, 7);
10990 	if (error)
10991 		device_printf(sc->sc_dev,
10992 		    "failed to change channel 7 (%d)\n", error);
10993 	bwn_phy_lp_txpctl_init(mac);
10994 	bwn_phy_lp_calib(mac);
10995 	return (0);
10996 }
10997 
10998 static uint16_t
10999 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
11000 {
11001 
11002 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
11003 	return (BWN_READ_2(mac, BWN_PHYDATA));
11004 }
11005 
11006 static void
11007 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
11008 {
11009 
11010 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
11011 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
11012 }
11013 
11014 static void
11015 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
11016     uint16_t set)
11017 {
11018 
11019 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
11020 	BWN_WRITE_2(mac, BWN_PHYDATA,
11021 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
11022 }
11023 
11024 static uint16_t
11025 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
11026 {
11027 
11028 	KASSERT(reg != 1, ("unaccessible register %d", reg));
11029 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
11030 		reg |= 0x100;
11031 	if (mac->mac_phy.rev >= 2)
11032 		reg |= 0x200;
11033 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
11034 	return BWN_READ_2(mac, BWN_RFDATALO);
11035 }
11036 
11037 static void
11038 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
11039 {
11040 
11041 	KASSERT(reg != 1, ("unaccessible register %d", reg));
11042 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
11043 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
11044 }
11045 
11046 static void
11047 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
11048 {
11049 
11050 	if (on) {
11051 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
11052 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
11053 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
11054 		return;
11055 	}
11056 
11057 	if (mac->mac_phy.rev >= 2) {
11058 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
11059 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11060 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
11061 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
11062 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
11063 		return;
11064 	}
11065 
11066 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11067 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11068 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11069 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11070 }
11071 
11072 static int
11073 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11074 {
11075 	struct bwn_phy *phy = &mac->mac_phy;
11076 	struct bwn_phy_lp *plp = &phy->phy_lp;
11077 	int error;
11078 
11079 	if (phy->rf_ver == 0x2063) {
11080 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11081 		if (error)
11082 			return (error);
11083 	} else {
11084 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11085 		if (error)
11086 			return (error);
11087 		bwn_phy_lp_set_anafilter(mac, chan);
11088 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11089 	}
11090 
11091 	plp->plp_chan = chan;
11092 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11093 	return (0);
11094 }
11095 
11096 static uint32_t
11097 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11098 {
11099 	struct bwn_softc *sc = mac->mac_sc;
11100 	struct ifnet *ifp = sc->sc_ifp;
11101 	struct ieee80211com *ic = ifp->if_l2com;
11102 
11103 	device_printf(sc->sc_dev, "correct?\n");
11104 
11105 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11106 }
11107 
11108 static void
11109 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11110 {
11111 	struct bwn_phy *phy = &mac->mac_phy;
11112 	struct bwn_phy_lp *plp = &phy->phy_lp;
11113 
11114 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11115 		return;
11116 
11117 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11118 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11119 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11120 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11121 	plp->plp_antenna = antenna;
11122 }
11123 
11124 static void
11125 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11126 {
11127 
11128 	bwn_phy_lp_calib(mac);
11129 }
11130 
11131 static void
11132 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11133 {
11134 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11135 	struct bwn_softc *sc = mac->mac_sc;
11136 	struct ifnet *ifp = sc->sc_ifp;
11137 	struct ieee80211com *ic = ifp->if_l2com;
11138 	struct siba_dev_softc *sd = mac->mac_sd;
11139 	struct siba_softc *siba = sd->sd_bus;
11140 	struct siba_sprom *sprom = &siba->siba_sprom;
11141 
11142 	device_printf(sc->sc_dev, "XXX using %dghz\n",
11143 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 2 : 5);
11144 
11145 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11146 		plp->plp_txisoband_m = sprom->tri2g;
11147 		plp->plp_bxarch = sprom->bxa2g;
11148 		plp->plp_rxpwroffset = sprom->rxpo2g;
11149 		plp->plp_rssivf = sprom->rssismf2g;
11150 		plp->plp_rssivc = sprom->rssismc2g;
11151 		plp->plp_rssigs = sprom->rssisav2g;
11152 		return;
11153 	}
11154 
11155 	plp->plp_txisoband_l = sprom->tri5gl;
11156 	plp->plp_txisoband_m = sprom->tri5g;
11157 	plp->plp_txisoband_h = sprom->tri5gh;
11158 	plp->plp_bxarch = sprom->bxa5g;
11159 	plp->plp_rxpwroffset = sprom->rxpo5g;
11160 	plp->plp_rssivf = sprom->rssismf5g;
11161 	plp->plp_rssivc = sprom->rssismc5g;
11162 	plp->plp_rssigs = sprom->rssisav5g;
11163 }
11164 
11165 static void
11166 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11167 {
11168 
11169 	bwn_phy_lp_tblinit(mac);
11170 	if (mac->mac_phy.rev >= 2)
11171 		bwn_phy_lp_bbinit_r2(mac);
11172 	else
11173 		bwn_phy_lp_bbinit_r01(mac);
11174 }
11175 
11176 static void
11177 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11178 {
11179 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11180 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11181 	struct bwn_softc *sc = mac->mac_sc;
11182 	struct ifnet *ifp = sc->sc_ifp;
11183 	struct ieee80211com *ic = ifp->if_l2com;
11184 
11185 	bwn_phy_lp_set_txgain(mac,
11186 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11187 	bwn_phy_lp_set_bbmult(mac, 150);
11188 }
11189 
11190 static void
11191 bwn_phy_lp_calib(struct bwn_mac *mac)
11192 {
11193 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11194 	struct siba_dev_softc *sd = mac->mac_sd;
11195 	struct siba_softc *siba = sd->sd_bus;
11196 	struct bwn_softc *sc = mac->mac_sc;
11197 	struct ifnet *ifp = sc->sc_ifp;
11198 	struct ieee80211com *ic = ifp->if_l2com;
11199 	const struct bwn_rxcompco *rc = NULL;
11200 	struct bwn_txgain ogain;
11201 	int i, omode, oafeovr, orf, obbmult;
11202 	uint8_t mode, fc = 0;
11203 
11204 	if (plp->plp_chanfullcal != plp->plp_chan) {
11205 		plp->plp_chanfullcal = plp->plp_chan;
11206 		fc = 1;
11207 	}
11208 
11209 	bwn_mac_suspend(mac);
11210 
11211 	/* BlueTooth Coexistance Override */
11212 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11213 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11214 
11215 	if (mac->mac_phy.rev >= 2)
11216 		bwn_phy_lp_digflt_save(mac);
11217 	bwn_phy_lp_get_txpctlmode(mac);
11218 	mode = plp->plp_txpctlmode;
11219 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11220 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11221 		bwn_phy_lp_bugfix(mac);
11222 	if (mac->mac_phy.rev >= 2 && fc == 1) {
11223 		bwn_phy_lp_get_txpctlmode(mac);
11224 		omode = plp->plp_txpctlmode;
11225 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11226 		if (oafeovr)
11227 			ogain = bwn_phy_lp_get_txgain(mac);
11228 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11229 		obbmult = bwn_phy_lp_get_bbmult(mac);
11230 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11231 		if (oafeovr)
11232 			bwn_phy_lp_set_txgain(mac, &ogain);
11233 		bwn_phy_lp_set_bbmult(mac, obbmult);
11234 		bwn_phy_lp_set_txpctlmode(mac, omode);
11235 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11236 	}
11237 	bwn_phy_lp_set_txpctlmode(mac, mode);
11238 	if (mac->mac_phy.rev >= 2)
11239 		bwn_phy_lp_digflt_restore(mac);
11240 
11241 	/* do RX IQ Calculation; assumes that noise is true. */
11242 	if (siba->siba_chipid == 0x5354) {
11243 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11244 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11245 				rc = &bwn_rxcompco_5354[i];
11246 		}
11247 	} else if (mac->mac_phy.rev >= 2)
11248 		rc = &bwn_rxcompco_r2;
11249 	else {
11250 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11251 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11252 				rc = &bwn_rxcompco_r12[i];
11253 		}
11254 	}
11255 	if (rc == NULL)
11256 		goto fail;
11257 
11258 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11259 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11260 
11261 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11262 
11263 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11264 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11265 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11266 	} else {
11267 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11268 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11269 	}
11270 
11271 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11272 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11273 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11274 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11275 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11276 	bwn_phy_lp_set_deaf(mac, 0);
11277 	/* XXX no checking return value? */
11278 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11279 	bwn_phy_lp_clear_deaf(mac, 0);
11280 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11281 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11282 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11283 
11284 	/* disable RX GAIN override. */
11285 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11286 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11287 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11288 	if (mac->mac_phy.rev >= 2) {
11289 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11290 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11291 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11292 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11293 		}
11294 	} else {
11295 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11296 	}
11297 
11298 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11299 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11300 fail:
11301 	bwn_mac_enable(mac);
11302 }
11303 
11304 static void
11305 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11306 {
11307 
11308        if (on) {
11309                BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11310 	       return;
11311        }
11312 
11313        BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11314        BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11315 }
11316 
11317 static int
11318 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11319 {
11320 	struct siba_dev_softc *sd = mac->mac_sd;
11321 	struct siba_softc *siba = sd->sd_bus;
11322 	static const struct bwn_b206x_chan *bc = NULL;
11323 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11324 	    tmp[6];
11325 	uint16_t old, scale, tmp16;
11326 	int i, div;
11327 
11328 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
11329 		if (bwn_b2063_chantable[i].bc_chan == chan) {
11330 			bc = &bwn_b2063_chantable[i];
11331 			break;
11332 		}
11333 	}
11334 	if (bc == NULL)
11335 		return (EINVAL);
11336 
11337 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11338 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11339 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11340 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11341 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11342 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11343 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11344 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11345 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11346 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11347 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11348 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11349 
11350 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
11351 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11352 
11353 	freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
11354 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11355 	freqref = freqxtal * 3;
11356 	div = (freqxtal <= 26000000 ? 1 : 2);
11357 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11358 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11359 		999999) / 1000000) + 1;
11360 
11361 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11362 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11363 	    0xfff8, timeout >> 2);
11364 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11365 	    0xff9f,timeout << 5);
11366 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11367 
11368 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11369 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11370 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11371 
11372 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11373 	    (timeoutref + 1)) - 1;
11374 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11375 	    0xf0, count >> 8);
11376 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11377 
11378 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
11379 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
11380 	while (tmp[1] >= freqref) {
11381 		tmp[0]++;
11382 		tmp[1] -= freqref;
11383 	}
11384 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11385 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11386 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11387 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11388 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11389 
11390 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11391 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11392 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11393 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11394 
11395 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11396 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11397 
11398 	if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11399 		scale = 1;
11400 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11401 	} else {
11402 		scale = 0;
11403 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11404 	}
11405 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11406 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11407 
11408 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11409 	    (scale + 1);
11410 	if (tmp[5] > 150)
11411 		tmp[5] = 0;
11412 
11413 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11414 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11415 
11416 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11417 	if (freqxtal > 26000000)
11418 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11419 	else
11420 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11421 
11422 	if (val[0] == 45)
11423 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11424 	else
11425 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11426 
11427 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11428 	DELAY(1);
11429 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11430 
11431 	/* VCO Calibration */
11432 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11433 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11434 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11435 	DELAY(1);
11436 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11437 	DELAY(1);
11438 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11439 	DELAY(1);
11440 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11441 	DELAY(300);
11442 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11443 
11444 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11445 	return (0);
11446 }
11447 
11448 static int
11449 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11450 {
11451 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11452 	struct siba_dev_softc *sd = mac->mac_sd;
11453 	struct siba_softc *siba = sd->sd_bus;
11454 	const struct bwn_b206x_chan *bc = NULL;
11455 	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
11456 	uint32_t tmp[9];
11457 	int i;
11458 
11459 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
11460 		if (bwn_b2062_chantable[i].bc_chan == chan) {
11461 			bc = &bwn_b2062_chantable[i];
11462 			break;
11463 		}
11464 	}
11465 
11466 	if (bc == NULL)
11467 		return (EINVAL);
11468 
11469 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11470 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11471 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11472 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11473 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11474 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11475 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11476 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11477 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11478 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11479 
11480 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11481 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11482 	bwn_phy_lp_b2062_reset_pllbias(mac);
11483 	tmp[0] = freqxtal / 1000;
11484 	tmp[1] = plp->plp_div * 1000;
11485 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11486 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
11487 		tmp[2] *= 2;
11488 	tmp[3] = 48 * tmp[0];
11489 	tmp[5] = tmp[2] / tmp[3];
11490 	tmp[6] = tmp[2] % tmp[3];
11491 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11492 	tmp[4] = tmp[6] * 0x100;
11493 	tmp[5] = tmp[4] / tmp[3];
11494 	tmp[6] = tmp[4] % tmp[3];
11495 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11496 	tmp[4] = tmp[6] * 0x100;
11497 	tmp[5] = tmp[4] / tmp[3];
11498 	tmp[6] = tmp[4] % tmp[3];
11499 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11500 	tmp[4] = tmp[6] * 0x100;
11501 	tmp[5] = tmp[4] / tmp[3];
11502 	tmp[6] = tmp[4] % tmp[3];
11503 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11504 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
11505 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11506 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11507 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11508 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11509 
11510 	bwn_phy_lp_b2062_vco_calib(mac);
11511 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11512 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11513 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11514 		bwn_phy_lp_b2062_reset_pllbias(mac);
11515 		bwn_phy_lp_b2062_vco_calib(mac);
11516 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11517 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11518 			return (EIO);
11519 		}
11520 	}
11521 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11522 	return (0);
11523 }
11524 
11525 static void
11526 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11527 {
11528 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11529 	uint16_t tmp = (channel == 14);
11530 
11531 	if (mac->mac_phy.rev < 2) {
11532 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11533 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11534 			bwn_phy_lp_set_rccap(mac);
11535 		return;
11536 	}
11537 
11538 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11539 }
11540 
11541 static void
11542 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11543 {
11544 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11545 	struct bwn_softc *sc = mac->mac_sc;
11546 	struct ifnet *ifp = sc->sc_ifp;
11547 	struct ieee80211com *ic = ifp->if_l2com;
11548 	uint16_t iso, tmp[3];
11549 
11550 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11551 
11552 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11553 		iso = plp->plp_txisoband_m;
11554 	else if (freq <= 5320)
11555 		iso = plp->plp_txisoband_l;
11556 	else if (freq <= 5700)
11557 		iso = plp->plp_txisoband_m;
11558 	else
11559 		iso = plp->plp_txisoband_h;
11560 
11561 	tmp[0] = ((iso - 26) / 12) << 12;
11562 	tmp[1] = tmp[0] + 0x1000;
11563 	tmp[2] = tmp[0] + 0x2000;
11564 
11565 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11566 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11567 }
11568 
11569 static void
11570 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11571 {
11572 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11573 	int i;
11574 	static const uint16_t addr[] = {
11575 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11576 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11577 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11578 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11579 		BWN_PHY_OFDM(0xcf),
11580 	};
11581 	static const uint16_t val[] = {
11582 		0xde5e, 0xe832, 0xe331, 0x4d26,
11583 		0x0026, 0x1420, 0x0020, 0xfe08,
11584 		0x0008,
11585 	};
11586 
11587 	for (i = 0; i < N(addr); i++) {
11588 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11589 		BWN_PHY_WRITE(mac, addr[i], val[i]);
11590 	}
11591 }
11592 
11593 static void
11594 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11595 {
11596 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11597 	struct bwn_softc *sc = mac->mac_sc;
11598 	uint16_t ctl;
11599 
11600 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11601 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11602 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11603 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11604 		break;
11605 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11606 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11607 		break;
11608 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11609 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11610 		break;
11611 	default:
11612 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11613 		device_printf(sc->sc_dev, "unknown command mode\n");
11614 		break;
11615 	}
11616 }
11617 
11618 static void
11619 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11620 {
11621 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11622 	uint16_t ctl;
11623 	uint8_t old;
11624 
11625 	bwn_phy_lp_get_txpctlmode(mac);
11626 	old = plp->plp_txpctlmode;
11627 	if (old == mode)
11628 		return;
11629 	plp->plp_txpctlmode = mode;
11630 
11631 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11632 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11633 		    plp->plp_tssiidx);
11634 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11635 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11636 
11637 		/* disable TX GAIN override */
11638 		if (mac->mac_phy.rev < 2)
11639 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11640 		else {
11641 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11642 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11643 		}
11644 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11645 
11646 		plp->plp_txpwridx = -1;
11647 	}
11648 	if (mac->mac_phy.rev >= 2) {
11649 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11650 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11651 		else
11652 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11653 	}
11654 
11655 	/* writes TX Power Control mode */
11656 	switch (plp->plp_txpctlmode) {
11657 	case BWN_PHYLP_TXPCTL_OFF:
11658 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11659 		break;
11660 	case BWN_PHYLP_TXPCTL_ON_HW:
11661 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11662 		break;
11663 	case BWN_PHYLP_TXPCTL_ON_SW:
11664 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11665 		break;
11666 	default:
11667 		ctl = 0;
11668 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11669 	}
11670 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11671 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11672 }
11673 
11674 static void
11675 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11676 {
11677 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11678 	struct bwn_softc *sc = mac->mac_sc;
11679 	const unsigned int size = 256;
11680 	struct bwn_txgain tg;
11681 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11682 	uint16_t tssinpt, tssiidx, value[2];
11683 	uint8_t mode;
11684 	int8_t txpwridx;
11685 
11686 	tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11687 	    M_NOWAIT | M_ZERO);
11688 	if (tabs == NULL) {
11689 		device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11690 		return;
11691 	}
11692 
11693 	bwn_phy_lp_get_txpctlmode(mac);
11694 	mode = plp->plp_txpctlmode;
11695 	txpwridx = plp->plp_txpwridx;
11696 	tssinpt = plp->plp_tssinpt;
11697 	tssiidx = plp->plp_tssiidx;
11698 
11699 	bwn_tab_read_multi(mac,
11700 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11701 	    BWN_TAB_4(7, 0x140), size, tabs);
11702 
11703 	bwn_phy_lp_tblinit(mac);
11704 	bwn_phy_lp_bbinit(mac);
11705 	bwn_phy_lp_txpctl_init(mac);
11706 	bwn_phy_lp_rf_onoff(mac, 1);
11707 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11708 
11709 	bwn_tab_write_multi(mac,
11710 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11711 	    BWN_TAB_4(7, 0x140), size, tabs);
11712 
11713 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11714 	plp->plp_tssinpt = tssinpt;
11715 	plp->plp_tssiidx = tssiidx;
11716 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11717 	if (txpwridx != -1) {
11718 		/* set TX power by index */
11719 		plp->plp_txpwridx = txpwridx;
11720 		bwn_phy_lp_get_txpctlmode(mac);
11721 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11722 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11723 		if (mac->mac_phy.rev >= 2) {
11724 			rxcomp = bwn_tab_read(mac,
11725 			    BWN_TAB_4(7, txpwridx + 320));
11726 			txgain = bwn_tab_read(mac,
11727 			    BWN_TAB_4(7, txpwridx + 192));
11728 			tg.tg_pad = (txgain >> 16) & 0xff;
11729 			tg.tg_gm = txgain & 0xff;
11730 			tg.tg_pga = (txgain >> 8) & 0xff;
11731 			tg.tg_dac = (rxcomp >> 28) & 0xff;
11732 			bwn_phy_lp_set_txgain(mac, &tg);
11733 		} else {
11734 			rxcomp = bwn_tab_read(mac,
11735 			    BWN_TAB_4(10, txpwridx + 320));
11736 			txgain = bwn_tab_read(mac,
11737 			    BWN_TAB_4(10, txpwridx + 192));
11738 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11739 			    0xf800, (txgain >> 4) & 0x7fff);
11740 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11741 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11742 		}
11743 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11744 
11745 		/* set TX IQCC */
11746 		value[0] = (rxcomp >> 10) & 0x3ff;
11747 		value[1] = rxcomp & 0x3ff;
11748 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11749 
11750 		coeff = bwn_tab_read(mac,
11751 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11752 		    BWN_TAB_4(10, txpwridx + 448));
11753 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11754 		if (mac->mac_phy.rev >= 2) {
11755 			rfpwr = bwn_tab_read(mac,
11756 			    BWN_TAB_4(7, txpwridx + 576));
11757 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11758 			    rfpwr & 0xffff);
11759 		}
11760 		bwn_phy_lp_set_txgain_override(mac);
11761 	}
11762 	if (plp->plp_rccap)
11763 		bwn_phy_lp_set_rccap(mac);
11764 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11765 	bwn_phy_lp_set_txpctlmode(mac, mode);
11766 	free(tabs, M_DEVBUF);
11767 }
11768 
11769 static void
11770 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11771 {
11772 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11773 	int i;
11774 	static const uint16_t addr[] = {
11775 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11776 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11777 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11778 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11779 		BWN_PHY_OFDM(0xcf),
11780 	};
11781 
11782 	for (i = 0; i < N(addr); i++)
11783 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11784 }
11785 
11786 static void
11787 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11788 {
11789 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11790 
11791 	if (mac->mac_phy.rev < 2) {
11792 		bwn_phy_lp_tblinit_r01(mac);
11793 		bwn_phy_lp_tblinit_txgain(mac);
11794 		bwn_phy_lp_set_gaintbl(mac, freq);
11795 		return;
11796 	}
11797 
11798 	bwn_phy_lp_tblinit_r2(mac);
11799 	bwn_phy_lp_tblinit_txgain(mac);
11800 }
11801 
11802 struct bwn_wpair {
11803 	uint16_t		reg;
11804 	uint16_t		value;
11805 };
11806 
11807 struct bwn_smpair {
11808 	uint16_t		offset;
11809 	uint16_t		mask;
11810 	uint16_t		set;
11811 };
11812 
11813 static void
11814 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11815 {
11816 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11817 	struct siba_dev_softc *sd = mac->mac_sd;
11818 	struct siba_softc *siba = sd->sd_bus;
11819 	struct bwn_softc *sc = mac->mac_sc;
11820 	struct ifnet *ifp = sc->sc_ifp;
11821 	struct ieee80211com *ic = ifp->if_l2com;
11822 	static const struct bwn_wpair v1[] = {
11823 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
11824 		{ BWN_PHY_AFE_CTL, 0x8800 },
11825 		{ BWN_PHY_AFE_CTL_OVR, 0 },
11826 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
11827 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
11828 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
11829 		{ BWN_PHY_OFDM(0xf9), 0 },
11830 		{ BWN_PHY_TR_LOOKUP_1, 0 }
11831 	};
11832 	static const struct bwn_smpair v2[] = {
11833 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11834 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11835 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11836 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11837 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11838 	};
11839 	static const struct bwn_smpair v3[] = {
11840 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11841 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11842 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11843 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11844 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11845 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11846 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11847 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11848 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11849 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11850 
11851 	};
11852 	int i;
11853 
11854 	for (i = 0; i < N(v1); i++)
11855 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11856 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11857 	for (i = 0; i < N(v2); i++)
11858 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11859 
11860 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11861 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11862 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11863 	if (siba->siba_board_rev >= 0x18) {
11864 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11865 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11866 	} else {
11867 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11868 	}
11869 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11870 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11871 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11872 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11873 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11874 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11875 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11876 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11877 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11878 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11879 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11880 	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
11881 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11882 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11883 	} else {
11884 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11885 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11886 	}
11887 	for (i = 0; i < N(v3); i++)
11888 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11889 	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
11890 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11891 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11892 	}
11893 
11894 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11895 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11896 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11897 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11898 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11899 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11900 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11901 	} else
11902 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11903 
11904 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11905 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11906 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11907 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11908 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11909 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11910 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11911 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11912 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11913 
11914 	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
11915 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11916 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11917 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11918 	}
11919 
11920 	bwn_phy_lp_digflt_save(mac);
11921 }
11922 
11923 static void
11924 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11925 {
11926 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11927 	struct siba_dev_softc *sd = mac->mac_sd;
11928 	struct siba_softc *siba = sd->sd_bus;
11929 	struct bwn_softc *sc = mac->mac_sc;
11930 	struct ifnet *ifp = sc->sc_ifp;
11931 	struct ieee80211com *ic = ifp->if_l2com;
11932 	static const struct bwn_smpair v1[] = {
11933 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11934 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11935 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11936 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11937 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11938 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11939 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11940 	};
11941 	static const struct bwn_smpair v2[] = {
11942 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11943 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11944 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11945 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11946 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11947 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11948 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11949 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11950 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11951 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11952 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11953 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11954 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11955 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11956 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11957 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11958 	};
11959 	static const struct bwn_smpair v3[] = {
11960 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11961 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11962 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11963 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11964 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11965 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11966 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11967 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11968 	};
11969 	static const struct bwn_smpair v4[] = {
11970 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11971 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11972 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11973 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11974 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11975 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11976 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11977 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11978 	};
11979 	static const struct bwn_smpair v5[] = {
11980 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11981 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11982 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11983 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11984 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11985 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11986 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11987 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11988 	};
11989 	int i;
11990 	uint16_t tmp, tmp2;
11991 
11992 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11993 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11994 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11995 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11996 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11997 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11998 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11999 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
12000 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
12001 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
12002 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
12003 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
12004 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
12005 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
12006 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
12007 	for (i = 0; i < N(v1); i++)
12008 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
12009 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
12010 	    0xff00, plp->plp_rxpwroffset);
12011 	if ((siba->siba_sprom.bf_lo & BWN_BFL_FEM) &&
12012 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
12013 	   (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF))) {
12014 		siba_cc_pmu_set_ldovolt(&siba->siba_cc, SIBA_LDO_PAREF, 0x28);
12015 		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 1);
12016 		if (mac->mac_phy.rev == 0)
12017 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
12018 			    0xffcf, 0x0010);
12019 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
12020 	} else {
12021 		siba_cc_pmu_set_ldoparef(&siba->siba_cc, 0);
12022 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
12023 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
12024 	}
12025 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
12026 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
12027 	if (siba->siba_sprom.bf_hi & BWN_BFH_RSSIINV)
12028 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
12029 	else
12030 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
12031 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
12032 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
12033 	    0xfff9, (plp->plp_bxarch << 1));
12034 	if (mac->mac_phy.rev == 1 &&
12035 	    (siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT)) {
12036 		for (i = 0; i < N(v2); i++)
12037 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
12038 			    v2[i].set);
12039 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
12040 	    (siba->siba_board_type == 0x048a) || ((mac->mac_phy.rev == 0) &&
12041 	    (siba->siba_sprom.bf_lo & BWN_BFL_FEM))) {
12042 		for (i = 0; i < N(v3); i++)
12043 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
12044 			    v3[i].set);
12045 	} else if (mac->mac_phy.rev == 1 ||
12046 		  (siba->siba_sprom.bf_lo & BWN_BFL_FEM)) {
12047 		for (i = 0; i < N(v4); i++)
12048 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
12049 			    v4[i].set);
12050 	} else {
12051 		for (i = 0; i < N(v5); i++)
12052 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
12053 			    v5[i].set);
12054 	}
12055 	if (mac->mac_phy.rev == 1 &&
12056 	    (siba->siba_sprom.bf_hi & BWN_BFH_LDO_PAREF)) {
12057 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
12058 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
12059 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
12060 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
12061 	}
12062 	if ((siba->siba_sprom.bf_hi & BWN_BFH_FEM_BT) &&
12063 	    (siba->siba_chipid == 0x5354) &&
12064 	    (siba->siba_chippkg == SIBA_CHIPPACK_BCM4712S)) {
12065 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
12066 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
12067 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
12068 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
12069 	}
12070 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12071 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
12072 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
12073 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
12074 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
12075 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
12076 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
12077 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12078 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12079 	} else {
12080 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12081 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12082 	}
12083 	if (mac->mac_phy.rev == 1) {
12084 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12085 		tmp2 = (tmp & 0x03e0) >> 5;
12086 		tmp2 |= tmp2 << 5;
12087 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12088 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12089 		tmp2 = (tmp & 0x1f00) >> 8;
12090 		tmp2 |= tmp2 << 5;
12091 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12092 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12093 		tmp2 = tmp & 0x00ff;
12094 		tmp2 |= tmp << 8;
12095 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12096 	}
12097 }
12098 
12099 struct bwn_b2062_freq {
12100 	uint16_t		freq;
12101 	uint8_t			value[6];
12102 };
12103 
12104 static void
12105 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12106 {
12107 #define	CALC_CTL7(freq, div)						\
12108 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12109 #define	CALC_CTL18(freq, div)						\
12110 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12111 #define	CALC_CTL19(freq, div)						\
12112 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12113 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12114 	struct siba_dev_softc *sd = mac->mac_sd;
12115 	struct siba_softc *siba = sd->sd_bus;
12116 	struct bwn_softc *sc = mac->mac_sc;
12117 	struct ifnet *ifp = sc->sc_ifp;
12118 	struct ieee80211com *ic = ifp->if_l2com;
12119 	static const struct bwn_b2062_freq freqdata_tab[] = {
12120 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
12121 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
12122 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
12123 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
12124 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
12125 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
12126 	};
12127 	static const struct bwn_wpair v1[] = {
12128 		{ BWN_B2062_N_TXCTL3, 0 },
12129 		{ BWN_B2062_N_TXCTL4, 0 },
12130 		{ BWN_B2062_N_TXCTL5, 0 },
12131 		{ BWN_B2062_N_TXCTL6, 0 },
12132 		{ BWN_B2062_N_PDNCTL0, 0x40 },
12133 		{ BWN_B2062_N_PDNCTL0, 0 },
12134 		{ BWN_B2062_N_CALIB_TS, 0x10 },
12135 		{ BWN_B2062_N_CALIB_TS, 0 }
12136 	};
12137 	const struct bwn_b2062_freq *f = NULL;
12138 	uint32_t xtalfreq, ref;
12139 	unsigned int i;
12140 
12141 	bwn_phy_lp_b2062_tblinit(mac);
12142 
12143 	for (i = 0; i < N(v1); i++)
12144 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12145 	if (mac->mac_phy.rev > 0)
12146 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12147 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12148 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12149 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12150 	else
12151 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12152 
12153 	KASSERT(siba->siba_cc.scc_caps & SIBA_CC_CAPS_PMU,
12154 	    ("%s:%d: fail", __func__, __LINE__));
12155 	xtalfreq = siba->siba_cc.scc_pmu.freq * 1000;
12156 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12157 
12158 	if (xtalfreq <= 30000000) {
12159 		plp->plp_div = 1;
12160 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12161 	} else {
12162 		plp->plp_div = 2;
12163 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12164 	}
12165 
12166 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12167 	    CALC_CTL7(xtalfreq, plp->plp_div));
12168 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12169 	    CALC_CTL18(xtalfreq, plp->plp_div));
12170 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12171 	    CALC_CTL19(xtalfreq, plp->plp_div));
12172 
12173 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12174 	ref &= 0xffff;
12175 	for (i = 0; i < N(freqdata_tab); i++) {
12176 		if (ref < freqdata_tab[i].freq) {
12177 			f = &freqdata_tab[i];
12178 			break;
12179 		}
12180 	}
12181 	if (f == NULL)
12182 		f = &freqdata_tab[N(freqdata_tab) - 1];
12183 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12184 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12185 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12186 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12187 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12188 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12189 #undef CALC_CTL7
12190 #undef CALC_CTL18
12191 #undef CALC_CTL19
12192 }
12193 
12194 static void
12195 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12196 {
12197 
12198 	bwn_phy_lp_b2063_tblinit(mac);
12199 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12200 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12201 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12202 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12203 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12204 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12205 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12206 	if (mac->mac_phy.rev == 2) {
12207 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12208 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12209 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12210 	} else {
12211 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12212 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12213 	}
12214 }
12215 
12216 static void
12217 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12218 {
12219 	struct siba_dev_softc *sd = mac->mac_sd;
12220 	struct siba_softc *siba = sd->sd_bus;
12221 	static const struct bwn_wpair v1[] = {
12222 		{ BWN_B2063_RX_BB_SP8, 0x0 },
12223 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12224 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12225 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
12226 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
12227 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
12228 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
12229 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
12230 	};
12231 	static const struct bwn_wpair v2[] = {
12232 		{ BWN_B2063_TX_BB_SP3, 0x0 },
12233 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
12234 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
12235 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
12236 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
12237 	};
12238 	uint32_t freqxtal = siba->siba_cc.scc_pmu.freq * 1000;
12239 	int i;
12240 	uint8_t tmp;
12241 
12242 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12243 
12244 	for (i = 0; i < 2; i++)
12245 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12246 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12247 	for (i = 2; i < N(v1); i++)
12248 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12249 	for (i = 0; i < 10000; i++) {
12250 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12251 			break;
12252 		DELAY(1000);
12253 	}
12254 
12255 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12256 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12257 
12258 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12259 
12260 	for (i = 0; i < N(v2); i++)
12261 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12262 	if (freqxtal == 24000000) {
12263 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12264 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12265 	} else {
12266 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12267 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12268 	}
12269 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12270 	for (i = 0; i < 10000; i++) {
12271 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12272 			break;
12273 		DELAY(1000);
12274 	}
12275 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12276 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12277 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12278 }
12279 
12280 static void
12281 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12282 {
12283 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12284 	struct bwn_softc *sc = mac->mac_sc;
12285 	struct bwn_phy_lp_iq_est ie;
12286 	struct bwn_txgain tx_gains;
12287 	static const uint32_t pwrtbl[21] = {
12288 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12289 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12290 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12291 		0x0004c, 0x0002c, 0x0001a,
12292 	};
12293 	uint32_t npwr, ipwr, sqpwr, tmp;
12294 	int loopback, i, j, sum, error;
12295 	uint16_t save[7];
12296 	uint8_t txo, bbmult, txpctlmode;
12297 
12298 	error = bwn_phy_lp_switch_channel(mac, 7);
12299 	if (error)
12300 		device_printf(sc->sc_dev,
12301 		    "failed to change channel to 7 (%d)\n", error);
12302 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12303 	bbmult = bwn_phy_lp_get_bbmult(mac);
12304 	if (txo)
12305 		tx_gains = bwn_phy_lp_get_txgain(mac);
12306 
12307 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12308 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12309 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12310 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12311 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12312 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12313 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12314 
12315 	bwn_phy_lp_get_txpctlmode(mac);
12316 	txpctlmode = plp->plp_txpctlmode;
12317 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12318 
12319 	/* disable CRS */
12320 	bwn_phy_lp_set_deaf(mac, 1);
12321 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
12322 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12323 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12324 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12325 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12326 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12327 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12328 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12329 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12330 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12331 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12332 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12333 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12334 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12335 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12336 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12337 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12338 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12339 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12340 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12341 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12342 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12343 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12344 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12345 
12346 	loopback = bwn_phy_lp_loopback(mac);
12347 	if (loopback == -1)
12348 		goto done;
12349 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
12350 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12351 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12352 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12353 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12354 
12355 	tmp = 0;
12356 	memset(&ie, 0, sizeof(ie));
12357 	for (i = 128; i <= 159; i++) {
12358 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12359 		sum = 0;
12360 		for (j = 5; j <= 25; j++) {
12361 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12362 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12363 				goto done;
12364 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12365 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12366 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12367 			    12);
12368 			sum += ((ipwr - npwr) * (ipwr - npwr));
12369 			if ((i == 128) || (sum < tmp)) {
12370 				plp->plp_rccap = i;
12371 				tmp = sum;
12372 			}
12373 		}
12374 	}
12375 	bwn_phy_lp_ddfs_turnoff(mac);
12376 done:
12377 	/* restore CRS */
12378 	bwn_phy_lp_clear_deaf(mac, 1);
12379 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12380 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12381 
12382 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12383 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12384 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12385 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12386 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12387 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12388 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12389 
12390 	bwn_phy_lp_set_bbmult(mac, bbmult);
12391 	if (txo)
12392 		bwn_phy_lp_set_txgain(mac, &tx_gains);
12393 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12394 	if (plp->plp_rccap)
12395 		bwn_phy_lp_set_rccap(mac);
12396 }
12397 
12398 static void
12399 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12400 {
12401 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12402 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12403 
12404 	if (mac->mac_phy.rev == 1)
12405 		rc_cap = MIN(rc_cap + 5, 15);
12406 
12407 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12408 	    MAX(plp->plp_rccap - 4, 0x80));
12409 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12410 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12411 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12412 }
12413 
12414 static uint32_t
12415 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12416 {
12417 	uint32_t i, q, r;
12418 
12419 	if (div == 0)
12420 		return (0);
12421 
12422 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12423 		q <<= 1;
12424 		if (r << 1 >= div) {
12425 			q++;
12426 			r = (r << 1) - div;
12427 		}
12428 	}
12429 	if (r << 1 >= div)
12430 		q++;
12431 	return (q);
12432 }
12433 
12434 static void
12435 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12436 {
12437 	struct siba_dev_softc *sd = mac->mac_sd;
12438 	struct siba_softc *siba = sd->sd_bus;
12439 
12440 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12441 	DELAY(20);
12442 	if (siba->siba_chipid == 0x5354) {
12443 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12444 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12445 	} else {
12446 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12447 	}
12448 	DELAY(5);
12449 }
12450 
12451 static void
12452 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12453 {
12454 
12455 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12456 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12457 	DELAY(200);
12458 }
12459 
12460 static void
12461 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12462 {
12463 #define	FLAG_A	0x01
12464 #define	FLAG_G	0x02
12465 	struct bwn_softc *sc = mac->mac_sc;
12466 	struct ifnet *ifp = sc->sc_ifp;
12467 	struct ieee80211com *ic = ifp->if_l2com;
12468 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12469 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12470 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12471 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12472 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12473 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12474 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12475 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12476 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12477 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12478 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12479 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12480 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12481 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12482 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12483 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12484 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12485 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12486 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12487 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12488 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12489 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12490 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12491 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12492 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12493 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12494 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12495 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12496 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12497 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12498 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12499 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12500 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12501 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12502 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12503 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12504 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12505 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12506 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12507 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12508 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12509 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12510 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12511 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12512 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12513 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12514 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12515 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12516 	};
12517 	const struct bwn_b206x_rfinit_entry *br;
12518 	unsigned int i;
12519 
12520 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12521 		br = &bwn_b2062_init_tab[i];
12522 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12523 			if (br->br_flags & FLAG_G)
12524 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12525 		} else {
12526 			if (br->br_flags & FLAG_A)
12527 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12528 		}
12529 	}
12530 #undef FLAG_A
12531 #undef FLAG_B
12532 }
12533 
12534 static void
12535 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12536 {
12537 #define	FLAG_A	0x01
12538 #define	FLAG_G	0x02
12539 	struct bwn_softc *sc = mac->mac_sc;
12540 	struct ifnet *ifp = sc->sc_ifp;
12541 	struct ieee80211com *ic = ifp->if_l2com;
12542 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12543 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12544 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12545 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12546 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12547 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12548 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12549 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12550 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12551 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12552 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12553 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12554 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12555 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12556 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12557 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12558 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12559 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12560 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12561 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12562 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12563 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12564 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12565 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12566 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12567 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12568 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12569 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12570 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12571 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12572 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12573 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12574 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12575 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12576 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12577 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12578 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12579 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12580 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12581 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12582 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12583 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12584 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12585 	};
12586 	const struct bwn_b206x_rfinit_entry *br;
12587 	unsigned int i;
12588 
12589 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12590 		br = &bwn_b2063_init_tab[i];
12591 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12592 			if (br->br_flags & FLAG_G)
12593 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12594 		} else {
12595 			if (br->br_flags & FLAG_A)
12596 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12597 		}
12598 	}
12599 #undef FLAG_A
12600 #undef FLAG_B
12601 }
12602 
12603 static void
12604 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12605     int count, void *_data)
12606 {
12607 	unsigned int i;
12608 	uint32_t offset, type;
12609 	uint8_t *data = _data;
12610 
12611 	type = BWN_TAB_GETTYPE(typenoffset);
12612 	offset = BWN_TAB_GETOFFSET(typenoffset);
12613 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12614 
12615 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12616 
12617 	for (i = 0; i < count; i++) {
12618 		switch (type) {
12619 		case BWN_TAB_8BIT:
12620 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12621 			data++;
12622 			break;
12623 		case BWN_TAB_16BIT:
12624 			*((uint16_t *)data) = BWN_PHY_READ(mac,
12625 			    BWN_PHY_TABLEDATALO);
12626 			data += 2;
12627 			break;
12628 		case BWN_TAB_32BIT:
12629 			*((uint32_t *)data) = BWN_PHY_READ(mac,
12630 			    BWN_PHY_TABLEDATAHI);
12631 			*((uint32_t *)data) <<= 16;
12632 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
12633 			    BWN_PHY_TABLEDATALO);
12634 			data += 4;
12635 			break;
12636 		default:
12637 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12638 		}
12639 	}
12640 }
12641 
12642 static void
12643 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12644     int count, const void *_data)
12645 {
12646 	uint32_t offset, type, value;
12647 	const uint8_t *data = _data;
12648 	unsigned int i;
12649 
12650 	type = BWN_TAB_GETTYPE(typenoffset);
12651 	offset = BWN_TAB_GETOFFSET(typenoffset);
12652 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12653 
12654 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12655 
12656 	for (i = 0; i < count; i++) {
12657 		switch (type) {
12658 		case BWN_TAB_8BIT:
12659 			value = *data;
12660 			data++;
12661 			KASSERT(!(value & ~0xff),
12662 			    ("%s:%d: fail", __func__, __LINE__));
12663 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12664 			break;
12665 		case BWN_TAB_16BIT:
12666 			value = *((const uint16_t *)data);
12667 			data += 2;
12668 			KASSERT(!(value & ~0xffff),
12669 			    ("%s:%d: fail", __func__, __LINE__));
12670 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12671 			break;
12672 		case BWN_TAB_32BIT:
12673 			value = *((const uint32_t *)data);
12674 			data += 4;
12675 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12676 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12677 			break;
12678 		default:
12679 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12680 		}
12681 	}
12682 }
12683 
12684 static struct bwn_txgain
12685 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12686 {
12687 	struct bwn_txgain tg;
12688 	uint16_t tmp;
12689 
12690 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12691 	if (mac->mac_phy.rev < 2) {
12692 		tmp = BWN_PHY_READ(mac,
12693 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12694 		tg.tg_gm = tmp & 0x0007;
12695 		tg.tg_pga = (tmp & 0x0078) >> 3;
12696 		tg.tg_pad = (tmp & 0x780) >> 7;
12697 		return (tg);
12698 	}
12699 
12700 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12701 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12702 	tg.tg_gm = tmp & 0xff;
12703 	tg.tg_pga = (tmp >> 8) & 0xff;
12704 	return (tg);
12705 }
12706 
12707 static uint8_t
12708 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12709 {
12710 
12711 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12712 }
12713 
12714 static void
12715 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12716 {
12717 	uint16_t pa;
12718 
12719 	if (mac->mac_phy.rev < 2) {
12720 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12721 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12722 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12723 		bwn_phy_lp_set_txgain_override(mac);
12724 		return;
12725 	}
12726 
12727 	pa = bwn_phy_lp_get_pa_gain(mac);
12728 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12729 	    (tg->tg_pga << 8) | tg->tg_gm);
12730 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12731 	    tg->tg_pad | (pa << 6));
12732 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12733 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12734 	    tg->tg_pad | (pa << 8));
12735 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12736 	bwn_phy_lp_set_txgain_override(mac);
12737 }
12738 
12739 static void
12740 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12741 {
12742 
12743 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12744 }
12745 
12746 static void
12747 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12748 {
12749 	uint16_t trsw = (tx << 1) | rx;
12750 
12751 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12752 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12753 }
12754 
12755 static void
12756 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12757 {
12758 	struct bwn_softc *sc = mac->mac_sc;
12759 	struct ifnet *ifp = sc->sc_ifp;
12760 	struct ieee80211com *ic = ifp->if_l2com;
12761 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12762 
12763 	if (mac->mac_phy.rev < 2) {
12764 		trsw = gain & 0x1;
12765 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12766 		ext_lna = (gain & 2) >> 1;
12767 
12768 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12769 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12770 		    0xfbff, ext_lna << 10);
12771 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12772 		    0xf7ff, ext_lna << 11);
12773 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12774 	} else {
12775 		low_gain = gain & 0xffff;
12776 		high_gain = (gain >> 16) & 0xf;
12777 		ext_lna = (gain >> 21) & 0x1;
12778 		trsw = ~(gain >> 20) & 0x1;
12779 
12780 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12781 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12782 		    0xfdff, ext_lna << 9);
12783 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12784 		    0xfbff, ext_lna << 10);
12785 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12786 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12787 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12788 			tmp = (gain >> 2) & 0x3;
12789 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12790 			    0xe7ff, tmp<<11);
12791 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12792 			    tmp << 3);
12793 		}
12794 	}
12795 
12796 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12797 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12798 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12799 	if (mac->mac_phy.rev >= 2) {
12800 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12801 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12802 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12803 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12804 		}
12805 		return;
12806 	}
12807 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12808 }
12809 
12810 static void
12811 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12812 {
12813 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12814 
12815 	if (user)
12816 		plp->plp_crsusr_off = 1;
12817 	else
12818 		plp->plp_crssys_off = 1;
12819 
12820 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12821 }
12822 
12823 static void
12824 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12825 {
12826 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12827 	struct bwn_softc *sc = mac->mac_sc;
12828 	struct ifnet *ifp = sc->sc_ifp;
12829 	struct ieee80211com *ic = ifp->if_l2com;
12830 
12831 	if (user)
12832 		plp->plp_crsusr_off = 0;
12833 	else
12834 		plp->plp_crssys_off = 0;
12835 
12836 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
12837 		return;
12838 
12839 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12840 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12841 	else
12842 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12843 }
12844 
12845 static unsigned int
12846 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12847 {
12848 	struct bwn_softc *sc = mac->mac_sc;
12849 	/* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12850 	static uint8_t sqrt_table[256] = {
12851 		10, 14, 17, 20, 22, 24, 26, 28,
12852 		30, 31, 33, 34, 36, 37, 38, 40,
12853 		41, 42, 43, 44, 45, 46, 47, 48,
12854 		50, 50, 51, 52, 53, 54, 55, 56,
12855 		57, 58, 59, 60, 60, 61, 62, 63,
12856 		64, 64, 65, 66, 67, 67, 68, 69,
12857 		70, 70, 71, 72, 72, 73, 74, 74,
12858 		75, 76, 76, 77, 78, 78, 79, 80,
12859 		80, 81, 81, 82, 83, 83, 84, 84,
12860 		85, 86, 86, 87, 87, 88, 88, 89,
12861 		90, 90, 91, 91, 92, 92, 93, 93,
12862 		94, 94, 95, 95, 96, 96, 97, 97,
12863 		98, 98, 99, 100, 100, 100, 101, 101,
12864 		102, 102, 103, 103, 104, 104, 105, 105,
12865 		106, 106, 107, 107, 108, 108, 109, 109,
12866 		110, 110, 110, 111, 111, 112, 112, 113,
12867 		113, 114, 114, 114, 115, 115, 116, 116,
12868 		117, 117, 117, 118, 118, 119, 119, 120,
12869 		120, 120, 121, 121, 122, 122, 122, 123,
12870 		123, 124, 124, 124, 125, 125, 126, 126,
12871 		126, 127, 127, 128, 128, 128, 129, 129,
12872 		130, 130, 130, 131, 131, 131, 132, 132,
12873 		133, 133, 133, 134, 134, 134, 135, 135,
12874 		136, 136, 136, 137, 137, 137, 138, 138,
12875 		138, 139, 139, 140, 140, 140, 141, 141,
12876 		141, 142, 142, 142, 143, 143, 143, 144,
12877 		144, 144, 145, 145, 145, 146, 146, 146,
12878 		147, 147, 147, 148, 148, 148, 149, 149,
12879 		150, 150, 150, 150, 151, 151, 151, 152,
12880 		152, 152, 153, 153, 153, 154, 154, 154,
12881 		155, 155, 155, 156, 156, 156, 157, 157,
12882 		157, 158, 158, 158, 159, 159, 159, 160
12883 	};
12884 
12885 	if (x == 0)
12886 		return (0);
12887 	if (x >= 256) {
12888 		device_printf(sc->sc_dev,
12889 		    "out of bounds of the square-root table (%d)\n", x);
12890 		return (16);
12891 	}
12892 	return (sqrt_table[x - 1] / 10);
12893 }
12894 
12895 static int
12896 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12897 {
12898 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
12899 	int _t;								\
12900 	_t = _x - 20;							\
12901 	if (_t >= 0) {							\
12902 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12903 	} else {							\
12904 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12905 	}								\
12906 } while (0)
12907 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
12908 	int _t;								\
12909 	_t = _x - 11;							\
12910 	if (_t >= 0)							\
12911 		tmp[3] = (_y << (31 - _x)) / (_z >> _t);		\
12912 	else								\
12913 		tmp[3] = (_y << (31 - _x)) / (_z << -_t);		\
12914 } while (0)
12915 	struct bwn_phy_lp_iq_est ie;
12916 	uint16_t v0, v1;
12917 	int tmp[2], ret;
12918 
12919 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12920 	v0 = v1 >> 8;
12921 	v1 |= 0xff;
12922 
12923 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12924 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12925 
12926 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12927 	if (ret == 0)
12928 		goto done;
12929 
12930 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12931 		ret = 0;
12932 		goto done;
12933 	}
12934 
12935 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12936 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12937 
12938 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12939 	v0 = tmp[0] >> 3;
12940 	v1 = tmp[1] >> 4;
12941 done:
12942 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12943 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12944 	return ret;
12945 #undef CALC_COEFF
12946 #undef CALC_COEFF2
12947 }
12948 
12949 static void
12950 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12951 {
12952 	static const uint16_t noisescale[] = {
12953 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12954 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12955 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12956 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12957 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12958 	};
12959 	static const uint16_t crsgainnft[] = {
12960 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12961 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12962 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12963 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12964 		0x013d,
12965 	};
12966 	static const uint16_t filterctl[] = {
12967 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12968 		0xff53, 0x0127,
12969 	};
12970 	static const uint32_t psctl[] = {
12971 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12972 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12973 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12974 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12975 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12976 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12977 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12978 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12979 	};
12980 	static const uint16_t ofdmcckgain_r0[] = {
12981 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12982 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12983 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12984 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12985 		0x755d,
12986 	};
12987 	static const uint16_t ofdmcckgain_r1[] = {
12988 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12989 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12990 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12991 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12992 		0x755d,
12993 	};
12994 	static const uint16_t gaindelta[] = {
12995 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12996 		0x0000,
12997 	};
12998 	static const uint32_t txpwrctl[] = {
12999 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
13000 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
13001 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
13002 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
13003 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
13004 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
13005 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
13006 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
13007 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
13008 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
13009 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
13010 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
13011 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
13012 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13013 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13014 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13015 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13016 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13017 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13018 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13019 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13020 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13021 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13022 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13023 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13024 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13025 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13026 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13027 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13028 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13029 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13030 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13031 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13032 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13033 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13034 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13035 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13036 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13037 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
13038 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
13039 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
13040 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
13041 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
13042 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
13043 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
13044 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
13045 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
13046 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
13047 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
13048 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
13049 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
13050 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
13051 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
13052 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
13053 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
13054 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
13055 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
13056 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
13057 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
13058 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
13059 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
13060 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
13061 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
13062 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
13063 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13064 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13065 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13066 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13067 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13068 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13069 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13070 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13071 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13072 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13073 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13074 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13075 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13076 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13077 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13078 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13079 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13080 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13081 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13082 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13083 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13084 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13085 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13086 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13087 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13088 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13089 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13090 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13091 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13092 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13093 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13094 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13095 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13096 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13097 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13098 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13099 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13100 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13101 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13102 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13103 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13104 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13105 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13106 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13107 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13108 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13109 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13110 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13111 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13112 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13113 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13114 		0x00000702,
13115 	};
13116 
13117 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13118 
13119 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13120 	    bwn_tab_sigsq_tbl);
13121 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13122 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13123 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13124 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13125 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13126 	    bwn_tab_pllfrac_tbl);
13127 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13128 	    bwn_tabl_iqlocal_tbl);
13129 	if (mac->mac_phy.rev == 0) {
13130 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13131 		    ofdmcckgain_r0);
13132 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13133 		    ofdmcckgain_r0);
13134 	} else {
13135 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13136 		    ofdmcckgain_r1);
13137 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13138 		    ofdmcckgain_r1);
13139 	}
13140 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13141 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13142 }
13143 
13144 static void
13145 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13146 {
13147 	struct siba_dev_softc *sd = mac->mac_sd;
13148 	struct siba_softc *siba = sd->sd_bus;
13149 	int i;
13150 	static const uint16_t noisescale[] = {
13151 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13152 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13153 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13154 		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13155 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13156 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13157 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13158 	};
13159 	static const uint32_t filterctl[] = {
13160 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13161 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13162 	};
13163 	static const uint32_t psctl[] = {
13164 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13165 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13166 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13167 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13168 	};
13169 	static const uint32_t gainidx[] = {
13170 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13171 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13172 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13173 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13174 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13175 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13176 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13177 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13178 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13179 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13180 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13181 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13182 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13183 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13184 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13185 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13186 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13187 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13188 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13189 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13190 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13191 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13192 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13193 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13194 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13195 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13196 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13197 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13198 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13199 		0x0000001a, 0x64ca55ad, 0x0000001a
13200 	};
13201 	static const uint16_t auxgainidx[] = {
13202 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13203 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13204 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13205 		0x0004, 0x0016
13206 	};
13207 	static const uint16_t swctl[] = {
13208 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13209 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13210 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13211 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13212 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13213 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13214 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13215 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13216 	};
13217 	static const uint8_t hf[] = {
13218 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13219 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13220 	};
13221 	static const uint32_t gainval[] = {
13222 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13223 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13224 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13225 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13226 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13227 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13228 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13229 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13230 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13231 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13232 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13233 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13234 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13235 		0x000000f1, 0x00000000, 0x00000000
13236 	};
13237 	static const uint16_t gain[] = {
13238 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13239 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13240 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13241 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13242 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13243 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13250 	};
13251 	static const uint32_t papdeps[] = {
13252 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13253 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13254 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13255 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13256 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13257 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13258 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13259 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13260 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13261 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13262 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13263 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13264 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13265 	};
13266 	static const uint32_t papdmult[] = {
13267 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13268 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13269 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13270 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13271 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13272 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13273 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13274 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13275 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13276 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13277 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13278 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13279 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13280 	};
13281 	static const uint32_t gainidx_a0[] = {
13282 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13283 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13284 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13285 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13286 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13287 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13288 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13289 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13290 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13291 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13292 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13293 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13294 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13295 	};
13296 	static const uint16_t auxgainidx_a0[] = {
13297 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13298 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13299 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13300 		0x0002, 0x0014
13301 	};
13302 	static const uint32_t gainval_a0[] = {
13303 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13304 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13305 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13306 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13307 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13308 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13309 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13310 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13311 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13312 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13313 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13314 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13315 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13316 		0x000000f7, 0x00000000, 0x00000000
13317 	};
13318 	static const uint16_t gain_a0[] = {
13319 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13320 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13321 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13322 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13323 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13324 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13325 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13326 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13327 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13328 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13329 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13330 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13331 	};
13332 
13333 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13334 
13335 	for (i = 0; i < 704; i++)
13336 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13337 
13338 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13339 	    bwn_tab_sigsq_tbl);
13340 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13341 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13342 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13343 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13344 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13345 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13346 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13347 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13348 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13349 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13350 	    bwn_tab_pllfrac_tbl);
13351 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13352 	    bwn_tabl_iqlocal_tbl);
13353 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13354 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13355 
13356 	if ((siba->siba_chipid == 0x4325) && (siba->siba_chiprev == 0)) {
13357 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13358 		    gainidx_a0);
13359 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13360 		    auxgainidx_a0);
13361 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13362 		    gainval_a0);
13363 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13364 	}
13365 }
13366 
13367 static void
13368 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13369 {
13370 	struct siba_dev_softc *sd = mac->mac_sd;
13371 	struct siba_softc *siba = sd->sd_bus;
13372 	struct bwn_softc *sc = mac->mac_sc;
13373 	struct ifnet *ifp = sc->sc_ifp;
13374 	struct ieee80211com *ic = ifp->if_l2com;
13375 	static struct bwn_txgain_entry txgain_r2[] = {
13376 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13377 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13378 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13379 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13380 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13381 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13382 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13383 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13384 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13385 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13386 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13387 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13388 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13389 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13390 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13391 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13392 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13393 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13394 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13395 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13396 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13397 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13398 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13399 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13400 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13401 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13402 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13403 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13404 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13405 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13406 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13407 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13408 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13409 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13410 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13411 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13412 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13413 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13414 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13415 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13416 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13417 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13418 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13419 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13420 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13421 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13422 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13423 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13424 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13425 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13426 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13427 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13428 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13429 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13430 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13431 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13432 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13433 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13434 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13435 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13436 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13437 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13438 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13439 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13440 	};
13441 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13442 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13443 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13444 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13445 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13446 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13447 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13448 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13449 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13450 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13451 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13452 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13453 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13454 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13455 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13456 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13457 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13458 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13459 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13460 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13461 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13462 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13463 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13464 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13465 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13466 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13467 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13468 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13469 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13470 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13471 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13472 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13473 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13474 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13475 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13476 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13477 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13478 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13479 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13480 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13481 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13482 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13483 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13484 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13485 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13486 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13487 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13488 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13489 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13490 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13491 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13492 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13493 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13494 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13495 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13496 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13497 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13498 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13499 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13500 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13501 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13502 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13503 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13504 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13505 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13506 	};
13507 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13508 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13509 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13510 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13511 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13512 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13513 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13514 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13515 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13516 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13517 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13518 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13519 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13520 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13521 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13522 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13523 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13524 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13525 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13526 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13527 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13528 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13529 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13530 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13531 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13532 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13533 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13534 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13535 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13536 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13537 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13538 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13539 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13540 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13541 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13542 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13543 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13544 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13545 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13546 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13547 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13548 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13549 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13550 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13551 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13552 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13553 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13554 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13555 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13556 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13557 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13558 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13559 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13560 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13561 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13562 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13563 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13564 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13565 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13566 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13567 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13568 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13569 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13570 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13571 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13572 	};
13573 	static struct bwn_txgain_entry txgain_r0[] = {
13574 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13575 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13576 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13577 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13578 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13579 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13580 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13581 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13582 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13583 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13584 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13585 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13586 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13587 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13588 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13589 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13590 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13591 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13592 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13593 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13594 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13595 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13596 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13597 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13598 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13599 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13600 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13601 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13602 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13603 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13604 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13605 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13606 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13607 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13608 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13609 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13610 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13611 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13612 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13613 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13614 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13615 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13616 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13617 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13618 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13619 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13620 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13621 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13622 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13623 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13624 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13625 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13626 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13627 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13628 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13629 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13630 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13631 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13632 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13633 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13634 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13635 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13636 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13637 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13638 	};
13639 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13640 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13641 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13642 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13643 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13644 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13645 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13646 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13647 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13648 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13649 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13650 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13651 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13652 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13653 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13654 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13655 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13656 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13657 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13658 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13659 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13660 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13661 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13662 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13663 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13664 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13665 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13666 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13667 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13668 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13669 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13670 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13671 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13672 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13673 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13674 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13675 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13676 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13677 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13678 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13679 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13680 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13681 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13682 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13683 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13684 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13685 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13686 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13687 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13688 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13689 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13690 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13691 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13692 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13693 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13694 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13695 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13696 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13697 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13698 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13699 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13700 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13701 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13702 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13703 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13704 	};
13705 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13706 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13707 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13708 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13709 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13710 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13711 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13712 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13713 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13714 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13715 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13716 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13717 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13718 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13719 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13720 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13721 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13722 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13723 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13724 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13725 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13726 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13727 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13728 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13729 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13730 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13731 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13732 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13733 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13734 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13735 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13736 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13737 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13738 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13739 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13740 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13741 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13742 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13743 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13744 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13745 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13746 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13747 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13748 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13749 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13750 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13751 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13752 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13753 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13754 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13755 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13756 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13757 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13758 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13759 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13760 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13761 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13762 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13763 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13764 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13765 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13766 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13767 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13768 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13769 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13770 	};
13771 	static struct bwn_txgain_entry txgain_r1[] = {
13772 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13773 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13774 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13775 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13776 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13777 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13778 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13779 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13780 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13781 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13782 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13783 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13784 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13785 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13786 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13787 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13788 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13789 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13790 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13791 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13792 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13793 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13794 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13795 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13796 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13797 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13798 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13799 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13800 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13801 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13802 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13803 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13804 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13805 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13806 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13807 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13808 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13809 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13810 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13811 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13812 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13813 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13814 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13815 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13816 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13817 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13818 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13819 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13820 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13821 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13822 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13823 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13824 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13825 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13826 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13827 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13828 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13829 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13830 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13831 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13832 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13833 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13834 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13835 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13836 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13837 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13838 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13839 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13840 		{ 7, 11, 6, 0, 71 }
13841 	};
13842 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13843 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13844 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13845 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13846 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13847 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13848 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13849 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13850 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13851 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13852 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13853 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13854 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13855 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13856 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13857 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13858 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13859 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13860 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13861 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13862 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13863 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13864 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13865 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13866 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13867 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13868 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13869 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13870 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13871 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13872 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13873 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13874 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13875 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13876 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13877 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13878 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13879 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13880 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13881 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13882 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13883 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13884 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13885 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13886 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13887 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13888 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13889 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13890 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13891 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13892 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13893 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13894 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13895 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13896 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13897 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13898 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13899 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13900 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13901 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13902 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13903 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13904 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13905 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13906 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13907 	};
13908 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13909 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13910 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13911 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13912 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13913 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13914 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13915 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13916 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13917 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13918 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13919 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13920 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13921 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13922 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13923 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13924 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13925 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13926 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13927 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13928 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13929 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13930 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13931 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13932 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13933 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13934 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13935 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13936 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13937 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13938 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13939 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13940 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13941 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13942 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13943 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13944 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13945 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13946 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13947 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13948 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13949 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13950 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13951 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13952 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13953 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13954 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13955 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13956 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13957 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13958 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13959 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13960 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13961 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13962 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13963 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13964 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13965 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13966 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13967 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13968 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13969 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13970 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13971 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13972 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13973 	};
13974 
13975 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13976 		if (siba->siba_sprom.bf_hi & BWN_BFH_NOPA)
13977 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13978 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13979 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13980 			    txgain_2ghz_r2);
13981 		else
13982 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13983 			    txgain_5ghz_r2);
13984 		return;
13985 	}
13986 
13987 	if (mac->mac_phy.rev == 0) {
13988 		if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
13989 		    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
13990 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13991 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13992 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13993 			    txgain_2ghz_r0);
13994 		else
13995 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13996 			    txgain_5ghz_r0);
13997 		return;
13998 	}
13999 
14000 	if ((siba->siba_sprom.bf_hi & BWN_BFH_NOPA) ||
14001 	    (siba->siba_sprom.bf_lo & BWN_BFL_HGPA))
14002 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
14003 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
14004 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
14005 	else
14006 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
14007 }
14008 
14009 static void
14010 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
14011 {
14012 	uint32_t offset, type;
14013 
14014 	type = BWN_TAB_GETTYPE(typeoffset);
14015 	offset = BWN_TAB_GETOFFSET(typeoffset);
14016 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14017 
14018 	switch (type) {
14019 	case BWN_TAB_8BIT:
14020 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
14021 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14022 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
14023 		break;
14024 	case BWN_TAB_16BIT:
14025 		KASSERT(!(value & ~0xffff),
14026 		    ("%s:%d: fail", __func__, __LINE__));
14027 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14028 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
14029 		break;
14030 	case BWN_TAB_32BIT:
14031 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14032 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
14033 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
14034 		break;
14035 	default:
14036 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14037 	}
14038 }
14039 
14040 static int
14041 bwn_phy_lp_loopback(struct bwn_mac *mac)
14042 {
14043 	struct bwn_phy_lp_iq_est ie;
14044 	int i, index = -1;
14045 	uint32_t tmp;
14046 
14047 	memset(&ie, 0, sizeof(ie));
14048 
14049 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
14050 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
14051 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
14052 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
14053 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
14054 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
14055 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
14056 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
14057 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
14058 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
14059 	for (i = 0; i < 32; i++) {
14060 		bwn_phy_lp_set_rxgain_idx(mac, i);
14061 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
14062 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
14063 			continue;
14064 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
14065 		if ((tmp > 4000) && (tmp < 10000)) {
14066 			index = i;
14067 			break;
14068 		}
14069 	}
14070 	bwn_phy_lp_ddfs_turnoff(mac);
14071 	return (index);
14072 }
14073 
14074 static void
14075 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
14076 {
14077 
14078 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
14079 }
14080 
14081 static void
14082 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14083     int incr1, int incr2, int scale_idx)
14084 {
14085 
14086 	bwn_phy_lp_ddfs_turnoff(mac);
14087 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14088 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14089 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14090 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14091 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14092 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14093 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14094 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14095 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14096 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14097 }
14098 
14099 static uint8_t
14100 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14101     struct bwn_phy_lp_iq_est *ie)
14102 {
14103 	int i;
14104 
14105 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14106 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14107 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14108 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14109 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14110 
14111 	for (i = 0; i < 500; i++) {
14112 		if (!(BWN_PHY_READ(mac,
14113 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14114 			break;
14115 		DELAY(1000);
14116 	}
14117 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14118 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14119 		return 0;
14120 	}
14121 
14122 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14123 	ie->ie_iqprod <<= 16;
14124 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14125 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14126 	ie->ie_ipwr <<= 16;
14127 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14128 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14129 	ie->ie_qpwr <<= 16;
14130 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14131 
14132 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14133 	return 1;
14134 }
14135 
14136 static uint32_t
14137 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14138 {
14139 	uint32_t offset, type, value;
14140 
14141 	type = BWN_TAB_GETTYPE(typeoffset);
14142 	offset = BWN_TAB_GETOFFSET(typeoffset);
14143 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14144 
14145 	switch (type) {
14146 	case BWN_TAB_8BIT:
14147 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14148 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14149 		break;
14150 	case BWN_TAB_16BIT:
14151 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14152 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14153 		break;
14154 	case BWN_TAB_32BIT:
14155 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14156 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14157 		value <<= 16;
14158 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14159 		break;
14160 	default:
14161 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14162 		value = 0;
14163 	}
14164 
14165 	return (value);
14166 }
14167 
14168 static void
14169 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14170 {
14171 
14172 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14173 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14174 }
14175 
14176 static void
14177 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14178 {
14179 	uint16_t ctl;
14180 
14181 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14182 	ctl |= dac << 7;
14183 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14184 }
14185 
14186 static void
14187 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14188 {
14189 
14190 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14191 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14192 }
14193 
14194 static void
14195 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14196 {
14197 
14198 	if (mac->mac_phy.rev < 2)
14199 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14200 	else {
14201 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14202 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14203 	}
14204 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14205 }
14206 
14207 static uint16_t
14208 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14209 {
14210 
14211 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14212 }
14213 
14214 static uint8_t
14215 bwn_nbits(int32_t val)
14216 {
14217 	uint32_t tmp;
14218 	uint8_t nbits = 0;
14219 
14220 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
14221 		nbits++;
14222 	return (nbits);
14223 }
14224 
14225 static void
14226 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14227     struct bwn_txgain_entry *table)
14228 {
14229 	int i;
14230 
14231 	for (i = offset; i < count; i++)
14232 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14233 }
14234 
14235 static void
14236 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14237     struct bwn_txgain_entry data)
14238 {
14239 
14240 	if (mac->mac_phy.rev >= 2)
14241 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14242 	else
14243 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14244 }
14245 
14246 static void
14247 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14248     struct bwn_txgain_entry te)
14249 {
14250 	struct bwn_softc *sc = mac->mac_sc;
14251 	struct ifnet *ifp = sc->sc_ifp;
14252 	struct ieee80211com *ic = ifp->if_l2com;
14253 	uint32_t tmp;
14254 
14255 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14256 
14257 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14258 	if (mac->mac_phy.rev >= 3) {
14259 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14260 		    (0x10 << 24) : (0x70 << 24));
14261 	} else {
14262 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14263 		    (0x14 << 24) : (0x7f << 24));
14264 	}
14265 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14266 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14267 	    te.te_bbmult << 20 | te.te_dac << 28);
14268 }
14269 
14270 static void
14271 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14272     struct bwn_txgain_entry te)
14273 {
14274 
14275 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14276 
14277 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14278 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14279 	    te.te_dac);
14280 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14281 }
14282 
14283 static void
14284 bwn_sysctl_node(struct bwn_softc *sc)
14285 {
14286 	device_t dev = sc->sc_dev;
14287 	struct bwn_mac *mac;
14288 	struct bwn_stats *stats;
14289 
14290 	/* XXX assume that count of MAC is only 1. */
14291 
14292 	if ((mac = sc->sc_curmac) == NULL)
14293 		return;
14294 	stats = &mac->mac_stats;
14295 
14296 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14297 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14298 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14299 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14300 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14301 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14302 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14303 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14304 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14305 
14306 #ifdef BWN_DEBUG
14307 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14308 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14309 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14310 #endif
14311 }
14312 
14313 static void
14314 bwn_identify(driver_t *driver, device_t parent)
14315 {
14316 
14317 	BUS_ADD_CHILD(parent, 0, "bwn", -1);
14318 }
14319 
14320 static device_method_t bwn_methods[] = {
14321 	/* Device interface */
14322 	DEVMETHOD(device_identify,	bwn_identify),
14323 	DEVMETHOD(device_probe,		bwn_probe),
14324 	DEVMETHOD(device_attach,	bwn_attach),
14325 	DEVMETHOD(device_detach,	bwn_detach),
14326 	DEVMETHOD(device_suspend,	bwn_suspend),
14327 	DEVMETHOD(device_resume,	bwn_resume),
14328 	{ 0,0 }
14329 };
14330 static driver_t bwn_driver = {
14331 	"bwn",
14332 	bwn_methods,
14333 	sizeof(struct bwn_softc)
14334 };
14335 static devclass_t bwn_devclass;
14336 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14337 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14338 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
14339 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
14340 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
14341