]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/bwn/if_bwn.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
72
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
75
76 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
77     "Broadcom driver parameters");
78
79 /*
80  * Tunable & sysctl variables.
81  */
82
83 #ifdef BWN_DEBUG
84 static  int bwn_debug = 0;
85 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
86     "Broadcom debugging printfs");
87 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
88 enum {
89         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
90         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
91         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
92         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
93         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
94         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
95         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
96         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
97         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
98         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
99         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
100         BWN_DEBUG_LED           = 0x00000800,   /* led management */
101         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
102         BWN_DEBUG_LO            = 0x00002000,   /* LO */
103         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
104         BWN_DEBUG_WME           = 0x00008000,   /* WME */
105         BWN_DEBUG_RF            = 0x00010000,   /* RF */
106         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
107         BWN_DEBUG_ANY           = 0xffffffff
108 };
109 #define DPRINTF(sc, m, fmt, ...) do {                   \
110         if (sc->sc_debug & (m))                         \
111                 printf(fmt, __VA_ARGS__);               \
112 } while (0)
113 #else
114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
115 #endif
116
117 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
118 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
119     "uses Bad Frames Preemption");
120 static int      bwn_bluetooth = 1;
121 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
122     "turns on Bluetooth Coexistence");
123 static int      bwn_hwpctl = 0;
124 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
125     "uses H/W power control");
126 static int      bwn_msi_disable = 0;            /* MSI disabled  */
127 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
128 static int      bwn_usedma = 1;
129 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
130     "uses DMA");
131 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
132 static int      bwn_wme = 1;
133 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
134     "uses WME support");
135
136 static int      bwn_attach_pre(struct bwn_softc *);
137 static int      bwn_attach_post(struct bwn_softc *);
138 static void     bwn_sprom_bugfixes(device_t);
139 static void     bwn_init(void *);
140 static int      bwn_init_locked(struct bwn_softc *);
141 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t);
142 static void     bwn_start(struct ifnet *);
143 static int      bwn_attach_core(struct bwn_mac *);
144 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
145 static int      bwn_phy_getinfo(struct bwn_mac *, int);
146 static int      bwn_chiptest(struct bwn_mac *);
147 static int      bwn_setup_channels(struct bwn_mac *, int, int);
148 static int      bwn_phy_g_attach(struct bwn_mac *);
149 static void     bwn_phy_g_detach(struct bwn_mac *);
150 static void     bwn_phy_g_init_pre(struct bwn_mac *);
151 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
152 static int      bwn_phy_g_init(struct bwn_mac *);
153 static void     bwn_phy_g_exit(struct bwn_mac *);
154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
155 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
156                     uint16_t);
157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
158 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
159                     uint16_t);
160 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
161 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
162 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
164 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
165 static int      bwn_phy_g_im(struct bwn_mac *, int);
166 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
167 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
168 static void     bwn_phy_g_task_15s(struct bwn_mac *);
169 static void     bwn_phy_g_task_60s(struct bwn_mac *);
170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
171 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
173 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
174                     uint16_t);
175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
176 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
177                     uint32_t);
178 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
179                     uint16_t);
180 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
181                     const struct bwn_channelinfo *, int);
182 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
183                     const struct ieee80211_bpf_params *);
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 void     bwn_wme_clear(struct bwn_softc *);
189 static void     bwn_wme_load(struct bwn_mac *);
190 static void     bwn_wme_loadparams(struct bwn_mac *,
191                     const struct wmeParams *, uint16_t);
192 static void     bwn_scan_start(struct ieee80211com *);
193 static void     bwn_scan_end(struct ieee80211com *);
194 static void     bwn_set_channel(struct ieee80211com *);
195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
196                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
197                     const uint8_t [IEEE80211_ADDR_LEN],
198                     const uint8_t [IEEE80211_ADDR_LEN]);
199 static void     bwn_vap_delete(struct ieee80211vap *);
200 static void     bwn_stop(struct bwn_softc *, int);
201 static void     bwn_stop_locked(struct bwn_softc *, int);
202 static int      bwn_core_init(struct bwn_mac *);
203 static void     bwn_core_start(struct bwn_mac *);
204 static void     bwn_core_exit(struct bwn_mac *);
205 static void     bwn_bt_disable(struct bwn_mac *);
206 static int      bwn_chip_init(struct bwn_mac *);
207 static uint64_t bwn_hf_read(struct bwn_mac *);
208 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
209 static void     bwn_set_txretry(struct bwn_mac *, int, int);
210 static void     bwn_rate_init(struct bwn_mac *);
211 static void     bwn_set_phytxctl(struct bwn_mac *);
212 static void     bwn_spu_setdelay(struct bwn_mac *, int);
213 static void     bwn_bt_enable(struct bwn_mac *);
214 static void     bwn_set_macaddr(struct bwn_mac *);
215 static void     bwn_crypt_init(struct bwn_mac *);
216 static void     bwn_chip_exit(struct bwn_mac *);
217 static int      bwn_fw_fillinfo(struct bwn_mac *);
218 static int      bwn_fw_loaducode(struct bwn_mac *);
219 static int      bwn_gpio_init(struct bwn_mac *);
220 static int      bwn_fw_loadinitvals(struct bwn_mac *);
221 static int      bwn_phy_init(struct bwn_mac *);
222 static void     bwn_set_txantenna(struct bwn_mac *, int);
223 static void     bwn_set_opmode(struct bwn_mac *);
224 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
225 static uint8_t  bwn_plcp_getcck(const uint8_t);
226 static uint8_t  bwn_plcp_getofdm(const uint8_t);
227 static void     bwn_pio_init(struct bwn_mac *);
228 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
229 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
230                     int);
231 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
232                     struct bwn_pio_rxqueue *, int);
233 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
234 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
235                     uint16_t);
236 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
237 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
238 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
239 static void     bwn_pio_handle_txeof(struct bwn_mac *,
240                     const struct bwn_txstatus *);
241 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
242 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
243 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
244                     uint16_t);
245 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
246                     uint32_t);
247 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
248                     struct mbuf *);
249 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
250 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
251                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
252 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
253                     uint16_t, uint32_t);
254 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
255                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
256 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
257                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
258 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
259                     uint16_t, struct bwn_pio_txpkt **);
260 static void     bwn_dma_init(struct bwn_mac *);
261 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
262 static int      bwn_dma_mask2type(uint64_t);
263 static uint64_t bwn_dma_mask(struct bwn_mac *);
264 static uint16_t bwn_dma_base(int, int);
265 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
266 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
267                     int, struct bwn_dmadesc_generic **,
268                     struct bwn_dmadesc_meta **);
269 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
270                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
271                     int, int);
272 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
273 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
274 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
275 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
276 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
277 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
278                     int, struct bwn_dmadesc_generic **,
279                     struct bwn_dmadesc_meta **);
280 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
281                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
282                     int, int);
283 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
284 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
285 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
286 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
287 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
288 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
289 static void     bwn_dma_setup(struct bwn_dma_ring *);
290 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
291 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
292 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
293 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
294 static void     bwn_dma_rx(struct bwn_dma_ring *);
295 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
296 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
297                     struct bwn_dmadesc_meta *);
298 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
299 static int      bwn_dma_gettype(struct bwn_mac *);
300 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
301 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
302 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
303 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
304 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
305                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
306                     int);
307 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
308                     bus_size_t, int);
309 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
310 static void     bwn_dma_handle_txeof(struct bwn_mac *,
311                     const struct bwn_txstatus *);
312 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
313                     struct mbuf *);
314 static int      bwn_dma_getslot(struct bwn_dma_ring *);
315 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
316                     uint8_t);
317 static int      bwn_dma_attach(struct bwn_mac *);
318 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
319                     int, int, int);
320 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
321                     const struct bwn_txstatus *, uint16_t, int *);
322 static void     bwn_dma_free(struct bwn_mac *);
323 static void     bwn_phy_g_init_sub(struct bwn_mac *);
324 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
325 static void     bwn_phy_init_b5(struct bwn_mac *);
326 static void     bwn_phy_init_b6(struct bwn_mac *);
327 static void     bwn_phy_init_a(struct bwn_mac *);
328 static void     bwn_loopback_calcgain(struct bwn_mac *);
329 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
330 static void     bwn_lo_g_init(struct bwn_mac *);
331 static void     bwn_lo_g_adjust(struct bwn_mac *);
332 static void     bwn_lo_get_powervector(struct bwn_mac *);
333 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
334                     const struct bwn_bbatt *, const struct bwn_rfatt *);
335 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
336 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
337 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
338 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
339                     const struct bwn_bbatt *, const struct bwn_rfatt *,
340                     uint8_t);
341 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
342 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
343 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
344 static void     bwn_wa_init(struct bwn_mac *);
345 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
346                     uint16_t);
347 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
348 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
349                     uint32_t);
350 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
351                     uint16_t);
352 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
353 static void     bwn_mac_suspend(struct bwn_mac *);
354 static void     bwn_mac_enable(struct bwn_mac *);
355 static void     bwn_psctl(struct bwn_mac *, uint32_t);
356 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
357 static void     bwn_nrssi_offset(struct bwn_mac *);
358 static void     bwn_nrssi_threshold(struct bwn_mac *);
359 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
360 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
361                     int16_t);
362 static void     bwn_set_original_gains(struct bwn_mac *);
363 static void     bwn_hwpctl_early_init(struct bwn_mac *);
364 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
365 static uint16_t bwn_phy_g_chan2freq(uint8_t);
366 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
367 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
368                     const char *, struct bwn_fwfile *);
369 static void     bwn_release_firmware(struct bwn_mac *);
370 static void     bwn_do_release_fw(struct bwn_fwfile *);
371 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
372 static int      bwn_fwinitvals_write(struct bwn_mac *,
373                     const struct bwn_fwinitvals *, size_t, size_t);
374 static int      bwn_switch_channel(struct bwn_mac *, int);
375 static uint16_t bwn_ant2phy(int);
376 static void     bwn_mac_write_bssid(struct bwn_mac *);
377 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
378                     const uint8_t *);
379 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
380                     const uint8_t *, size_t, const uint8_t *);
381 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
382                     const uint8_t *);
383 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
384                     const uint8_t *);
385 static void     bwn_phy_exit(struct bwn_mac *);
386 static void     bwn_core_stop(struct bwn_mac *);
387 static int      bwn_switch_band(struct bwn_softc *,
388                     struct ieee80211_channel *);
389 static void     bwn_phy_reset(struct bwn_mac *);
390 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
391 static void     bwn_set_pretbtt(struct bwn_mac *);
392 static int      bwn_intr(void *);
393 static void     bwn_intrtask(void *, int);
394 static void     bwn_restart(struct bwn_mac *, const char *);
395 static void     bwn_intr_ucode_debug(struct bwn_mac *);
396 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
397 static void     bwn_intr_atim_end(struct bwn_mac *);
398 static void     bwn_intr_beacon(struct bwn_mac *);
399 static void     bwn_intr_pmq(struct bwn_mac *);
400 static void     bwn_intr_noise(struct bwn_mac *);
401 static void     bwn_intr_txeof(struct bwn_mac *);
402 static void     bwn_hwreset(void *, int);
403 static void     bwn_handle_fwpanic(struct bwn_mac *);
404 static void     bwn_load_beacon0(struct bwn_mac *);
405 static void     bwn_load_beacon1(struct bwn_mac *);
406 static uint32_t bwn_jssi_read(struct bwn_mac *);
407 static void     bwn_noise_gensample(struct bwn_mac *);
408 static void     bwn_handle_txeof(struct bwn_mac *,
409                     const struct bwn_txstatus *);
410 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
411 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
412 static void     bwn_start_locked(struct ifnet *);
413 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
414                     struct mbuf *);
415 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
416 static int      bwn_set_txhdr(struct bwn_mac *,
417                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
418                     uint16_t);
419 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
420                     const uint8_t);
421 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
422 static uint8_t  bwn_get_fbrate(uint8_t);
423 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
424 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
425 static void     bwn_phy_lock(struct bwn_mac *);
426 static void     bwn_phy_unlock(struct bwn_mac *);
427 static void     bwn_rf_lock(struct bwn_mac *);
428 static void     bwn_rf_unlock(struct bwn_mac *);
429 static void     bwn_txpwr(void *, int);
430 static void     bwn_tasks(void *);
431 static void     bwn_task_15s(struct bwn_mac *);
432 static void     bwn_task_30s(struct bwn_mac *);
433 static void     bwn_task_60s(struct bwn_mac *);
434 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
435                     uint8_t);
436 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
437 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
438                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
439                     int, int);
440 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
441 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
442 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
443 static void     bwn_watchdog(void *);
444 static void     bwn_dma_stop(struct bwn_mac *);
445 static void     bwn_pio_stop(struct bwn_mac *);
446 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
447 static void     bwn_led_attach(struct bwn_mac *);
448 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
449 static void     bwn_led_event(struct bwn_mac *, int);
450 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
451 static void     bwn_led_blink_next(void *);
452 static void     bwn_led_blink_end(void *);
453 static void     bwn_rfswitch(void *);
454 static void     bwn_rf_turnon(struct bwn_mac *);
455 static void     bwn_rf_turnoff(struct bwn_mac *);
456 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
457 static int      bwn_phy_lp_init(struct bwn_mac *);
458 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
459 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
460 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
461                     uint16_t);
462 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
463 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
464 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
465 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
466 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
467 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
468 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
469 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
470 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
471 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
472 static void     bwn_phy_lp_calib(struct bwn_mac *);
473 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
474 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
475 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
476 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
477 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
478 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
479 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
480 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
481 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
482 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
483 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
484 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
485 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
486 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
487 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
488 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
489 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
490 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
491 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
492 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
493 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
494 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
495                     const void *);
496 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
497 static struct bwn_txgain
498                 bwn_phy_lp_get_txgain(struct bwn_mac *);
499 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
500 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
501 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
502 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
503 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
504 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
505 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
506 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
507 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
508 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
509 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
510 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
511 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
512 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
513 static int      bwn_phy_lp_loopback(struct bwn_mac *);
514 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
515 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
516                     int);
517 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
518                     struct bwn_phy_lp_iq_est *);
519 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
520 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
521 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
522 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
523 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
524 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
525 static uint8_t  bwn_nbits(int32_t);
526 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
527                     struct bwn_txgain_entry *);
528 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
529                     struct bwn_txgain_entry);
530 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
531                     struct bwn_txgain_entry);
532 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
533                     struct bwn_txgain_entry);
534 static void     bwn_sysctl_node(struct bwn_softc *);
535
536 static struct resource_spec bwn_res_spec_legacy[] = {
537         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
538         { -1,                   0,              0 }
539 };
540
541 static struct resource_spec bwn_res_spec_msi[] = {
542         { SYS_RES_IRQ,          1,              RF_ACTIVE },
543         { -1,                   0,              0 }
544 };
545
546 static const struct bwn_channelinfo bwn_chantable_bg = {
547         .channels = {
548                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
549                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
550                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
551                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
552                 { 2472, 13, 30 }, { 2484, 14, 30 } },
553         .nchannels = 14
554 };
555
556 static const struct bwn_channelinfo bwn_chantable_a = {
557         .channels = {
558                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
559                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
560                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
561                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
562                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
563                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
564                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
565                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
566                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
567                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
568                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
569                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
570                 { 6080, 216, 30 } },
571         .nchannels = 37
572 };
573
574 static const struct bwn_channelinfo bwn_chantable_n = {
575         .channels = {
576                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
577                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
578                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
579                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
580                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
581                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
582                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
583                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
584                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
585                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
586                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
587                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
588                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
589                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
590                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
591                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
592                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
593                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
594                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
595                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
596                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
597                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
598                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
599                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
600                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
601                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
602                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
603                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
604                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
605                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
606                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
607                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
608                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
609                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
610                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
611                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
612                 { 6130, 226, 30 }, { 6140, 228, 30 } },
613         .nchannels = 110
614 };
615
616 static const uint8_t bwn_b2063_chantable_data[33][12] = {
617         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
622         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
623         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
624         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
628         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
629         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
630         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
631         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
633         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
634         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
635         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
636         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
638         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
642         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
649         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
650 };
651
652 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
653         { 1, 2412, bwn_b2063_chantable_data[0] },
654         { 2, 2417, bwn_b2063_chantable_data[0] },
655         { 3, 2422, bwn_b2063_chantable_data[0] },
656         { 4, 2427, bwn_b2063_chantable_data[1] },
657         { 5, 2432, bwn_b2063_chantable_data[1] },
658         { 6, 2437, bwn_b2063_chantable_data[1] },
659         { 7, 2442, bwn_b2063_chantable_data[1] },
660         { 8, 2447, bwn_b2063_chantable_data[1] },
661         { 9, 2452, bwn_b2063_chantable_data[2] },
662         { 10, 2457, bwn_b2063_chantable_data[2] },
663         { 11, 2462, bwn_b2063_chantable_data[3] },
664         { 12, 2467, bwn_b2063_chantable_data[3] },
665         { 13, 2472, bwn_b2063_chantable_data[3] },
666         { 14, 2484, bwn_b2063_chantable_data[4] },
667         { 34, 5170, bwn_b2063_chantable_data[5] },
668         { 36, 5180, bwn_b2063_chantable_data[6] },
669         { 38, 5190, bwn_b2063_chantable_data[7] },
670         { 40, 5200, bwn_b2063_chantable_data[8] },
671         { 42, 5210, bwn_b2063_chantable_data[9] },
672         { 44, 5220, bwn_b2063_chantable_data[10] },
673         { 46, 5230, bwn_b2063_chantable_data[11] },
674         { 48, 5240, bwn_b2063_chantable_data[12] },
675         { 52, 5260, bwn_b2063_chantable_data[13] },
676         { 56, 5280, bwn_b2063_chantable_data[14] },
677         { 60, 5300, bwn_b2063_chantable_data[14] },
678         { 64, 5320, bwn_b2063_chantable_data[15] },
679         { 100, 5500, bwn_b2063_chantable_data[16] },
680         { 104, 5520, bwn_b2063_chantable_data[17] },
681         { 108, 5540, bwn_b2063_chantable_data[18] },
682         { 112, 5560, bwn_b2063_chantable_data[19] },
683         { 116, 5580, bwn_b2063_chantable_data[20] },
684         { 120, 5600, bwn_b2063_chantable_data[21] },
685         { 124, 5620, bwn_b2063_chantable_data[21] },
686         { 128, 5640, bwn_b2063_chantable_data[22] },
687         { 132, 5660, bwn_b2063_chantable_data[22] },
688         { 136, 5680, bwn_b2063_chantable_data[22] },
689         { 140, 5700, bwn_b2063_chantable_data[23] },
690         { 149, 5745, bwn_b2063_chantable_data[23] },
691         { 153, 5765, bwn_b2063_chantable_data[23] },
692         { 157, 5785, bwn_b2063_chantable_data[23] },
693         { 161, 5805, bwn_b2063_chantable_data[23] },
694         { 165, 5825, bwn_b2063_chantable_data[23] },
695         { 184, 4920, bwn_b2063_chantable_data[24] },
696         { 188, 4940, bwn_b2063_chantable_data[25] },
697         { 192, 4960, bwn_b2063_chantable_data[26] },
698         { 196, 4980, bwn_b2063_chantable_data[27] },
699         { 200, 5000, bwn_b2063_chantable_data[28] },
700         { 204, 5020, bwn_b2063_chantable_data[29] },
701         { 208, 5040, bwn_b2063_chantable_data[30] },
702         { 212, 5060, bwn_b2063_chantable_data[31] },
703         { 216, 5080, bwn_b2063_chantable_data[32] }
704 };
705
706 static const uint8_t bwn_b2062_chantable_data[22][12] = {
707         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
708         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
720         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
728         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
729 };
730
731 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
732         { 1, 2412, bwn_b2062_chantable_data[0] },
733         { 2, 2417, bwn_b2062_chantable_data[0] },
734         { 3, 2422, bwn_b2062_chantable_data[0] },
735         { 4, 2427, bwn_b2062_chantable_data[0] },
736         { 5, 2432, bwn_b2062_chantable_data[0] },
737         { 6, 2437, bwn_b2062_chantable_data[0] },
738         { 7, 2442, bwn_b2062_chantable_data[0] },
739         { 8, 2447, bwn_b2062_chantable_data[0] },
740         { 9, 2452, bwn_b2062_chantable_data[0] },
741         { 10, 2457, bwn_b2062_chantable_data[0] },
742         { 11, 2462, bwn_b2062_chantable_data[0] },
743         { 12, 2467, bwn_b2062_chantable_data[0] },
744         { 13, 2472, bwn_b2062_chantable_data[0] },
745         { 14, 2484, bwn_b2062_chantable_data[0] },
746         { 34, 5170, bwn_b2062_chantable_data[1] },
747         { 38, 5190, bwn_b2062_chantable_data[2] },
748         { 42, 5210, bwn_b2062_chantable_data[2] },
749         { 46, 5230, bwn_b2062_chantable_data[3] },
750         { 36, 5180, bwn_b2062_chantable_data[4] },
751         { 40, 5200, bwn_b2062_chantable_data[5] },
752         { 44, 5220, bwn_b2062_chantable_data[6] },
753         { 48, 5240, bwn_b2062_chantable_data[3] },
754         { 52, 5260, bwn_b2062_chantable_data[3] },
755         { 56, 5280, bwn_b2062_chantable_data[3] },
756         { 60, 5300, bwn_b2062_chantable_data[7] },
757         { 64, 5320, bwn_b2062_chantable_data[8] },
758         { 100, 5500, bwn_b2062_chantable_data[9] },
759         { 104, 5520, bwn_b2062_chantable_data[10] },
760         { 108, 5540, bwn_b2062_chantable_data[10] },
761         { 112, 5560, bwn_b2062_chantable_data[10] },
762         { 116, 5580, bwn_b2062_chantable_data[11] },
763         { 120, 5600, bwn_b2062_chantable_data[12] },
764         { 124, 5620, bwn_b2062_chantable_data[12] },
765         { 128, 5640, bwn_b2062_chantable_data[12] },
766         { 132, 5660, bwn_b2062_chantable_data[12] },
767         { 136, 5680, bwn_b2062_chantable_data[12] },
768         { 140, 5700, bwn_b2062_chantable_data[12] },
769         { 149, 5745, bwn_b2062_chantable_data[12] },
770         { 153, 5765, bwn_b2062_chantable_data[12] },
771         { 157, 5785, bwn_b2062_chantable_data[12] },
772         { 161, 5805, bwn_b2062_chantable_data[12] },
773         { 165, 5825, bwn_b2062_chantable_data[12] },
774         { 184, 4920, bwn_b2062_chantable_data[13] },
775         { 188, 4940, bwn_b2062_chantable_data[14] },
776         { 192, 4960, bwn_b2062_chantable_data[15] },
777         { 196, 4980, bwn_b2062_chantable_data[16] },
778         { 200, 5000, bwn_b2062_chantable_data[17] },
779         { 204, 5020, bwn_b2062_chantable_data[18] },
780         { 208, 5040, bwn_b2062_chantable_data[19] },
781         { 212, 5060, bwn_b2062_chantable_data[20] },
782         { 216, 5080, bwn_b2062_chantable_data[21] }
783 };
784
785 /* for LP PHY */
786 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
787         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
788         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
789         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
790         { 13, -66, 13 }, { 14, -66, 13 },
791 };
792
793 /* for LP PHY */
794 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
795         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
796         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
797         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
798         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
799         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
800         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
801         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
802         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
803         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
804         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
805         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
806         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
807         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
808 };
809
810 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
811
812 static const uint8_t bwn_tab_sigsq_tbl[] = {
813         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
814         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
816         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
817         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
818         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
819 };
820
821 static const uint8_t bwn_tab_pllfrac_tbl[] = {
822         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
823         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
824 };
825
826 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
827         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
828         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
829         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
830         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
831         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
832         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
837         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839 };
840
841 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
842 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
843 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
844 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
845 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
846 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
847
848 #define VENDOR_LED_ACT(vendor)                          \
849 {                                                       \
850         .vid = PCI_VENDOR_##vendor,                     \
851         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
852 }
853
854 static const struct {
855         uint16_t        vid;
856         uint8_t         led_act[BWN_LED_MAX];
857 } bwn_vendor_led_act[] = {
858         VENDOR_LED_ACT(COMPAQ),
859         VENDOR_LED_ACT(ASUSTEK)
860 };
861
862 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
863         { BWN_VENDOR_LED_ACT_DEFAULT };
864
865 #undef VENDOR_LED_ACT
866
867 static const struct {
868         int             on_dur;
869         int             off_dur;
870 } bwn_led_duration[109] = {
871         [0]     = { 400, 100 },
872         [2]     = { 150, 75 },
873         [4]     = { 90, 45 },
874         [11]    = { 66, 34 },
875         [12]    = { 53, 26 },
876         [18]    = { 42, 21 },
877         [22]    = { 35, 17 },
878         [24]    = { 32, 16 },
879         [36]    = { 21, 10 },
880         [48]    = { 16, 8 },
881         [72]    = { 11, 5 },
882         [96]    = { 9, 4 },
883         [108]   = { 7, 3 }
884 };
885
886 static const uint16_t bwn_wme_shm_offsets[] = {
887         [0] = BWN_WME_BESTEFFORT,
888         [1] = BWN_WME_BACKGROUND,
889         [2] = BWN_WME_VOICE,
890         [3] = BWN_WME_VIDEO,
891 };
892
893 static const struct siba_devid bwn_devs[] = {
894         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
895         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
896         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
897         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
898         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
899         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
900         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
901         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
902         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
903 };
904
905 static int
906 bwn_probe(device_t dev)
907 {
908         int i;
909
910         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
911                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
912                     siba_get_device(dev) == bwn_devs[i].sd_device &&
913                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
914                         return (BUS_PROBE_DEFAULT);
915         }
916
917         return (ENXIO);
918 }
919
920 static int
921 bwn_attach(device_t dev)
922 {
923         struct bwn_mac *mac;
924         struct bwn_softc *sc = device_get_softc(dev);
925         int error, i, msic, reg;
926
927         sc->sc_dev = dev;
928 #ifdef BWN_DEBUG
929         sc->sc_debug = bwn_debug;
930 #endif
931
932         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933                 error = bwn_attach_pre(sc);
934                 if (error != 0)
935                         return (error);
936                 bwn_sprom_bugfixes(dev);
937                 sc->sc_flags |= BWN_FLAG_ATTACHED;
938         }
939
940         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
941                 if (siba_get_pci_device(dev) != 0x4313 &&
942                     siba_get_pci_device(dev) != 0x431a &&
943                     siba_get_pci_device(dev) != 0x4321) {
944                         device_printf(sc->sc_dev,
945                             "skip 802.11 cores\n");
946                         return (ENODEV);
947                 }
948         }
949
950         mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
951             M_NOWAIT | M_ZERO);
952         if (mac == NULL)
953                 return (ENOMEM);
954         mac->mac_sc = sc;
955         mac->mac_status = BWN_MAC_STATUS_UNINIT;
956         if (bwn_bfp != 0)
957                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
958
959         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
960         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
961         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
962
963         error = bwn_attach_core(mac);
964         if (error)
965                 goto fail0;
966         bwn_led_attach(mac);
967
968         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
969             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
970             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
971             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
972             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
973             mac->mac_phy.rf_rev);
974         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
975                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
976                     mac->mac_method.dma.dmatype);
977         else
978                 device_printf(sc->sc_dev, "PIO\n");
979
980         /*
981          * setup PCI resources and interrupt.
982          */
983         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
984                 msic = pci_msi_count(dev);
985                 if (bootverbose)
986                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
987         } else
988                 msic = 0;
989
990         mac->mac_intr_spec = bwn_res_spec_legacy;
991         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
992                 if (pci_alloc_msi(dev, &msic) == 0) {
993                         device_printf(sc->sc_dev,
994                             "Using %d MSI messages\n", msic);
995                         mac->mac_intr_spec = bwn_res_spec_msi;
996                         mac->mac_msi = 1;
997                 }
998         }
999
1000         error = bus_alloc_resources(dev, mac->mac_intr_spec,
1001             mac->mac_res_irq);
1002         if (error) {
1003                 device_printf(sc->sc_dev,
1004                     "couldn't allocate IRQ resources (%d)\n", error);
1005                 goto fail1;
1006         }
1007
1008         if (mac->mac_msi == 0)
1009                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1010                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1011                     &mac->mac_intrhand[0]);
1012         else {
1013                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1014                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1015                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1016                             &mac->mac_intrhand[i]);
1017                         if (error != 0) {
1018                                 device_printf(sc->sc_dev,
1019                                     "couldn't setup interrupt (%d)\n", error);
1020                                 break;
1021                         }
1022                 }
1023         }
1024
1025         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1026
1027         /*
1028          * calls attach-post routine
1029          */
1030         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1031                 bwn_attach_post(sc);
1032
1033         return (0);
1034 fail1:
1035         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1036                 pci_release_msi(dev);
1037 fail0:
1038         free(mac, M_DEVBUF);
1039         return (error);
1040 }
1041
1042 static int
1043 bwn_is_valid_ether_addr(uint8_t *addr)
1044 {
1045         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1046
1047         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1048                 return (FALSE);
1049
1050         return (TRUE);
1051 }
1052
1053 static int
1054 bwn_attach_post(struct bwn_softc *sc)
1055 {
1056         struct ieee80211com *ic;
1057         struct ifnet *ifp = sc->sc_ifp;
1058
1059         ic = ifp->if_l2com;
1060         ic->ic_ifp = ifp;
1061         /* XXX not right but it's not used anywhere important */
1062         ic->ic_phytype = IEEE80211_T_OFDM;
1063         ic->ic_opmode = IEEE80211_M_STA;
1064         ic->ic_caps =
1065                   IEEE80211_C_STA               /* station mode supported */
1066                 | IEEE80211_C_MONITOR           /* monitor mode */
1067                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1068                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1069                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1070                 | IEEE80211_C_WME               /* WME/WMM supported */
1071                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1072                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1073                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1074                 ;
1075
1076         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1077
1078         /* call MI attach routine. */
1079         ieee80211_ifattach(ic,
1080             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1081             siba_sprom_get_mac_80211a(sc->sc_dev) :
1082             siba_sprom_get_mac_80211bg(sc->sc_dev));
1083
1084         ic->ic_headroom = sizeof(struct bwn_txhdr);
1085
1086         /* override default methods */
1087         ic->ic_raw_xmit = bwn_raw_xmit;
1088         ic->ic_updateslot = bwn_updateslot;
1089         ic->ic_update_promisc = bwn_update_promisc;
1090         ic->ic_wme.wme_update = bwn_wme_update;
1091
1092         ic->ic_scan_start = bwn_scan_start;
1093         ic->ic_scan_end = bwn_scan_end;
1094         ic->ic_set_channel = bwn_set_channel;
1095
1096         ic->ic_vap_create = bwn_vap_create;
1097         ic->ic_vap_delete = bwn_vap_delete;
1098
1099         ieee80211_radiotap_attach(ic,
1100             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1101             BWN_TX_RADIOTAP_PRESENT,
1102             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1103             BWN_RX_RADIOTAP_PRESENT);
1104
1105         bwn_sysctl_node(sc);
1106
1107         if (bootverbose)
1108                 ieee80211_announce(ic);
1109         return (0);
1110 }
1111
1112 static void
1113 bwn_phy_detach(struct bwn_mac *mac)
1114 {
1115
1116         if (mac->mac_phy.detach != NULL)
1117                 mac->mac_phy.detach(mac);
1118 }
1119
1120 static int
1121 bwn_detach(device_t dev)
1122 {
1123         struct bwn_softc *sc = device_get_softc(dev);
1124         struct bwn_mac *mac = sc->sc_curmac;
1125         struct ifnet *ifp = sc->sc_ifp;
1126         struct ieee80211com *ic = ifp->if_l2com;
1127         int i;
1128
1129         sc->sc_flags |= BWN_FLAG_INVALID;
1130
1131         if (device_is_attached(sc->sc_dev)) {
1132                 bwn_stop(sc, 1);
1133                 bwn_dma_free(mac);
1134                 callout_drain(&sc->sc_led_blink_ch);
1135                 callout_drain(&sc->sc_rfswitch_ch);
1136                 callout_drain(&sc->sc_task_ch);
1137                 callout_drain(&sc->sc_watchdog_ch);
1138                 bwn_phy_detach(mac);
1139                 if (ifp != NULL) {
1140                         ieee80211_draintask(ic, &mac->mac_hwreset);
1141                         ieee80211_draintask(ic, &mac->mac_txpower);
1142                         ieee80211_ifdetach(ic);
1143                         if_free(ifp);
1144                 }
1145         }
1146         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1147         taskqueue_free(sc->sc_tq);
1148
1149         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1150                 if (mac->mac_intrhand[i] != NULL) {
1151                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1152                             mac->mac_intrhand[i]);
1153                         mac->mac_intrhand[i] = NULL;
1154                 }
1155         }
1156         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1157         if (mac->mac_msi != 0)
1158                 pci_release_msi(dev);
1159
1160         BWN_LOCK_DESTROY(sc);
1161         return (0);
1162 }
1163
1164 static int
1165 bwn_attach_pre(struct bwn_softc *sc)
1166 {
1167         struct ifnet *ifp;
1168         int error = 0;
1169
1170         BWN_LOCK_INIT(sc);
1171         TAILQ_INIT(&sc->sc_maclist);
1172         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1173         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1174         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1175
1176         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1177                 taskqueue_thread_enqueue, &sc->sc_tq);
1178         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1179                 "%s taskq", device_get_nameunit(sc->sc_dev));
1180
1181         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1182         if (ifp == NULL) {
1183                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1184                 error = ENOSPC;
1185                 goto fail;
1186         }
1187
1188         /* set these up early for if_printf use */
1189         if_initname(ifp, device_get_name(sc->sc_dev),
1190             device_get_unit(sc->sc_dev));
1191
1192         ifp->if_softc = sc;
1193         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1194         ifp->if_init = bwn_init;
1195         ifp->if_ioctl = bwn_ioctl;
1196         ifp->if_start = bwn_start;
1197         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1198         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1199         IFQ_SET_READY(&ifp->if_snd);
1200
1201         return (0);
1202
1203 fail:   BWN_LOCK_DESTROY(sc);
1204         return (error);
1205 }
1206
1207 static void
1208 bwn_sprom_bugfixes(device_t dev)
1209 {
1210 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1211         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1212          (siba_get_pci_device(dev) == _device) &&                       \
1213          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1214          (siba_get_pci_subdevice(dev) == _subdevice))
1215
1216         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1217             siba_get_pci_subdevice(dev) == 0x4e &&
1218             siba_get_pci_revid(dev) > 0x40)
1219                 siba_sprom_set_bf_lo(dev,
1220                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1221         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1222             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1223                 siba_sprom_set_bf_lo(dev,
1224                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1225         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1226                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1227                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1228                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1229                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1230                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1231                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1232                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1233                         siba_sprom_set_bf_lo(dev,
1234                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1235         }
1236 #undef  BWN_ISDEV
1237 }
1238
1239 static int
1240 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1241 {
1242 #define IS_RUNNING(ifp) \
1243         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1244         struct bwn_softc *sc = ifp->if_softc;
1245         struct ieee80211com *ic = ifp->if_l2com;
1246         struct ifreq *ifr = (struct ifreq *)data;
1247         int error = 0, startall;
1248
1249         switch (cmd) {
1250         case SIOCSIFFLAGS:
1251                 startall = 0;
1252                 if (IS_RUNNING(ifp)) {
1253                         bwn_update_promisc(ifp);
1254                 } else if (ifp->if_flags & IFF_UP) {
1255                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1256                                 bwn_init(sc);
1257                                 startall = 1;
1258                         }
1259                 } else
1260                         bwn_stop(sc, 1);
1261                 if (startall)
1262                         ieee80211_start_all(ic);
1263                 break;
1264         case SIOCGIFMEDIA:
1265                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1266                 break;
1267         case SIOCGIFADDR:
1268                 error = ether_ioctl(ifp, cmd, data);
1269                 break;
1270         default:
1271                 error = EINVAL;
1272                 break;
1273         }
1274         return (error);
1275 }
1276
1277 static void
1278 bwn_start(struct ifnet *ifp)
1279 {
1280         struct bwn_softc *sc = ifp->if_softc;
1281
1282         BWN_LOCK(sc);
1283         bwn_start_locked(ifp);
1284         BWN_UNLOCK(sc);
1285 }
1286
1287 static void
1288 bwn_start_locked(struct ifnet *ifp)
1289 {
1290         struct bwn_softc *sc = ifp->if_softc;
1291         struct bwn_mac *mac = sc->sc_curmac;
1292         struct ieee80211_frame *wh;
1293         struct ieee80211_node *ni;
1294         struct ieee80211_key *k;
1295         struct mbuf *m;
1296
1297         BWN_ASSERT_LOCKED(sc);
1298
1299         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1300             mac->mac_status < BWN_MAC_STATUS_STARTED)
1301                 return;
1302
1303         for (;;) {
1304                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1305                 if (m == NULL)
1306                         break;
1307
1308                 if (bwn_tx_isfull(sc, m))
1309                         break;
1310                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1311                 if (ni == NULL) {
1312                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1313                         m_freem(m);
1314                         ifp->if_oerrors++;
1315                         continue;
1316                 }
1317                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1318                 wh = mtod(m, struct ieee80211_frame *);
1319                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1320                         k = ieee80211_crypto_encap(ni, m);
1321                         if (k == NULL) {
1322                                 ieee80211_free_node(ni);
1323                                 m_freem(m);
1324                                 ifp->if_oerrors++;
1325                                 continue;
1326                         }
1327                 }
1328                 wh = NULL;      /* Catch any invalid use */
1329
1330                 if (bwn_tx_start(sc, ni, m) != 0) {
1331                         if (ni != NULL)
1332                                 ieee80211_free_node(ni);
1333                         ifp->if_oerrors++;
1334                         continue;
1335                 }
1336
1337                 sc->sc_watchdog_timer = 5;
1338         }
1339 }
1340
1341 static int
1342 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1343 {
1344         struct bwn_dma_ring *dr;
1345         struct bwn_mac *mac = sc->sc_curmac;
1346         struct bwn_pio_txqueue *tq;
1347         struct ifnet *ifp = sc->sc_ifp;
1348         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1349
1350         BWN_ASSERT_LOCKED(sc);
1351
1352         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1353                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1354                 if (dr->dr_stop == 1 ||
1355                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1356                         dr->dr_stop = 1;
1357                         goto full;
1358                 }
1359         } else {
1360                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1361                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1362                     pktlen > (tq->tq_size - tq->tq_used)) {
1363                         tq->tq_stop = 1;
1364                         goto full;
1365                 }
1366         }
1367         return (0);
1368 full:
1369         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1370         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1371         return (1);
1372 }
1373
1374 static int
1375 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1376 {
1377         struct bwn_mac *mac = sc->sc_curmac;
1378         int error;
1379
1380         BWN_ASSERT_LOCKED(sc);
1381
1382         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1383                 m_freem(m);
1384                 return (ENXIO);
1385         }
1386
1387         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1388             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1389         if (error) {
1390                 m_freem(m);
1391                 return (error);
1392         }
1393         return (0);
1394 }
1395
1396 static int
1397 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1398 {
1399         struct bwn_pio_txpkt *tp;
1400         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1401         struct bwn_softc *sc = mac->mac_sc;
1402         struct bwn_txhdr txhdr;
1403         struct mbuf *m_new;
1404         uint32_t ctl32;
1405         int error;
1406         uint16_t ctl16;
1407
1408         BWN_ASSERT_LOCKED(sc);
1409
1410         /* XXX TODO send packets after DTIM */
1411
1412         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1413         tp = TAILQ_FIRST(&tq->tq_pktlist);
1414         tp->tp_ni = ni;
1415         tp->tp_m = m;
1416
1417         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1418         if (error) {
1419                 device_printf(sc->sc_dev, "tx fail\n");
1420                 return (error);
1421         }
1422
1423         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1424         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1425         tq->tq_free--;
1426
1427         if (siba_get_revid(sc->sc_dev) >= 8) {
1428                 /*
1429                  * XXX please removes m_defrag(9)
1430                  */
1431                 m_new = m_defrag(m, M_NOWAIT);
1432                 if (m_new == NULL) {
1433                         device_printf(sc->sc_dev,
1434                             "%s: can't defrag TX buffer\n",
1435                             __func__);
1436                         return (ENOBUFS);
1437                 }
1438                 if (m_new->m_next != NULL)
1439                         device_printf(sc->sc_dev,
1440                             "TODO: fragmented packets for PIO\n");
1441                 tp->tp_m = m_new;
1442
1443                 /* send HEADER */
1444                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1445                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1446                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1447                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1448                 /* send BODY */
1449                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1450                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1451                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1452                     ctl32 | BWN_PIO8_TXCTL_EOF);
1453         } else {
1454                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1455                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1456                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1457                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1458                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1459                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1460                     ctl16 | BWN_PIO_TXCTL_EOF);
1461         }
1462
1463         return (0);
1464 }
1465
1466 static struct bwn_pio_txqueue *
1467 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1468 {
1469
1470         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1471                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1472
1473         switch (prio) {
1474         case 0:
1475                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1476         case 1:
1477                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1478         case 2:
1479                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1480         case 3:
1481                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1482         }
1483         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1484         return (NULL);
1485 }
1486
1487 static int
1488 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1489 {
1490 #define BWN_GET_TXHDRCACHE(slot)                                        \
1491         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1492         struct bwn_dma *dma = &mac->mac_method.dma;
1493         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1494         struct bwn_dmadesc_generic *desc;
1495         struct bwn_dmadesc_meta *mt;
1496         struct bwn_softc *sc = mac->mac_sc;
1497         struct ifnet *ifp = sc->sc_ifp;
1498         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1499         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1500
1501         BWN_ASSERT_LOCKED(sc);
1502         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1503
1504         /* XXX send after DTIM */
1505
1506         slot = bwn_dma_getslot(dr);
1507         dr->getdesc(dr, slot, &desc, &mt);
1508         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1509             ("%s:%d: fail", __func__, __LINE__));
1510
1511         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1512             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1513             BWN_DMA_COOKIE(dr, slot));
1514         if (error)
1515                 goto fail;
1516         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1517             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1518             &mt->mt_paddr, BUS_DMA_NOWAIT);
1519         if (error) {
1520                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1521                     __func__, error);
1522                 goto fail;
1523         }
1524         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1525             BUS_DMASYNC_PREWRITE);
1526         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1527         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1528             BUS_DMASYNC_PREWRITE);
1529
1530         slot = bwn_dma_getslot(dr);
1531         dr->getdesc(dr, slot, &desc, &mt);
1532         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1533             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1534         mt->mt_m = m;
1535         mt->mt_ni = ni;
1536
1537         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1538             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1539         if (error && error != EFBIG) {
1540                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1541                     __func__, error);
1542                 goto fail;
1543         }
1544         if (error) {    /* error == EFBIG */
1545                 struct mbuf *m_new;
1546
1547                 m_new = m_defrag(m, M_NOWAIT);
1548                 if (m_new == NULL) {
1549                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1550                             __func__);
1551                         error = ENOBUFS;
1552                         goto fail;
1553                 } else {
1554                         m = m_new;
1555                 }
1556
1557                 mt->mt_m = m;
1558                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1559                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1560                 if (error) {
1561                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1562                             __func__, error);
1563                         goto fail;
1564                 }
1565         }
1566         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1567         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1568         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1569             BUS_DMASYNC_PREWRITE);
1570
1571         /* XXX send after DTIM */
1572
1573         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1574         return (0);
1575 fail:
1576         dr->dr_curslot = backup[0];
1577         dr->dr_usedslot = backup[1];
1578         return (error);
1579 #undef BWN_GET_TXHDRCACHE
1580 }
1581
1582 static void
1583 bwn_watchdog(void *arg)
1584 {
1585         struct bwn_softc *sc = arg;
1586         struct ifnet *ifp = sc->sc_ifp;
1587
1588         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1589                 if_printf(ifp, "device timeout\n");
1590                 ifp->if_oerrors++;
1591         }
1592         callout_schedule(&sc->sc_watchdog_ch, hz);
1593 }
1594
1595 static int
1596 bwn_attach_core(struct bwn_mac *mac)
1597 {
1598         struct bwn_softc *sc = mac->mac_sc;
1599         int error, have_bg = 0, have_a = 0;
1600         uint32_t high;
1601
1602         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1603             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1604
1605         siba_powerup(sc->sc_dev, 0);
1606
1607         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1608         bwn_reset_core(mac,
1609             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1610         error = bwn_phy_getinfo(mac, high);
1611         if (error)
1612                 goto fail;
1613
1614         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1615         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1616         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1617             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1618             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1619                 have_a = have_bg = 0;
1620                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1621                         have_a = 1;
1622                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1623                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1624                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1625                         have_bg = 1;
1626                 else
1627                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1628                             mac->mac_phy.type));
1629         }
1630         /* XXX turns off PHY A because it's not supported */
1631         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1632             mac->mac_phy.type != BWN_PHYTYPE_N) {
1633                 have_a = 0;
1634                 have_bg = 1;
1635         }
1636
1637         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1638                 mac->mac_phy.attach = bwn_phy_g_attach;
1639                 mac->mac_phy.detach = bwn_phy_g_detach;
1640                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1641                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1642                 mac->mac_phy.init = bwn_phy_g_init;
1643                 mac->mac_phy.exit = bwn_phy_g_exit;
1644                 mac->mac_phy.phy_read = bwn_phy_g_read;
1645                 mac->mac_phy.phy_write = bwn_phy_g_write;
1646                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1647                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1648                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1649                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1650                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1651                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1652                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1653                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1654                 mac->mac_phy.set_im = bwn_phy_g_im;
1655                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1656                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1657                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1658                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1659         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1660                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1661                 mac->mac_phy.init = bwn_phy_lp_init;
1662                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1663                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1664                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1665                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1666                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1667                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1668                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1669                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1670                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1671                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1672                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1673         } else {
1674                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1675                     mac->mac_phy.type);
1676                 error = ENXIO;
1677                 goto fail;
1678         }
1679
1680         mac->mac_phy.gmode = have_bg;
1681         if (mac->mac_phy.attach != NULL) {
1682                 error = mac->mac_phy.attach(mac);
1683                 if (error) {
1684                         device_printf(sc->sc_dev, "failed\n");
1685                         goto fail;
1686                 }
1687         }
1688
1689         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1690
1691         error = bwn_chiptest(mac);
1692         if (error)
1693                 goto fail;
1694         error = bwn_setup_channels(mac, have_bg, have_a);
1695         if (error) {
1696                 device_printf(sc->sc_dev, "failed to setup channels\n");
1697                 goto fail;
1698         }
1699
1700         if (sc->sc_curmac == NULL)
1701                 sc->sc_curmac = mac;
1702
1703         error = bwn_dma_attach(mac);
1704         if (error != 0) {
1705                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1706                 goto fail;
1707         }
1708
1709         mac->mac_phy.switch_analog(mac, 0);
1710
1711         siba_dev_down(sc->sc_dev, 0);
1712 fail:
1713         siba_powerdown(sc->sc_dev);
1714         return (error);
1715 }
1716
1717 static void
1718 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1719 {
1720         struct bwn_softc *sc = mac->mac_sc;
1721         uint32_t low, ctl;
1722
1723         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1724
1725         siba_dev_up(sc->sc_dev, flags);
1726         DELAY(2000);
1727
1728         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1729             ~BWN_TGSLOW_PHYRESET;
1730         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1731         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1732         DELAY(1000);
1733         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1734         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1735         DELAY(1000);
1736
1737         if (mac->mac_phy.switch_analog != NULL)
1738                 mac->mac_phy.switch_analog(mac, 1);
1739
1740         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1741         if (flags & BWN_TGSLOW_SUPPORT_G)
1742                 ctl |= BWN_MACCTL_GMODE;
1743         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1744 }
1745
1746 static int
1747 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1748 {
1749         struct bwn_phy *phy = &mac->mac_phy;
1750         struct bwn_softc *sc = mac->mac_sc;
1751         uint32_t tmp;
1752
1753         /* PHY */
1754         tmp = BWN_READ_2(mac, BWN_PHYVER);
1755         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1756         phy->rf_on = 1;
1757         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1758         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1759         phy->rev = (tmp & BWN_PHYVER_VERSION);
1760         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1761             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1762                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1763             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1764             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1765             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1766                 goto unsupphy;
1767
1768         /* RADIO */
1769         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1770                 if (siba_get_chiprev(sc->sc_dev) == 0)
1771                         tmp = 0x3205017f;
1772                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1773                         tmp = 0x4205017f;
1774                 else
1775                         tmp = 0x5205017f;
1776         } else {
1777                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1778                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1779                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1780                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1781         }
1782         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1783         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1784         phy->rf_manuf = (tmp & 0x00000fff);
1785         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1786                 goto unsupradio;
1787         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1788              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1789             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1790             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1791             (phy->type == BWN_PHYTYPE_N &&
1792              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1793             (phy->type == BWN_PHYTYPE_LP &&
1794              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1795                 goto unsupradio;
1796
1797         return (0);
1798 unsupphy:
1799         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1800             "analog %#x)\n",
1801             phy->type, phy->rev, phy->analog);
1802         return (ENXIO);
1803 unsupradio:
1804         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1805             "rev %#x)\n",
1806             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1807         return (ENXIO);
1808 }
1809
1810 static int
1811 bwn_chiptest(struct bwn_mac *mac)
1812 {
1813 #define TESTVAL0        0x55aaaa55
1814 #define TESTVAL1        0xaa5555aa
1815         struct bwn_softc *sc = mac->mac_sc;
1816         uint32_t v, backup;
1817
1818         BWN_LOCK(sc);
1819
1820         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1821
1822         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1823         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1824                 goto error;
1825         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1826         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1827                 goto error;
1828
1829         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1830
1831         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1832             (siba_get_revid(sc->sc_dev) <= 10)) {
1833                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1834                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1835                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1836                         goto error;
1837                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1838                         goto error;
1839         }
1840         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1841
1842         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1843         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1844                 goto error;
1845
1846         BWN_UNLOCK(sc);
1847         return (0);
1848 error:
1849         BWN_UNLOCK(sc);
1850         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1851         return (ENODEV);
1852 }
1853
1854 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1855 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1856
1857 static int
1858 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1859 {
1860         struct bwn_softc *sc = mac->mac_sc;
1861         struct ifnet *ifp = sc->sc_ifp;
1862         struct ieee80211com *ic = ifp->if_l2com;
1863
1864         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1865         ic->ic_nchans = 0;
1866
1867         if (have_bg)
1868                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1869                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1870         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1871                 if (have_a)
1872                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1873                             &ic->ic_nchans, &bwn_chantable_n,
1874                             IEEE80211_CHAN_HTA);
1875         } else {
1876                 if (have_a)
1877                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1878                             &ic->ic_nchans, &bwn_chantable_a,
1879                             IEEE80211_CHAN_A);
1880         }
1881
1882         mac->mac_phy.supports_2ghz = have_bg;
1883         mac->mac_phy.supports_5ghz = have_a;
1884
1885         return (ic->ic_nchans == 0 ? ENXIO : 0);
1886 }
1887
1888 static uint32_t
1889 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1890 {
1891         uint32_t ret;
1892
1893         BWN_ASSERT_LOCKED(mac->mac_sc);
1894
1895         if (way == BWN_SHARED) {
1896                 KASSERT((offset & 0x0001) == 0,
1897                     ("%s:%d warn", __func__, __LINE__));
1898                 if (offset & 0x0003) {
1899                         bwn_shm_ctlword(mac, way, offset >> 2);
1900                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1901                         ret <<= 16;
1902                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1903                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1904                         goto out;
1905                 }
1906                 offset >>= 2;
1907         }
1908         bwn_shm_ctlword(mac, way, offset);
1909         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1910 out:
1911         return (ret);
1912 }
1913
1914 static uint16_t
1915 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1916 {
1917         uint16_t ret;
1918
1919         BWN_ASSERT_LOCKED(mac->mac_sc);
1920
1921         if (way == BWN_SHARED) {
1922                 KASSERT((offset & 0x0001) == 0,
1923                     ("%s:%d warn", __func__, __LINE__));
1924                 if (offset & 0x0003) {
1925                         bwn_shm_ctlword(mac, way, offset >> 2);
1926                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1927                         goto out;
1928                 }
1929                 offset >>= 2;
1930         }
1931         bwn_shm_ctlword(mac, way, offset);
1932         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1933 out:
1934
1935         return (ret);
1936 }
1937
1938 static void
1939 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1940     uint16_t offset)
1941 {
1942         uint32_t control;
1943
1944         control = way;
1945         control <<= 16;
1946         control |= offset;
1947         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1948 }
1949
1950 static void
1951 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1952     uint32_t value)
1953 {
1954         BWN_ASSERT_LOCKED(mac->mac_sc);
1955
1956         if (way == BWN_SHARED) {
1957                 KASSERT((offset & 0x0001) == 0,
1958                     ("%s:%d warn", __func__, __LINE__));
1959                 if (offset & 0x0003) {
1960                         bwn_shm_ctlword(mac, way, offset >> 2);
1961                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1962                                     (value >> 16) & 0xffff);
1963                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1964                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1965                         return;
1966                 }
1967                 offset >>= 2;
1968         }
1969         bwn_shm_ctlword(mac, way, offset);
1970         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1971 }
1972
1973 static void
1974 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1975     uint16_t value)
1976 {
1977         BWN_ASSERT_LOCKED(mac->mac_sc);
1978
1979         if (way == BWN_SHARED) {
1980                 KASSERT((offset & 0x0001) == 0,
1981                     ("%s:%d warn", __func__, __LINE__));
1982                 if (offset & 0x0003) {
1983                         bwn_shm_ctlword(mac, way, offset >> 2);
1984                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1985                         return;
1986                 }
1987                 offset >>= 2;
1988         }
1989         bwn_shm_ctlword(mac, way, offset);
1990         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1991 }
1992
1993 static void
1994 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1995     int txpow)
1996 {
1997
1998         c->ic_freq = freq;
1999         c->ic_flags = flags;
2000         c->ic_ieee = ieee;
2001         c->ic_minpower = 0;
2002         c->ic_maxpower = 2 * txpow;
2003         c->ic_maxregpower = txpow;
2004 }
2005
2006 static void
2007 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2008     const struct bwn_channelinfo *ci, int flags)
2009 {
2010         struct ieee80211_channel *c;
2011         int i;
2012
2013         c = &chans[*nchans];
2014
2015         for (i = 0; i < ci->nchannels; i++) {
2016                 const struct bwn_channel *hc;
2017
2018                 hc = &ci->channels[i];
2019                 if (*nchans >= maxchans)
2020                         break;
2021                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2022                 c++, (*nchans)++;
2023                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2024                         /* g channel have a separate b-only entry */
2025                         if (*nchans >= maxchans)
2026                                 break;
2027                         c[0] = c[-1];
2028                         c[-1].ic_flags = IEEE80211_CHAN_B;
2029                         c++, (*nchans)++;
2030                 }
2031                 if (flags == IEEE80211_CHAN_HTG) {
2032                         /* HT g channel have a separate g-only entry */
2033                         if (*nchans >= maxchans)
2034                                 break;
2035                         c[-1].ic_flags = IEEE80211_CHAN_G;
2036                         c[0] = c[-1];
2037                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2038                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2039                         c++, (*nchans)++;
2040                 }
2041                 if (flags == IEEE80211_CHAN_HTA) {
2042                         /* HT a channel have a separate a-only entry */
2043                         if (*nchans >= maxchans)
2044                                 break;
2045                         c[-1].ic_flags = IEEE80211_CHAN_A;
2046                         c[0] = c[-1];
2047                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2048                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2049                         c++, (*nchans)++;
2050                 }
2051         }
2052 }
2053
2054 static int
2055 bwn_phy_g_attach(struct bwn_mac *mac)
2056 {
2057         struct bwn_softc *sc = mac->mac_sc;
2058         struct bwn_phy *phy = &mac->mac_phy;
2059         struct bwn_phy_g *pg = &phy->phy_g;
2060         unsigned int i;
2061         int16_t pab0, pab1, pab2;
2062         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2063         int8_t bg;
2064
2065         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2066         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2067         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2068         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2069
2070         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2071                 device_printf(sc->sc_dev, "not supported anymore\n");
2072
2073         pg->pg_flags = 0;
2074         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2075             pab2 == -1) {
2076                 pg->pg_idletssi = 52;
2077                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2078                 return (0);
2079         }
2080
2081         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2082         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2083         if (pg->pg_tssi2dbm == NULL) {
2084                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2085                 return (ENOMEM);
2086         }
2087         for (i = 0; i < 64; i++) {
2088                 int32_t m1, m2, f, q, delta;
2089                 int8_t j = 0;
2090
2091                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2092                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2093                 f = 256;
2094
2095                 do {
2096                         if (j > 15) {
2097                                 device_printf(sc->sc_dev,
2098                                     "failed to generate tssi2dBm\n");
2099                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2100                                 return (ENOMEM);
2101                         }
2102                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2103                             f, 2048);
2104                         delta = abs(q - f);
2105                         f = q;
2106                         j++;
2107                 } while (delta >= 2);
2108
2109                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2110                     128);
2111         }
2112
2113         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2114         return (0);
2115 }
2116
2117 static void
2118 bwn_phy_g_detach(struct bwn_mac *mac)
2119 {
2120         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2121
2122         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2123                 free(pg->pg_tssi2dbm, M_DEVBUF);
2124                 pg->pg_tssi2dbm = NULL;
2125         }
2126         pg->pg_flags = 0;
2127 }
2128
2129 static void
2130 bwn_phy_g_init_pre(struct bwn_mac *mac)
2131 {
2132         struct bwn_phy *phy = &mac->mac_phy;
2133         struct bwn_phy_g *pg = &phy->phy_g;
2134         void *tssi2dbm;
2135         int idletssi;
2136         unsigned int i;
2137
2138         tssi2dbm = pg->pg_tssi2dbm;
2139         idletssi = pg->pg_idletssi;
2140
2141         memset(pg, 0, sizeof(*pg));
2142
2143         pg->pg_tssi2dbm = tssi2dbm;
2144         pg->pg_idletssi = idletssi;
2145
2146         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2147
2148         for (i = 0; i < N(pg->pg_nrssi); i++)
2149                 pg->pg_nrssi[i] = -1000;
2150         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2151                 pg->pg_nrssi_lt[i] = i;
2152         pg->pg_lofcal = 0xffff;
2153         pg->pg_initval = 0xffff;
2154         pg->pg_immode = BWN_IMMODE_NONE;
2155         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2156         pg->pg_avgtssi = 0xff;
2157
2158         pg->pg_loctl.tx_bias = 0xff;
2159         TAILQ_INIT(&pg->pg_loctl.calib_list);
2160 }
2161
2162 static int
2163 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2164 {
2165         struct bwn_phy *phy = &mac->mac_phy;
2166         struct bwn_phy_g *pg = &phy->phy_g;
2167         struct bwn_softc *sc = mac->mac_sc;
2168         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2169         static const struct bwn_rfatt rfatt0[] = {
2170                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2171                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2172                 { 3, 1 }, { 4, 1 }
2173         };
2174         static const struct bwn_rfatt rfatt1[] = {
2175                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2176                 { 14, 1 }
2177         };
2178         static const struct bwn_rfatt rfatt2[] = {
2179                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2180                 { 9, 1 }
2181         };
2182         static const struct bwn_bbatt bbatt_0[] = {
2183                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2184         };
2185
2186         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2187
2188         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2189                 pg->pg_bbatt.att = 0;
2190         else
2191                 pg->pg_bbatt.att = 2;
2192
2193         /* prepare Radio Attenuation */
2194         pg->pg_rfatt.padmix = 0;
2195
2196         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2197             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2198                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2199                         pg->pg_rfatt.att = 2;
2200                         goto done;
2201                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2202                         pg->pg_rfatt.att = 3;
2203                         goto done;
2204                 }
2205         }
2206
2207         if (phy->type == BWN_PHYTYPE_A) {
2208                 pg->pg_rfatt.att = 0x60;
2209                 goto done;
2210         }
2211
2212         switch (phy->rf_ver) {
2213         case 0x2050:
2214                 switch (phy->rf_rev) {
2215                 case 0:
2216                         pg->pg_rfatt.att = 5;
2217                         goto done;
2218                 case 1:
2219                         if (phy->type == BWN_PHYTYPE_G) {
2220                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2221                                     SIBA_BOARDVENDOR_BCM &&
2222                                     siba_get_pci_subdevice(sc->sc_dev) ==
2223                                     SIBA_BOARD_BCM4309G &&
2224                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2225                                         pg->pg_rfatt.att = 3;
2226                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2227                                     SIBA_BOARDVENDOR_BCM &&
2228                                     siba_get_pci_subdevice(sc->sc_dev) ==
2229                                     SIBA_BOARD_BU4306)
2230                                         pg->pg_rfatt.att = 3;
2231                                 else
2232                                         pg->pg_rfatt.att = 1;
2233                         } else {
2234                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2235                                     SIBA_BOARDVENDOR_BCM &&
2236                                     siba_get_pci_subdevice(sc->sc_dev) ==
2237                                     SIBA_BOARD_BCM4309G &&
2238                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2239                                         pg->pg_rfatt.att = 7;
2240                                 else
2241                                         pg->pg_rfatt.att = 6;
2242                         }
2243                         goto done;
2244                 case 2:
2245                         if (phy->type == BWN_PHYTYPE_G) {
2246                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2247                                     SIBA_BOARDVENDOR_BCM &&
2248                                     siba_get_pci_subdevice(sc->sc_dev) ==
2249                                     SIBA_BOARD_BCM4309G &&
2250                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2251                                         pg->pg_rfatt.att = 3;
2252                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2253                                     SIBA_BOARDVENDOR_BCM &&
2254                                     siba_get_pci_subdevice(sc->sc_dev) ==
2255                                     SIBA_BOARD_BU4306)
2256                                         pg->pg_rfatt.att = 5;
2257                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2258                                         pg->pg_rfatt.att = 4;
2259                                 else
2260                                         pg->pg_rfatt.att = 3;
2261                         } else
2262                                 pg->pg_rfatt.att = 6;
2263                         goto done;
2264                 case 3:
2265                         pg->pg_rfatt.att = 5;
2266                         goto done;
2267                 case 4:
2268                 case 5:
2269                         pg->pg_rfatt.att = 1;
2270                         goto done;
2271                 case 6:
2272                 case 7:
2273                         pg->pg_rfatt.att = 5;
2274                         goto done;
2275                 case 8:
2276                         pg->pg_rfatt.att = 0xa;
2277                         pg->pg_rfatt.padmix = 1;
2278                         goto done;
2279                 case 9:
2280                 default:
2281                         pg->pg_rfatt.att = 5;
2282                         goto done;
2283                 }
2284                 break;
2285         case 0x2053:
2286                 switch (phy->rf_rev) {
2287                 case 1:
2288                         pg->pg_rfatt.att = 6;
2289                         goto done;
2290                 }
2291                 break;
2292         }
2293         pg->pg_rfatt.att = 5;
2294 done:
2295         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2296
2297         if (!bwn_has_hwpctl(mac)) {
2298                 lo->rfatt.array = rfatt0;
2299                 lo->rfatt.len = N(rfatt0);
2300                 lo->rfatt.min = 0;
2301                 lo->rfatt.max = 9;
2302                 goto genbbatt;
2303         }
2304         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2305                 lo->rfatt.array = rfatt1;
2306                 lo->rfatt.len = N(rfatt1);
2307                 lo->rfatt.min = 0;
2308                 lo->rfatt.max = 14;
2309                 goto genbbatt;
2310         }
2311         lo->rfatt.array = rfatt2;
2312         lo->rfatt.len = N(rfatt2);
2313         lo->rfatt.min = 0;
2314         lo->rfatt.max = 9;
2315 genbbatt:
2316         lo->bbatt.array = bbatt_0;
2317         lo->bbatt.len = N(bbatt_0);
2318         lo->bbatt.min = 0;
2319         lo->bbatt.max = 8;
2320
2321         BWN_READ_4(mac, BWN_MACCTL);
2322         if (phy->rev == 1) {
2323                 phy->gmode = 0;
2324                 bwn_reset_core(mac, 0);
2325                 bwn_phy_g_init_sub(mac);
2326                 phy->gmode = 1;
2327                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2328         }
2329         return (0);
2330 }
2331
2332 static uint16_t
2333 bwn_phy_g_txctl(struct bwn_mac *mac)
2334 {
2335         struct bwn_phy *phy = &mac->mac_phy;
2336
2337         if (phy->rf_ver != 0x2050)
2338                 return (0);
2339         if (phy->rf_rev == 1)
2340                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2341         if (phy->rf_rev < 6)
2342                 return (BWN_TXCTL_PA2DB);
2343         if (phy->rf_rev == 8)
2344                 return (BWN_TXCTL_TXMIX);
2345         return (0);
2346 }
2347
2348 static int
2349 bwn_phy_g_init(struct bwn_mac *mac)
2350 {
2351
2352         bwn_phy_g_init_sub(mac);
2353         return (0);
2354 }
2355
2356 static void
2357 bwn_phy_g_exit(struct bwn_mac *mac)
2358 {
2359         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2360         struct bwn_lo_calib *cal, *tmp;
2361
2362         if (lo == NULL)
2363                 return;
2364         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2365                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2366                 free(cal, M_DEVBUF);
2367         }
2368 }
2369
2370 static uint16_t
2371 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2372 {
2373
2374         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2375         return (BWN_READ_2(mac, BWN_PHYDATA));
2376 }
2377
2378 static void
2379 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2380 {
2381
2382         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2383         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2384 }
2385
2386 static uint16_t
2387 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2388 {
2389
2390         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2391         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2392         return (BWN_READ_2(mac, BWN_RFDATALO));
2393 }
2394
2395 static void
2396 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2397 {
2398
2399         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2400         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2401         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2402 }
2403
2404 static int
2405 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2406 {
2407
2408         return (mac->mac_phy.rev >= 6);
2409 }
2410
2411 static void
2412 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2413 {
2414         struct bwn_phy *phy = &mac->mac_phy;
2415         struct bwn_phy_g *pg = &phy->phy_g;
2416         unsigned int channel;
2417         uint16_t rfover, rfoverval;
2418
2419         if (on) {
2420                 if (phy->rf_on)
2421                         return;
2422
2423                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2424                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2425                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2426                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2427                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2428                             pg->pg_radioctx_over);
2429                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2430                             pg->pg_radioctx_overval);
2431                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2432                 }
2433                 channel = phy->chan;
2434                 bwn_phy_g_switch_chan(mac, 6, 1);
2435                 bwn_phy_g_switch_chan(mac, channel, 0);
2436                 return;
2437         }
2438
2439         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2440         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2441         pg->pg_radioctx_over = rfover;
2442         pg->pg_radioctx_overval = rfoverval;
2443         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2444         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2445         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2446 }
2447
2448 static int
2449 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2450 {
2451
2452         if ((newchan < 1) || (newchan > 14))
2453                 return (EINVAL);
2454         bwn_phy_g_switch_chan(mac, newchan, 0);
2455
2456         return (0);
2457 }
2458
2459 static uint32_t
2460 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2461 {
2462
2463         return (1);
2464 }
2465
2466 static void
2467 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2468 {
2469         struct bwn_phy *phy = &mac->mac_phy;
2470         uint64_t hf;
2471         int autodiv = 0;
2472         uint16_t tmp;
2473
2474         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2475                 autodiv = 1;
2476
2477         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2478         bwn_hf_write(mac, hf);
2479
2480         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2481             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2482             ((autodiv ? BWN_ANTAUTO1 : antenna)
2483                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2484
2485         if (autodiv) {
2486                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2487                 if (antenna == BWN_ANTAUTO1)
2488                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2489                 else
2490                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2491                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2492         }
2493         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2494         if (autodiv)
2495                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2496         else
2497                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2498         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2499         if (phy->rev >= 2) {
2500                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2501                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2502                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2503                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2504                     0x15);
2505                 if (phy->rev == 2)
2506                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2507                 else
2508                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2509                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2510                             8);
2511         }
2512         if (phy->rev >= 6)
2513                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2514
2515         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2516         bwn_hf_write(mac, hf);
2517 }
2518
2519 static int
2520 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2521 {
2522         struct bwn_phy *phy = &mac->mac_phy;
2523         struct bwn_phy_g *pg = &phy->phy_g;
2524
2525         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2526         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2527
2528         if (phy->rev == 0 || !phy->gmode)
2529                 return (ENODEV);
2530
2531         pg->pg_aci_wlan_automatic = 0;
2532         return (0);
2533 }
2534
2535 static int
2536 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2537 {
2538         struct bwn_phy *phy = &mac->mac_phy;
2539         struct bwn_phy_g *pg = &phy->phy_g;
2540         struct bwn_softc *sc = mac->mac_sc;
2541         unsigned int tssi;
2542         int cck, ofdm;
2543         int power;
2544         int rfatt, bbatt;
2545         unsigned int max;
2546
2547         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2548
2549         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2550         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2551         if (cck < 0 && ofdm < 0) {
2552                 if (ignore_tssi == 0)
2553                         return (BWN_TXPWR_RES_DONE);
2554                 cck = 0;
2555                 ofdm = 0;
2556         }
2557         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2558         if (pg->pg_avgtssi != 0xff)
2559                 tssi = (tssi + pg->pg_avgtssi) / 2;
2560         pg->pg_avgtssi = tssi;
2561         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2562
2563         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2564         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2565                 max -= 3;
2566         if (max >= 120) {
2567                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2568                 max = 80;
2569                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2570         }
2571
2572         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2573             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2574              tssi, 0x00), 0x3f)]);
2575         if (power == 0)
2576                 return (BWN_TXPWR_RES_DONE);
2577
2578         rfatt = -((power + 7) / 8);
2579         bbatt = (-(power / 2)) - (4 * rfatt);
2580         if ((rfatt == 0) && (bbatt == 0))
2581                 return (BWN_TXPWR_RES_DONE);
2582         pg->pg_bbatt_delta = bbatt;
2583         pg->pg_rfatt_delta = rfatt;
2584         return (BWN_TXPWR_RES_NEED_ADJUST);
2585 }
2586
2587 static void
2588 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2589 {
2590         struct bwn_phy *phy = &mac->mac_phy;
2591         struct bwn_phy_g *pg = &phy->phy_g;
2592         struct bwn_softc *sc = mac->mac_sc;
2593         int rfatt, bbatt;
2594         uint8_t txctl;
2595
2596         bwn_mac_suspend(mac);
2597
2598         BWN_ASSERT_LOCKED(sc);
2599
2600         bbatt = pg->pg_bbatt.att;
2601         bbatt += pg->pg_bbatt_delta;
2602         rfatt = pg->pg_rfatt.att;
2603         rfatt += pg->pg_rfatt_delta;
2604
2605         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2606         txctl = pg->pg_txctl;
2607         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2608                 if (rfatt <= 1) {
2609                         if (txctl == 0) {
2610                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2611                                 rfatt += 2;
2612                                 bbatt += 2;
2613                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2614                             BWN_BFL_PACTRL) {
2615                                 bbatt += 4 * (rfatt - 2);
2616                                 rfatt = 2;
2617                         }
2618                 } else if (rfatt > 4 && txctl) {
2619                         txctl = 0;
2620                         if (bbatt < 3) {
2621                                 rfatt -= 3;
2622                                 bbatt += 2;
2623                         } else {
2624                                 rfatt -= 2;
2625                                 bbatt -= 2;
2626                         }
2627                 }
2628         }
2629         pg->pg_txctl = txctl;
2630         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2631         pg->pg_rfatt.att = rfatt;
2632         pg->pg_bbatt.att = bbatt;
2633
2634         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2635
2636         bwn_phy_lock(mac);
2637         bwn_rf_lock(mac);
2638         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2639             pg->pg_txctl);
2640         bwn_rf_unlock(mac);
2641         bwn_phy_unlock(mac);
2642
2643         bwn_mac_enable(mac);
2644 }
2645
2646 static void
2647 bwn_phy_g_task_15s(struct bwn_mac *mac)
2648 {
2649         struct bwn_phy *phy = &mac->mac_phy;
2650         struct bwn_phy_g *pg = &phy->phy_g;
2651         struct bwn_softc *sc = mac->mac_sc;
2652         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2653         unsigned long expire, now;
2654         struct bwn_lo_calib *cal, *tmp;
2655         uint8_t expired = 0;
2656
2657         bwn_mac_suspend(mac);
2658
2659         if (lo == NULL)
2660                 goto fail;
2661
2662         BWN_GETTIME(now);
2663         if (bwn_has_hwpctl(mac)) {
2664                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2665                 if (time_before(lo->pwr_vec_read_time, expire)) {
2666                         bwn_lo_get_powervector(mac);
2667                         bwn_phy_g_dc_lookup_init(mac, 0);
2668                 }
2669                 goto fail;
2670         }
2671
2672         expire = now - BWN_LO_CALIB_EXPIRE;
2673         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2674                 if (!time_before(cal->calib_time, expire))
2675                         continue;
2676                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2677                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2678                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2679                         expired = 1;
2680                 }
2681
2682                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2683                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2684                     cal->ctl.i, cal->ctl.q);
2685
2686                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2687                 free(cal, M_DEVBUF);
2688         }
2689         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2690                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2691                     &pg->pg_rfatt);
2692                 if (cal == NULL) {
2693                         device_printf(sc->sc_dev,
2694                             "failed to recalibrate LO\n");
2695                         goto fail;
2696                 }
2697                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2698                 bwn_lo_write(mac, &cal->ctl);
2699         }
2700
2701 fail:
2702         bwn_mac_enable(mac);
2703 }
2704
2705 static void
2706 bwn_phy_g_task_60s(struct bwn_mac *mac)
2707 {
2708         struct bwn_phy *phy = &mac->mac_phy;
2709         struct bwn_softc *sc = mac->mac_sc;
2710         uint8_t old = phy->chan;
2711
2712         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2713                 return;
2714
2715         bwn_mac_suspend(mac);
2716         bwn_nrssi_slope_11g(mac);
2717         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2718                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2719                 bwn_switch_channel(mac, old);
2720         }
2721         bwn_mac_enable(mac);
2722 }
2723
2724 static void
2725 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2726 {
2727
2728         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2729 }
2730
2731 static int
2732 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2733         const struct ieee80211_bpf_params *params)
2734 {
2735         struct ieee80211com *ic = ni->ni_ic;
2736         struct ifnet *ifp = ic->ic_ifp;
2737         struct bwn_softc *sc = ifp->if_softc;
2738         struct bwn_mac *mac = sc->sc_curmac;
2739
2740         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2741             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2742                 ieee80211_free_node(ni);
2743                 m_freem(m);
2744                 return (ENETDOWN);
2745         }
2746
2747         BWN_LOCK(sc);
2748         if (bwn_tx_isfull(sc, m)) {
2749                 ieee80211_free_node(ni);
2750                 m_freem(m);
2751                 ifp->if_oerrors++;
2752                 BWN_UNLOCK(sc);
2753                 return (ENOBUFS);
2754         }
2755
2756         if (bwn_tx_start(sc, ni, m) != 0) {
2757                 if (ni != NULL)
2758                         ieee80211_free_node(ni);
2759                 ifp->if_oerrors++;
2760         }
2761         sc->sc_watchdog_timer = 5;
2762         BWN_UNLOCK(sc);
2763         return (0);
2764 }
2765
2766 /*
2767  * Callback from the 802.11 layer to update the slot time
2768  * based on the current setting.  We use it to notify the
2769  * firmware of ERP changes and the f/w takes care of things
2770  * like slot time and preamble.
2771  */
2772 static void
2773 bwn_updateslot(struct ifnet *ifp)
2774 {
2775         struct bwn_softc *sc = ifp->if_softc;
2776         struct ieee80211com *ic = ifp->if_l2com;
2777         struct bwn_mac *mac;
2778
2779         BWN_LOCK(sc);
2780         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2781                 mac = (struct bwn_mac *)sc->sc_curmac;
2782                 bwn_set_slot_time(mac,
2783                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2784         }
2785         BWN_UNLOCK(sc);
2786 }
2787
2788 /*
2789  * Callback from the 802.11 layer after a promiscuous mode change.
2790  * Note this interface does not check the operating mode as this
2791  * is an internal callback and we are expected to honor the current
2792  * state (e.g. this is used for setting the interface in promiscuous
2793  * mode when operating in hostap mode to do ACS).
2794  */
2795 static void
2796 bwn_update_promisc(struct ifnet *ifp)
2797 {
2798         struct bwn_softc *sc = ifp->if_softc;
2799         struct bwn_mac *mac = sc->sc_curmac;
2800
2801         BWN_LOCK(sc);
2802         mac = sc->sc_curmac;
2803         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2804                 if (ifp->if_flags & IFF_PROMISC)
2805                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2806                 else
2807                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2808                 bwn_set_opmode(mac);
2809         }
2810         BWN_UNLOCK(sc);
2811 }
2812
2813 /*
2814  * Callback from the 802.11 layer to update WME parameters.
2815  */
2816 static int
2817 bwn_wme_update(struct ieee80211com *ic)
2818 {
2819         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2820         struct bwn_mac *mac = sc->sc_curmac;
2821         struct wmeParams *wmep;
2822         int i;
2823
2824         BWN_LOCK(sc);
2825         mac = sc->sc_curmac;
2826         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2827                 bwn_mac_suspend(mac);
2828                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2829                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2830                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2831                 }
2832                 bwn_mac_enable(mac);
2833         }
2834         BWN_UNLOCK(sc);
2835         return (0);
2836 }
2837
2838 static void
2839 bwn_scan_start(struct ieee80211com *ic)
2840 {
2841         struct ifnet *ifp = ic->ic_ifp;
2842         struct bwn_softc *sc = ifp->if_softc;
2843         struct bwn_mac *mac;
2844
2845         BWN_LOCK(sc);
2846         mac = sc->sc_curmac;
2847         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2848                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2849                 bwn_set_opmode(mac);
2850                 /* disable CFP update during scan */
2851                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2852         }
2853         BWN_UNLOCK(sc);
2854 }
2855
2856 static void
2857 bwn_scan_end(struct ieee80211com *ic)
2858 {
2859         struct ifnet *ifp = ic->ic_ifp;
2860         struct bwn_softc *sc = ifp->if_softc;
2861         struct bwn_mac *mac;
2862
2863         BWN_LOCK(sc);
2864         mac = sc->sc_curmac;
2865         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2866                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2867                 bwn_set_opmode(mac);
2868                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2869         }
2870         BWN_UNLOCK(sc);
2871 }
2872
2873 static void
2874 bwn_set_channel(struct ieee80211com *ic)
2875 {
2876         struct ifnet *ifp = ic->ic_ifp;
2877         struct bwn_softc *sc = ifp->if_softc;
2878         struct bwn_mac *mac = sc->sc_curmac;
2879         struct bwn_phy *phy = &mac->mac_phy;
2880         int chan, error;
2881
2882         BWN_LOCK(sc);
2883
2884         error = bwn_switch_band(sc, ic->ic_curchan);
2885         if (error)
2886                 goto fail;
2887         bwn_mac_suspend(mac);
2888         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2889         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2890         if (chan != phy->chan)
2891                 bwn_switch_channel(mac, chan);
2892
2893         /* TX power level */
2894         if (ic->ic_curchan->ic_maxpower != 0 &&
2895             ic->ic_curchan->ic_maxpower != phy->txpower) {
2896                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2897                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2898                     BWN_TXPWR_IGNORE_TSSI);
2899         }
2900
2901         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2902         if (phy->set_antenna)
2903                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2904
2905         if (sc->sc_rf_enabled != phy->rf_on) {
2906                 if (sc->sc_rf_enabled) {
2907                         bwn_rf_turnon(mac);
2908                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2909                                 device_printf(sc->sc_dev,
2910                                     "please turn on the RF switch\n");
2911                 } else
2912                         bwn_rf_turnoff(mac);
2913         }
2914
2915         bwn_mac_enable(mac);
2916
2917 fail:
2918         /*
2919          * Setup radio tap channel freq and flags
2920          */
2921         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2922                 htole16(ic->ic_curchan->ic_freq);
2923         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2924                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2925
2926         BWN_UNLOCK(sc);
2927 }
2928
2929 static struct ieee80211vap *
2930 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2931     enum ieee80211_opmode opmode, int flags,
2932     const uint8_t bssid[IEEE80211_ADDR_LEN],
2933     const uint8_t mac0[IEEE80211_ADDR_LEN])
2934 {
2935         struct ifnet *ifp = ic->ic_ifp;
2936         struct bwn_softc *sc = ifp->if_softc;
2937         struct ieee80211vap *vap;
2938         struct bwn_vap *bvp;
2939         uint8_t mac[IEEE80211_ADDR_LEN];
2940
2941         IEEE80211_ADDR_COPY(mac, mac0);
2942         switch (opmode) {
2943         case IEEE80211_M_HOSTAP:
2944         case IEEE80211_M_MBSS:
2945         case IEEE80211_M_STA:
2946         case IEEE80211_M_WDS:
2947         case IEEE80211_M_MONITOR:
2948         case IEEE80211_M_IBSS:
2949         case IEEE80211_M_AHDEMO:
2950                 break;
2951         default:
2952                 return (NULL);
2953         }
2954
2955         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2956
2957         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2958             M_80211_VAP, M_NOWAIT | M_ZERO);
2959         if (bvp == NULL) {
2960                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2961                 return (NULL);
2962         }
2963         vap = &bvp->bv_vap;
2964         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2965         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2966         /* override with driver methods */
2967         bvp->bv_newstate = vap->iv_newstate;
2968         vap->iv_newstate = bwn_newstate;
2969
2970         /* override max aid so sta's cannot assoc when we're out of sta id's */
2971         vap->iv_max_aid = BWN_STAID_MAX;
2972
2973         ieee80211_ratectl_init(vap);
2974
2975         /* complete setup */
2976         ieee80211_vap_attach(vap, ieee80211_media_change,
2977             ieee80211_media_status);
2978         return (vap);
2979 }
2980
2981 static void
2982 bwn_vap_delete(struct ieee80211vap *vap)
2983 {
2984         struct bwn_vap *bvp = BWN_VAP(vap);
2985
2986         ieee80211_ratectl_deinit(vap);
2987         ieee80211_vap_detach(vap);
2988         free(bvp, M_80211_VAP);
2989 }
2990
2991 static void
2992 bwn_init(void *arg)
2993 {
2994         struct bwn_softc *sc = arg;
2995         struct ifnet *ifp = sc->sc_ifp;
2996         struct ieee80211com *ic = ifp->if_l2com;
2997         int error = 0;
2998
2999         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3000                 __func__, ifp->if_flags);
3001
3002         BWN_LOCK(sc);
3003         error = bwn_init_locked(sc);
3004         BWN_UNLOCK(sc);
3005
3006         if (error == 0)
3007                 ieee80211_start_all(ic);        /* start all vap's */
3008 }
3009
3010 static int
3011 bwn_init_locked(struct bwn_softc *sc)
3012 {
3013         struct bwn_mac *mac;
3014         struct ifnet *ifp = sc->sc_ifp;
3015         int error;
3016
3017         BWN_ASSERT_LOCKED(sc);
3018
3019         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3020         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3021         sc->sc_filters = 0;
3022         bwn_wme_clear(sc);
3023         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3024         sc->sc_rf_enabled = 1;
3025
3026         mac = sc->sc_curmac;
3027         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3028                 error = bwn_core_init(mac);
3029                 if (error != 0)
3030                         return (error);
3031         }
3032         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3033                 bwn_core_start(mac);
3034
3035         bwn_set_opmode(mac);
3036         bwn_set_pretbtt(mac);
3037         bwn_spu_setdelay(mac, 0);
3038         bwn_set_macaddr(mac);
3039
3040         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3041         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3042         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3043
3044         return (0);
3045 }
3046
3047 static void
3048 bwn_stop(struct bwn_softc *sc, int statechg)
3049 {
3050
3051         BWN_LOCK(sc);
3052         bwn_stop_locked(sc, statechg);
3053         BWN_UNLOCK(sc);
3054 }
3055
3056 static void
3057 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3058 {
3059         struct bwn_mac *mac = sc->sc_curmac;
3060         struct ifnet *ifp = sc->sc_ifp;
3061
3062         BWN_ASSERT_LOCKED(sc);
3063
3064         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3065                 /* XXX FIXME opmode not based on VAP */
3066                 bwn_set_opmode(mac);
3067                 bwn_set_macaddr(mac);
3068         }
3069
3070         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3071                 bwn_core_stop(mac);
3072
3073         callout_stop(&sc->sc_led_blink_ch);
3074         sc->sc_led_blinking = 0;
3075
3076         bwn_core_exit(mac);
3077         sc->sc_rf_enabled = 0;
3078
3079         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3080 }
3081
3082 static void
3083 bwn_wme_clear(struct bwn_softc *sc)
3084 {
3085 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3086         struct wmeParams *p;
3087         unsigned int i;
3088
3089         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3090             ("%s:%d: fail", __func__, __LINE__));
3091
3092         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3093                 p = &(sc->sc_wmeParams[i]);
3094
3095                 switch (bwn_wme_shm_offsets[i]) {
3096                 case BWN_WME_VOICE:
3097                         p->wmep_txopLimit = 0;
3098                         p->wmep_aifsn = 2;
3099                         /* XXX FIXME: log2(cwmin) */
3100                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3101                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3102                         break;
3103                 case BWN_WME_VIDEO:
3104                         p->wmep_txopLimit = 0;
3105                         p->wmep_aifsn = 2;
3106                         /* XXX FIXME: log2(cwmin) */
3107                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3108                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3109                         break;
3110                 case BWN_WME_BESTEFFORT:
3111                         p->wmep_txopLimit = 0;
3112                         p->wmep_aifsn = 3;
3113                         /* XXX FIXME: log2(cwmin) */
3114                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3115                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3116                         break;
3117                 case BWN_WME_BACKGROUND:
3118                         p->wmep_txopLimit = 0;
3119                         p->wmep_aifsn = 7;
3120                         /* XXX FIXME: log2(cwmin) */
3121                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3122                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3123                         break;
3124                 default:
3125                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3126                 }
3127         }
3128 }
3129
3130 static int
3131 bwn_core_init(struct bwn_mac *mac)
3132 {
3133         struct bwn_softc *sc = mac->mac_sc;
3134         uint64_t hf;
3135         int error;
3136
3137         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3138             ("%s:%d: fail", __func__, __LINE__));
3139
3140         siba_powerup(sc->sc_dev, 0);
3141         if (!siba_dev_isup(sc->sc_dev))
3142                 bwn_reset_core(mac,
3143                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3144
3145         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3146         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3147         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3148         BWN_GETTIME(mac->mac_phy.nexttime);
3149         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3150         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3151         mac->mac_stats.link_noise = -95;
3152         mac->mac_reason_intr = 0;
3153         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3154         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3155 #ifdef BWN_DEBUG
3156         if (sc->sc_debug & BWN_DEBUG_XMIT)
3157                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3158 #endif
3159         mac->mac_suspended = 1;
3160         mac->mac_task_state = 0;
3161         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3162
3163         mac->mac_phy.init_pre(mac);
3164
3165         siba_pcicore_intr(sc->sc_dev);
3166
3167         siba_fix_imcfglobug(sc->sc_dev);
3168         bwn_bt_disable(mac);
3169         if (mac->mac_phy.prepare_hw) {
3170                 error = mac->mac_phy.prepare_hw(mac);
3171                 if (error)
3172                         goto fail0;
3173         }
3174         error = bwn_chip_init(mac);
3175         if (error)
3176                 goto fail0;
3177         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3178             siba_get_revid(sc->sc_dev));
3179         hf = bwn_hf_read(mac);
3180         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3181                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3182                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3183                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3184                 if (mac->mac_phy.rev == 1)
3185                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3186         }
3187         if (mac->mac_phy.rf_ver == 0x2050) {
3188                 if (mac->mac_phy.rf_rev < 6)
3189                         hf |= BWN_HF_FORCE_VCO_RECALC;
3190                 if (mac->mac_phy.rf_rev == 6)
3191                         hf |= BWN_HF_4318_TSSI;
3192         }
3193         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3194                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3195         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3196             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3197                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3198         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3199         bwn_hf_write(mac, hf);
3200
3201         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3202         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3203         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3204         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3205
3206         bwn_rate_init(mac);
3207         bwn_set_phytxctl(mac);
3208
3209         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3210             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3211         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3212
3213         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3214                 bwn_pio_init(mac);
3215         else
3216                 bwn_dma_init(mac);
3217         bwn_wme_init(mac);
3218         bwn_spu_setdelay(mac, 1);
3219         bwn_bt_enable(mac);
3220
3221         siba_powerup(sc->sc_dev,
3222             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3223         bwn_set_macaddr(mac);
3224         bwn_crypt_init(mac);
3225
3226         /* XXX LED initializatin */
3227
3228         mac->mac_status = BWN_MAC_STATUS_INITED;
3229
3230         return (error);
3231
3232 fail0:
3233         siba_powerdown(sc->sc_dev);
3234         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3235             ("%s:%d: fail", __func__, __LINE__));
3236         return (error);
3237 }
3238
3239 static void
3240 bwn_core_start(struct bwn_mac *mac)
3241 {
3242         struct bwn_softc *sc = mac->mac_sc;
3243         uint32_t tmp;
3244
3245         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3246             ("%s:%d: fail", __func__, __LINE__));
3247
3248         if (siba_get_revid(sc->sc_dev) < 5)
3249                 return;
3250
3251         while (1) {
3252                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3253                 if (!(tmp & 0x00000001))
3254                         break;
3255                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3256         }
3257
3258         bwn_mac_enable(mac);
3259         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3260         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3261
3262         mac->mac_status = BWN_MAC_STATUS_STARTED;
3263 }
3264
3265 static void
3266 bwn_core_exit(struct bwn_mac *mac)
3267 {
3268         struct bwn_softc *sc = mac->mac_sc;
3269         uint32_t macctl;
3270
3271         BWN_ASSERT_LOCKED(mac->mac_sc);
3272
3273         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3274             ("%s:%d: fail", __func__, __LINE__));
3275
3276         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3277                 return;
3278         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3279
3280         macctl = BWN_READ_4(mac, BWN_MACCTL);
3281         macctl &= ~BWN_MACCTL_MCODE_RUN;
3282         macctl |= BWN_MACCTL_MCODE_JMP0;
3283         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3284
3285         bwn_dma_stop(mac);
3286         bwn_pio_stop(mac);
3287         bwn_chip_exit(mac);
3288         mac->mac_phy.switch_analog(mac, 0);
3289         siba_dev_down(sc->sc_dev, 0);
3290         siba_powerdown(sc->sc_dev);
3291 }
3292
3293 static void
3294 bwn_bt_disable(struct bwn_mac *mac)
3295 {
3296         struct bwn_softc *sc = mac->mac_sc;
3297
3298         (void)sc;
3299         /* XXX do nothing yet */
3300 }
3301
3302 static int
3303 bwn_chip_init(struct bwn_mac *mac)
3304 {
3305         struct bwn_softc *sc = mac->mac_sc;
3306         struct bwn_phy *phy = &mac->mac_phy;
3307         uint32_t macctl;
3308         int error;
3309
3310         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3311         if (phy->gmode)
3312                 macctl |= BWN_MACCTL_GMODE;
3313         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3314
3315         error = bwn_fw_fillinfo(mac);
3316         if (error)
3317                 return (error);
3318         error = bwn_fw_loaducode(mac);
3319         if (error)
3320                 return (error);
3321
3322         error = bwn_gpio_init(mac);
3323         if (error)
3324                 return (error);
3325
3326         error = bwn_fw_loadinitvals(mac);
3327         if (error) {
3328                 siba_gpio_set(sc->sc_dev, 0);
3329                 return (error);
3330         }
3331         phy->switch_analog(mac, 1);
3332         error = bwn_phy_init(mac);
3333         if (error) {
3334                 siba_gpio_set(sc->sc_dev, 0);
3335                 return (error);
3336         }
3337         if (phy->set_im)
3338                 phy->set_im(mac, BWN_IMMODE_NONE);
3339         if (phy->set_antenna)
3340                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3341         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3342
3343         if (phy->type == BWN_PHYTYPE_B)
3344                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3345         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3346         if (siba_get_revid(sc->sc_dev) < 5)
3347                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3348
3349         BWN_WRITE_4(mac, BWN_MACCTL,
3350             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3351         BWN_WRITE_4(mac, BWN_MACCTL,
3352             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3353         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3354
3355         bwn_set_opmode(mac);
3356         if (siba_get_revid(sc->sc_dev) < 3) {
3357                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3358                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3359                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3360                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3361         } else {
3362                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3363                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3364         }
3365         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3366         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3367         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3368         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3369         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3370         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3371         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3372         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3373             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3374         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3375         return (error);
3376 }
3377
3378 /* read hostflags */
3379 static uint64_t
3380 bwn_hf_read(struct bwn_mac *mac)
3381 {
3382         uint64_t ret;
3383
3384         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3385         ret <<= 16;
3386         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3387         ret <<= 16;
3388         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3389         return (ret);
3390 }
3391
3392 static void
3393 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3394 {
3395
3396         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3397             (value & 0x00000000ffffull));
3398         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3399             (value & 0x0000ffff0000ull) >> 16);
3400         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3401             (value & 0xffff00000000ULL) >> 32);
3402 }
3403
3404 static void
3405 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3406 {
3407
3408         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3409         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3410 }
3411
3412 static void
3413 bwn_rate_init(struct bwn_mac *mac)
3414 {
3415
3416         switch (mac->mac_phy.type) {
3417         case BWN_PHYTYPE_A:
3418         case BWN_PHYTYPE_G:
3419         case BWN_PHYTYPE_LP:
3420         case BWN_PHYTYPE_N:
3421                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3422                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3423                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3424                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3425                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3426                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3427                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3428                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3429                         break;
3430                 /* FALLTHROUGH */
3431         case BWN_PHYTYPE_B:
3432                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3433                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3434                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3435                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3436                 break;
3437         default:
3438                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3439         }
3440 }
3441
3442 static void
3443 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3444 {
3445         uint16_t offset;
3446
3447         if (ofdm) {
3448                 offset = 0x480;
3449                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3450         } else {
3451                 offset = 0x4c0;
3452                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3453         }
3454         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3455             bwn_shm_read_2(mac, BWN_SHARED, offset));
3456 }
3457
3458 static uint8_t
3459 bwn_plcp_getcck(const uint8_t bitrate)
3460 {
3461
3462         switch (bitrate) {
3463         case BWN_CCK_RATE_1MB:
3464                 return (0x0a);
3465         case BWN_CCK_RATE_2MB:
3466                 return (0x14);
3467         case BWN_CCK_RATE_5MB:
3468                 return (0x37);
3469         case BWN_CCK_RATE_11MB:
3470                 return (0x6e);
3471         }
3472         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3473         return (0);
3474 }
3475
3476 static uint8_t
3477 bwn_plcp_getofdm(const uint8_t bitrate)
3478 {
3479
3480         switch (bitrate) {
3481         case BWN_OFDM_RATE_6MB:
3482                 return (0xb);
3483         case BWN_OFDM_RATE_9MB:
3484                 return (0xf);
3485         case BWN_OFDM_RATE_12MB:
3486                 return (0xa);
3487         case BWN_OFDM_RATE_18MB:
3488                 return (0xe);
3489         case BWN_OFDM_RATE_24MB:
3490                 return (0x9);
3491         case BWN_OFDM_RATE_36MB:
3492                 return (0xd);
3493         case BWN_OFDM_RATE_48MB:
3494                 return (0x8);
3495         case BWN_OFDM_RATE_54MB:
3496                 return (0xc);
3497         }
3498         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3499         return (0);
3500 }
3501
3502 static void
3503 bwn_set_phytxctl(struct bwn_mac *mac)
3504 {
3505         uint16_t ctl;
3506
3507         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3508             BWN_TX_PHY_TXPWR);
3509         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3510         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3511         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3512 }
3513
3514 static void
3515 bwn_pio_init(struct bwn_mac *mac)
3516 {
3517         struct bwn_pio *pio = &mac->mac_method.pio;
3518
3519         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3520             & ~BWN_MACCTL_BIGENDIAN);
3521         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3522
3523         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3524         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3525         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3526         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3527         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3528         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3529 }
3530
3531 static void
3532 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3533     int index)
3534 {
3535         struct bwn_pio_txpkt *tp;
3536         struct bwn_softc *sc = mac->mac_sc;
3537         unsigned int i;
3538
3539         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3540         tq->tq_index = index;
3541
3542         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3543         if (siba_get_revid(sc->sc_dev) >= 8)
3544                 tq->tq_size = 1920;
3545         else {
3546                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3547                 tq->tq_size -= 80;
3548         }
3549
3550         TAILQ_INIT(&tq->tq_pktlist);
3551         for (i = 0; i < N(tq->tq_pkts); i++) {
3552                 tp = &(tq->tq_pkts[i]);
3553                 tp->tp_index = i;
3554                 tp->tp_queue = tq;
3555                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3556         }
3557 }
3558
3559 static uint16_t
3560 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3561 {
3562         struct bwn_softc *sc = mac->mac_sc;
3563         static const uint16_t bases[] = {
3564                 BWN_PIO_BASE0,
3565                 BWN_PIO_BASE1,
3566                 BWN_PIO_BASE2,
3567                 BWN_PIO_BASE3,
3568                 BWN_PIO_BASE4,
3569                 BWN_PIO_BASE5,
3570                 BWN_PIO_BASE6,
3571                 BWN_PIO_BASE7,
3572         };
3573         static const uint16_t bases_rev11[] = {
3574                 BWN_PIO11_BASE0,
3575                 BWN_PIO11_BASE1,
3576                 BWN_PIO11_BASE2,
3577                 BWN_PIO11_BASE3,
3578                 BWN_PIO11_BASE4,
3579                 BWN_PIO11_BASE5,
3580         };
3581
3582         if (siba_get_revid(sc->sc_dev) >= 11) {
3583                 if (index >= N(bases_rev11))
3584                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3585                 return (bases_rev11[index]);
3586         }
3587         if (index >= N(bases))
3588                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3589         return (bases[index]);
3590 }
3591
3592 static void
3593 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3594     int index)
3595 {
3596         struct bwn_softc *sc = mac->mac_sc;
3597
3598         prq->prq_mac = mac;
3599         prq->prq_rev = siba_get_revid(sc->sc_dev);
3600         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3601         bwn_dma_rxdirectfifo(mac, index, 1);
3602 }
3603
3604 static void
3605 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3606 {
3607         if (tq == NULL)
3608                 return;
3609         bwn_pio_cancel_tx_packets(tq);
3610 }
3611
3612 static void
3613 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3614 {
3615
3616         bwn_destroy_pioqueue_tx(pio);
3617 }
3618
3619 static uint16_t
3620 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3621     uint16_t offset)
3622 {
3623
3624         return (BWN_READ_2(mac, tq->tq_base + offset));
3625 }
3626
3627 static void
3628 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3629 {
3630         uint32_t ctl;
3631         int type;
3632         uint16_t base;
3633
3634         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3635         base = bwn_dma_base(type, idx);
3636         if (type == BWN_DMA_64BIT) {
3637                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3638                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3639                 if (enable)
3640                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3641                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3642         } else {
3643                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3644                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3645                 if (enable)
3646                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3647                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3648         }
3649 }
3650
3651 static uint64_t
3652 bwn_dma_mask(struct bwn_mac *mac)
3653 {
3654         uint32_t tmp;
3655         uint16_t base;
3656
3657         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3658         if (tmp & SIBA_TGSHIGH_DMA64)
3659                 return (BWN_DMA_BIT_MASK(64));
3660         base = bwn_dma_base(0, 0);
3661         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3662         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3663         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3664                 return (BWN_DMA_BIT_MASK(32));
3665
3666         return (BWN_DMA_BIT_MASK(30));
3667 }
3668
3669 static int
3670 bwn_dma_mask2type(uint64_t dmamask)
3671 {
3672
3673         if (dmamask == BWN_DMA_BIT_MASK(30))
3674                 return (BWN_DMA_30BIT);
3675         if (dmamask == BWN_DMA_BIT_MASK(32))
3676                 return (BWN_DMA_32BIT);
3677         if (dmamask == BWN_DMA_BIT_MASK(64))
3678                 return (BWN_DMA_64BIT);
3679         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3680         return (BWN_DMA_30BIT);
3681 }
3682
3683 static void
3684 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3685 {
3686         struct bwn_pio_txpkt *tp;
3687         unsigned int i;
3688
3689         for (i = 0; i < N(tq->tq_pkts); i++) {
3690                 tp = &(tq->tq_pkts[i]);
3691                 if (tp->tp_m) {
3692                         m_freem(tp->tp_m);
3693                         tp->tp_m = NULL;
3694                 }
3695         }
3696 }
3697
3698 static uint16_t
3699 bwn_dma_base(int type, int controller_idx)
3700 {
3701         static const uint16_t map64[] = {
3702                 BWN_DMA64_BASE0,
3703                 BWN_DMA64_BASE1,
3704                 BWN_DMA64_BASE2,
3705                 BWN_DMA64_BASE3,
3706                 BWN_DMA64_BASE4,
3707                 BWN_DMA64_BASE5,
3708         };
3709         static const uint16_t map32[] = {
3710                 BWN_DMA32_BASE0,
3711                 BWN_DMA32_BASE1,
3712                 BWN_DMA32_BASE2,
3713                 BWN_DMA32_BASE3,
3714                 BWN_DMA32_BASE4,
3715                 BWN_DMA32_BASE5,
3716         };
3717
3718         if (type == BWN_DMA_64BIT) {
3719                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3720                     ("%s:%d: fail", __func__, __LINE__));
3721                 return (map64[controller_idx]);
3722         }
3723         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3724             ("%s:%d: fail", __func__, __LINE__));
3725         return (map32[controller_idx]);
3726 }
3727
3728 static void
3729 bwn_dma_init(struct bwn_mac *mac)
3730 {
3731         struct bwn_dma *dma = &mac->mac_method.dma;
3732
3733         /* setup TX DMA channels. */
3734         bwn_dma_setup(dma->wme[WME_AC_BK]);
3735         bwn_dma_setup(dma->wme[WME_AC_BE]);
3736         bwn_dma_setup(dma->wme[WME_AC_VI]);
3737         bwn_dma_setup(dma->wme[WME_AC_VO]);
3738         bwn_dma_setup(dma->mcast);
3739         /* setup RX DMA channel. */
3740         bwn_dma_setup(dma->rx);
3741 }
3742
3743 static struct bwn_dma_ring *
3744 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3745     int for_tx, int type)
3746 {
3747         struct bwn_dma *dma = &mac->mac_method.dma;
3748         struct bwn_dma_ring *dr;
3749         struct bwn_dmadesc_generic *desc;
3750         struct bwn_dmadesc_meta *mt;
3751         struct bwn_softc *sc = mac->mac_sc;
3752         int error, i;
3753
3754         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3755         if (dr == NULL)
3756                 goto out;
3757         dr->dr_numslots = BWN_RXRING_SLOTS;
3758         if (for_tx)
3759                 dr->dr_numslots = BWN_TXRING_SLOTS;
3760
3761         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3762             M_DEVBUF, M_NOWAIT | M_ZERO);
3763         if (dr->dr_meta == NULL)
3764                 goto fail0;
3765
3766         dr->dr_type = type;
3767         dr->dr_mac = mac;
3768         dr->dr_base = bwn_dma_base(type, controller_index);
3769         dr->dr_index = controller_index;
3770         if (type == BWN_DMA_64BIT) {
3771                 dr->getdesc = bwn_dma_64_getdesc;
3772                 dr->setdesc = bwn_dma_64_setdesc;
3773                 dr->start_transfer = bwn_dma_64_start_transfer;
3774                 dr->suspend = bwn_dma_64_suspend;
3775                 dr->resume = bwn_dma_64_resume;
3776                 dr->get_curslot = bwn_dma_64_get_curslot;
3777                 dr->set_curslot = bwn_dma_64_set_curslot;
3778         } else {
3779                 dr->getdesc = bwn_dma_32_getdesc;
3780                 dr->setdesc = bwn_dma_32_setdesc;
3781                 dr->start_transfer = bwn_dma_32_start_transfer;
3782                 dr->suspend = bwn_dma_32_suspend;
3783                 dr->resume = bwn_dma_32_resume;
3784                 dr->get_curslot = bwn_dma_32_get_curslot;
3785                 dr->set_curslot = bwn_dma_32_set_curslot;
3786         }
3787         if (for_tx) {
3788                 dr->dr_tx = 1;
3789                 dr->dr_curslot = -1;
3790         } else {
3791                 if (dr->dr_index == 0) {
3792                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3793                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3794                 } else
3795                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3796         }
3797
3798         error = bwn_dma_allocringmemory(dr);
3799         if (error)
3800                 goto fail2;
3801
3802         if (for_tx) {
3803                 /*
3804                  * Assumption: BWN_TXRING_SLOTS can be divided by
3805                  * BWN_TX_SLOTS_PER_FRAME
3806                  */
3807                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3808                     ("%s:%d: fail", __func__, __LINE__));
3809
3810                 dr->dr_txhdr_cache =
3811                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3812                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3813                 KASSERT(dr->dr_txhdr_cache != NULL,
3814                     ("%s:%d: fail", __func__, __LINE__));
3815
3816                 /*
3817                  * Create TX ring DMA stuffs
3818                  */
3819                 error = bus_dma_tag_create(dma->parent_dtag,
3820                                     BWN_ALIGN, 0,
3821                                     BUS_SPACE_MAXADDR,
3822                                     BUS_SPACE_MAXADDR,
3823                                     NULL, NULL,
3824                                     BWN_HDRSIZE(mac),
3825                                     1,
3826                                     BUS_SPACE_MAXSIZE_32BIT,
3827                                     0,
3828                                     NULL, NULL,
3829                                     &dr->dr_txring_dtag);
3830                 if (error) {
3831                         device_printf(sc->sc_dev,
3832                             "can't create TX ring DMA tag: TODO frees\n");
3833                         goto fail1;
3834                 }
3835
3836                 for (i = 0; i < dr->dr_numslots; i += 2) {
3837                         dr->getdesc(dr, i, &desc, &mt);
3838
3839                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3840                         mt->mt_m = NULL;
3841                         mt->mt_ni = NULL;
3842                         mt->mt_islast = 0;
3843                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3844                             &mt->mt_dmap);
3845                         if (error) {
3846                                 device_printf(sc->sc_dev,
3847                                      "can't create RX buf DMA map\n");
3848                                 goto fail1;
3849                         }
3850
3851                         dr->getdesc(dr, i + 1, &desc, &mt);
3852
3853                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3854                         mt->mt_m = NULL;
3855                         mt->mt_ni = NULL;
3856                         mt->mt_islast = 1;
3857                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3858                             &mt->mt_dmap);
3859                         if (error) {
3860                                 device_printf(sc->sc_dev,
3861                                      "can't create RX buf DMA map\n");
3862                                 goto fail1;
3863                         }
3864                 }
3865         } else {
3866                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3867                     &dr->dr_spare_dmap);
3868                 if (error) {
3869                         device_printf(sc->sc_dev,
3870                             "can't create RX buf DMA map\n");
3871                         goto out;               /* XXX wrong! */
3872                 }
3873
3874                 for (i = 0; i < dr->dr_numslots; i++) {
3875                         dr->getdesc(dr, i, &desc, &mt);
3876
3877                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3878                             &mt->mt_dmap);
3879                         if (error) {
3880                                 device_printf(sc->sc_dev,
3881                                     "can't create RX buf DMA map\n");
3882                                 goto out;       /* XXX wrong! */
3883                         }
3884                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3885                         if (error) {
3886                                 device_printf(sc->sc_dev,
3887                                     "failed to allocate RX buf\n");
3888                                 goto out;       /* XXX wrong! */
3889                         }
3890                 }
3891
3892                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3893                     BUS_DMASYNC_PREWRITE);
3894
3895                 dr->dr_usedslot = dr->dr_numslots;
3896         }
3897
3898       out:
3899         return (dr);
3900
3901 fail2:
3902         free(dr->dr_txhdr_cache, M_DEVBUF);
3903 fail1:
3904         free(dr->dr_meta, M_DEVBUF);
3905 fail0:
3906         free(dr, M_DEVBUF);
3907         return (NULL);
3908 }
3909
3910 static void
3911 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3912 {
3913
3914         if (dr == NULL)
3915                 return;
3916
3917         bwn_dma_free_descbufs(*dr);
3918         bwn_dma_free_ringmemory(*dr);
3919
3920         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3921         free((*dr)->dr_meta, M_DEVBUF);
3922         free(*dr, M_DEVBUF);
3923
3924         *dr = NULL;
3925 }
3926
3927 static void
3928 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3929     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3930 {
3931         struct bwn_dmadesc32 *desc;
3932
3933         *meta = &(dr->dr_meta[slot]);
3934         desc = dr->dr_ring_descbase;
3935         desc = &(desc[slot]);
3936
3937         *gdesc = (struct bwn_dmadesc_generic *)desc;
3938 }
3939
3940 static void
3941 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3942     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3943     int start, int end, int irq)
3944 {
3945         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3946         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3947         uint32_t addr, addrext, ctl;
3948         int slot;
3949
3950         slot = (int)(&(desc->dma.dma32) - descbase);
3951         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3952             ("%s:%d: fail", __func__, __LINE__));
3953
3954         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3955         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3956         addr |= siba_dma_translation(sc->sc_dev);
3957         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3958         if (slot == dr->dr_numslots - 1)
3959                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3960         if (start)
3961                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3962         if (end)
3963                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3964         if (irq)
3965                 ctl |= BWN_DMA32_DCTL_IRQ;
3966         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3967             & BWN_DMA32_DCTL_ADDREXT_MASK;
3968
3969         desc->dma.dma32.control = htole32(ctl);
3970         desc->dma.dma32.address = htole32(addr);
3971 }
3972
3973 static void
3974 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3975 {
3976
3977         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3978             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3979 }
3980
3981 static void
3982 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3983 {
3984
3985         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3986             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3987 }
3988
3989 static void
3990 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3991 {
3992
3993         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3994             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3995 }
3996
3997 static int
3998 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3999 {
4000         uint32_t val;
4001
4002         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4003         val &= BWN_DMA32_RXDPTR;
4004
4005         return (val / sizeof(struct bwn_dmadesc32));
4006 }
4007
4008 static void
4009 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4010 {
4011
4012         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4013             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4014 }
4015
4016 static void
4017 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4018     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4019 {
4020         struct bwn_dmadesc64 *desc;
4021
4022         *meta = &(dr->dr_meta[slot]);
4023         desc = dr->dr_ring_descbase;
4024         desc = &(desc[slot]);
4025
4026         *gdesc = (struct bwn_dmadesc_generic *)desc;
4027 }
4028
4029 static void
4030 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4031     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4032     int start, int end, int irq)
4033 {
4034         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4035         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4036         int slot;
4037         uint32_t ctl0 = 0, ctl1 = 0;
4038         uint32_t addrlo, addrhi;
4039         uint32_t addrext;
4040
4041         slot = (int)(&(desc->dma.dma64) - descbase);
4042         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4043             ("%s:%d: fail", __func__, __LINE__));
4044
4045         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4046         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4047         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4048             30;
4049         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4050         if (slot == dr->dr_numslots - 1)
4051                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4052         if (start)
4053                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4054         if (end)
4055                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4056         if (irq)
4057                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4058         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4059         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4060             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4061
4062         desc->dma.dma64.control0 = htole32(ctl0);
4063         desc->dma.dma64.control1 = htole32(ctl1);
4064         desc->dma.dma64.address_low = htole32(addrlo);
4065         desc->dma.dma64.address_high = htole32(addrhi);
4066 }
4067
4068 static void
4069 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4070 {
4071
4072         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4073             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4074 }
4075
4076 static void
4077 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4078 {
4079
4080         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4081             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4082 }
4083
4084 static void
4085 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4086 {
4087
4088         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4089             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4090 }
4091
4092 static int
4093 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4094 {
4095         uint32_t val;
4096
4097         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4098         val &= BWN_DMA64_RXSTATDPTR;
4099
4100         return (val / sizeof(struct bwn_dmadesc64));
4101 }
4102
4103 static void
4104 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4105 {
4106
4107         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4108             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4109 }
4110
4111 static int
4112 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4113 {
4114         struct bwn_mac *mac = dr->dr_mac;
4115         struct bwn_dma *dma = &mac->mac_method.dma;
4116         struct bwn_softc *sc = mac->mac_sc;
4117         int error;
4118
4119         error = bus_dma_tag_create(dma->parent_dtag,
4120                             BWN_ALIGN, 0,
4121                             BUS_SPACE_MAXADDR,
4122                             BUS_SPACE_MAXADDR,
4123                             NULL, NULL,
4124                             BWN_DMA_RINGMEMSIZE,
4125                             1,
4126                             BUS_SPACE_MAXSIZE_32BIT,
4127                             0,
4128                             NULL, NULL,
4129                             &dr->dr_ring_dtag);
4130         if (error) {
4131                 device_printf(sc->sc_dev,
4132                     "can't create TX ring DMA tag: TODO frees\n");
4133                 return (-1);
4134         }
4135
4136         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4137             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4138             &dr->dr_ring_dmap);
4139         if (error) {
4140                 device_printf(sc->sc_dev,
4141                     "can't allocate DMA mem: TODO frees\n");
4142                 return (-1);
4143         }
4144         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4145             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4146             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4147         if (error) {
4148                 device_printf(sc->sc_dev,
4149                     "can't load DMA mem: TODO free\n");
4150                 return (-1);
4151         }
4152
4153         return (0);
4154 }
4155
4156 static void
4157 bwn_dma_setup(struct bwn_dma_ring *dr)
4158 {
4159         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4160         uint64_t ring64;
4161         uint32_t addrext, ring32, value;
4162         uint32_t trans = siba_dma_translation(sc->sc_dev);
4163
4164         if (dr->dr_tx) {
4165                 dr->dr_curslot = -1;
4166
4167                 if (dr->dr_type == BWN_DMA_64BIT) {
4168                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4169                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4170                             >> 30;
4171                         value = BWN_DMA64_TXENABLE;
4172                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4173                             & BWN_DMA64_TXADDREXT_MASK;
4174                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4175                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4176                             (ring64 & 0xffffffff));
4177                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4178                             ((ring64 >> 32) &
4179                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4180                 } else {
4181                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4182                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4183                         value = BWN_DMA32_TXENABLE;
4184                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4185                             & BWN_DMA32_TXADDREXT_MASK;
4186                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4187                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4188                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4189                 }
4190                 return;
4191         }
4192
4193         /*
4194          * set for RX
4195          */
4196         dr->dr_usedslot = dr->dr_numslots;
4197
4198         if (dr->dr_type == BWN_DMA_64BIT) {
4199                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4200                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4201                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4202                 value |= BWN_DMA64_RXENABLE;
4203                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4204                     & BWN_DMA64_RXADDREXT_MASK;
4205                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4206                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4207                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4208                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4209                     | (trans << 1));
4210                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4211                     sizeof(struct bwn_dmadesc64));
4212         } else {
4213                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4214                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4215                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4216                 value |= BWN_DMA32_RXENABLE;
4217                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4218                     & BWN_DMA32_RXADDREXT_MASK;
4219                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4220                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4221                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4222                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4223                     sizeof(struct bwn_dmadesc32));
4224         }
4225 }
4226
4227 static void
4228 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4229 {
4230
4231         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4232         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4233             dr->dr_ring_dmap);
4234 }
4235
4236 static void
4237 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4238 {
4239
4240         if (dr->dr_tx) {
4241                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4242                 if (dr->dr_type == BWN_DMA_64BIT) {
4243                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4244                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4245                 } else
4246                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4247         } else {
4248                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4249                 if (dr->dr_type == BWN_DMA_64BIT) {
4250                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4251                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4252                 } else
4253                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4254         }
4255 }
4256
4257 static void
4258 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4259 {
4260         struct bwn_dmadesc_generic *desc;
4261         struct bwn_dmadesc_meta *meta;
4262         struct bwn_mac *mac = dr->dr_mac;
4263         struct bwn_dma *dma = &mac->mac_method.dma;
4264         struct bwn_softc *sc = mac->mac_sc;
4265         int i;
4266
4267         if (!dr->dr_usedslot)
4268                 return;
4269         for (i = 0; i < dr->dr_numslots; i++) {
4270                 dr->getdesc(dr, i, &desc, &meta);
4271
4272                 if (meta->mt_m == NULL) {
4273                         if (!dr->dr_tx)
4274                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4275                                     __func__);
4276                         continue;
4277                 }
4278                 if (dr->dr_tx) {
4279                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4280                                 bus_dmamap_unload(dr->dr_txring_dtag,
4281                                     meta->mt_dmap);
4282                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4283                                 bus_dmamap_unload(dma->txbuf_dtag,
4284                                     meta->mt_dmap);
4285                 } else
4286                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4287                 bwn_dma_free_descbuf(dr, meta);
4288         }
4289 }
4290
4291 static int
4292 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4293     int type)
4294 {
4295         struct bwn_softc *sc = mac->mac_sc;
4296         uint32_t value;
4297         int i;
4298         uint16_t offset;
4299
4300         for (i = 0; i < 10; i++) {
4301                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4302                     BWN_DMA32_TXSTATUS;
4303                 value = BWN_READ_4(mac, base + offset);
4304                 if (type == BWN_DMA_64BIT) {
4305                         value &= BWN_DMA64_TXSTAT;
4306                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4307                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4308                             value == BWN_DMA64_TXSTAT_STOPPED)
4309                                 break;
4310                 } else {
4311                         value &= BWN_DMA32_TXSTATE;
4312                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4313                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4314                             value == BWN_DMA32_TXSTAT_STOPPED)
4315                                 break;
4316                 }
4317                 DELAY(1000);
4318         }
4319         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4320         BWN_WRITE_4(mac, base + offset, 0);
4321         for (i = 0; i < 10; i++) {
4322                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4323                                                    BWN_DMA32_TXSTATUS;
4324                 value = BWN_READ_4(mac, base + offset);
4325                 if (type == BWN_DMA_64BIT) {
4326                         value &= BWN_DMA64_TXSTAT;
4327                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4328                                 i = -1;
4329                                 break;
4330                         }
4331                 } else {
4332                         value &= BWN_DMA32_TXSTATE;
4333                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4334                                 i = -1;
4335                                 break;
4336                         }
4337                 }
4338                 DELAY(1000);
4339         }
4340         if (i != -1) {
4341                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4342                 return (ENODEV);
4343         }
4344         DELAY(1000);
4345
4346         return (0);
4347 }
4348
4349 static int
4350 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4351     int type)
4352 {
4353         struct bwn_softc *sc = mac->mac_sc;
4354         uint32_t value;
4355         int i;
4356         uint16_t offset;
4357
4358         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4359         BWN_WRITE_4(mac, base + offset, 0);
4360         for (i = 0; i < 10; i++) {
4361                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4362                     BWN_DMA32_RXSTATUS;
4363                 value = BWN_READ_4(mac, base + offset);
4364                 if (type == BWN_DMA_64BIT) {
4365                         value &= BWN_DMA64_RXSTAT;
4366                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4367                                 i = -1;
4368                                 break;
4369                         }
4370                 } else {
4371                         value &= BWN_DMA32_RXSTATE;
4372                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4373                                 i = -1;
4374                                 break;
4375                         }
4376                 }
4377                 DELAY(1000);
4378         }
4379         if (i != -1) {
4380                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4381                 return (ENODEV);
4382         }
4383
4384         return (0);
4385 }
4386
4387 static void
4388 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4389     struct bwn_dmadesc_meta *meta)
4390 {
4391
4392         if (meta->mt_m != NULL) {
4393                 m_freem(meta->mt_m);
4394                 meta->mt_m = NULL;
4395         }
4396         if (meta->mt_ni != NULL) {
4397                 ieee80211_free_node(meta->mt_ni);
4398                 meta->mt_ni = NULL;
4399         }
4400 }
4401
4402 static void
4403 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4404 {
4405         struct bwn_rxhdr4 *rxhdr;
4406         unsigned char *frame;
4407
4408         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4409         rxhdr->frame_len = 0;
4410
4411         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4412             sizeof(struct bwn_plcp6) + 2,
4413             ("%s:%d: fail", __func__, __LINE__));
4414         frame = mtod(m, char *) + dr->dr_frameoffset;
4415         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4416 }
4417
4418 static uint8_t
4419 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4420 {
4421         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4422
4423         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4424             == 0xff);
4425 }
4426
4427 static void
4428 bwn_wme_init(struct bwn_mac *mac)
4429 {
4430
4431         bwn_wme_load(mac);
4432
4433         /* enable WME support. */
4434         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4435         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4436             BWN_IFSCTL_USE_EDCF);
4437 }
4438
4439 static void
4440 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4441 {
4442         struct bwn_softc *sc = mac->mac_sc;
4443         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4444         uint16_t delay; /* microsec */
4445
4446         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4447         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4448                 delay = 500;
4449         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4450                 delay = max(delay, (uint16_t)2400);
4451
4452         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4453 }
4454
4455 static void
4456 bwn_bt_enable(struct bwn_mac *mac)
4457 {
4458         struct bwn_softc *sc = mac->mac_sc;
4459         uint64_t hf;
4460
4461         if (bwn_bluetooth == 0)
4462                 return;
4463         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4464                 return;
4465         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4466                 return;
4467
4468         hf = bwn_hf_read(mac);
4469         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4470                 hf |= BWN_HF_BT_COEXISTALT;
4471         else
4472                 hf |= BWN_HF_BT_COEXIST;
4473         bwn_hf_write(mac, hf);
4474 }
4475
4476 static void
4477 bwn_set_macaddr(struct bwn_mac *mac)
4478 {
4479
4480         bwn_mac_write_bssid(mac);
4481         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4482 }
4483
4484 static void
4485 bwn_clear_keys(struct bwn_mac *mac)
4486 {
4487         int i;
4488
4489         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4490                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4491                     ("%s:%d: fail", __func__, __LINE__));
4492
4493                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4494                     NULL, BWN_SEC_KEYSIZE, NULL);
4495                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4496                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4497                             NULL, BWN_SEC_KEYSIZE, NULL);
4498                 }
4499                 mac->mac_key[i].keyconf = NULL;
4500         }
4501 }
4502
4503 static void
4504 bwn_crypt_init(struct bwn_mac *mac)
4505 {
4506         struct bwn_softc *sc = mac->mac_sc;
4507
4508         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4509         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4510             ("%s:%d: fail", __func__, __LINE__));
4511         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4512         mac->mac_ktp *= 2;
4513         if (siba_get_revid(sc->sc_dev) >= 5)
4514                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4515         bwn_clear_keys(mac);
4516 }
4517
4518 static void
4519 bwn_chip_exit(struct bwn_mac *mac)
4520 {
4521         struct bwn_softc *sc = mac->mac_sc;
4522
4523         bwn_phy_exit(mac);
4524         siba_gpio_set(sc->sc_dev, 0);
4525 }
4526
4527 static int
4528 bwn_fw_fillinfo(struct bwn_mac *mac)
4529 {
4530         int error;
4531
4532         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4533         if (error == 0)
4534                 return (0);
4535         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4536         if (error == 0)
4537                 return (0);
4538         return (error);
4539 }
4540
4541 static int
4542 bwn_gpio_init(struct bwn_mac *mac)
4543 {
4544         struct bwn_softc *sc = mac->mac_sc;
4545         uint32_t mask = 0x1f, set = 0xf, value;
4546
4547         BWN_WRITE_4(mac, BWN_MACCTL,
4548             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4549         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4550             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4551
4552         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4553                 mask |= 0x0060;
4554                 set |= 0x0060;
4555         }
4556         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4557                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4558                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4559                 mask |= 0x0200;
4560                 set |= 0x0200;
4561         }
4562         if (siba_get_revid(sc->sc_dev) >= 2)
4563                 mask |= 0x0010;
4564
4565         value = siba_gpio_get(sc->sc_dev);
4566         if (value == -1)
4567                 return (0);
4568         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4569
4570         return (0);
4571 }
4572
4573 static int
4574 bwn_fw_loadinitvals(struct bwn_mac *mac)
4575 {
4576 #define GETFWOFFSET(fwp, offset)                                \
4577         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4578         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4579         const struct bwn_fwhdr *hdr;
4580         struct bwn_fw *fw = &mac->mac_fw;
4581         int error;
4582
4583         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4584         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4585             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4586         if (error)
4587                 return (error);
4588         if (fw->initvals_band.fw) {
4589                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4590                 error = bwn_fwinitvals_write(mac,
4591                     GETFWOFFSET(fw->initvals_band, hdr_len),
4592                     be32toh(hdr->size),
4593                     fw->initvals_band.fw->datasize - hdr_len);
4594         }
4595         return (error);
4596 #undef GETFWOFFSET
4597 }
4598
4599 static int
4600 bwn_phy_init(struct bwn_mac *mac)
4601 {
4602         struct bwn_softc *sc = mac->mac_sc;
4603         int error;
4604
4605         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4606         mac->mac_phy.rf_onoff(mac, 1);
4607         error = mac->mac_phy.init(mac);
4608         if (error) {
4609                 device_printf(sc->sc_dev, "PHY init failed\n");
4610                 goto fail0;
4611         }
4612         error = bwn_switch_channel(mac,
4613             mac->mac_phy.get_default_chan(mac));
4614         if (error) {
4615                 device_printf(sc->sc_dev,
4616                     "failed to switch default channel\n");
4617                 goto fail1;
4618         }
4619         return (0);
4620 fail1:
4621         if (mac->mac_phy.exit)
4622                 mac->mac_phy.exit(mac);
4623 fail0:
4624         mac->mac_phy.rf_onoff(mac, 0);
4625
4626         return (error);
4627 }
4628
4629 static void
4630 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4631 {
4632         uint16_t ant;
4633         uint16_t tmp;
4634
4635         ant = bwn_ant2phy(antenna);
4636
4637         /* For ACK/CTS */
4638         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4639         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4640         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4641         /* For Probe Resposes */
4642         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4643         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4644         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4645 }
4646
4647 static void
4648 bwn_set_opmode(struct bwn_mac *mac)
4649 {
4650         struct bwn_softc *sc = mac->mac_sc;
4651         struct ifnet *ifp = sc->sc_ifp;
4652         struct ieee80211com *ic = ifp->if_l2com;
4653         uint32_t ctl;
4654         uint16_t cfp_pretbtt;
4655
4656         ctl = BWN_READ_4(mac, BWN_MACCTL);
4657         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4658             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4659             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4660         ctl |= BWN_MACCTL_STA;
4661
4662         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4663             ic->ic_opmode == IEEE80211_M_MBSS)
4664                 ctl |= BWN_MACCTL_HOSTAP;
4665         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4666                 ctl &= ~BWN_MACCTL_STA;
4667         ctl |= sc->sc_filters;
4668
4669         if (siba_get_revid(sc->sc_dev) <= 4)
4670                 ctl |= BWN_MACCTL_PROMISC;
4671
4672         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4673
4674         cfp_pretbtt = 2;
4675         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4676                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4677                     siba_get_chiprev(sc->sc_dev) == 3)
4678                         cfp_pretbtt = 100;
4679                 else
4680                         cfp_pretbtt = 50;
4681         }
4682         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4683 }
4684
4685 static int
4686 bwn_dma_gettype(struct bwn_mac *mac)
4687 {
4688         uint32_t tmp;
4689         uint16_t base;
4690
4691         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4692         if (tmp & SIBA_TGSHIGH_DMA64)
4693                 return (BWN_DMA_64BIT);
4694         base = bwn_dma_base(0, 0);
4695         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4696         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4697         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4698                 return (BWN_DMA_32BIT);
4699
4700         return (BWN_DMA_30BIT);
4701 }
4702
4703 static void
4704 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4705 {
4706         if (!error) {
4707                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4708                 *((bus_addr_t *)arg) = seg->ds_addr;
4709         }
4710 }
4711
4712 static void
4713 bwn_phy_g_init_sub(struct bwn_mac *mac)
4714 {
4715         struct bwn_phy *phy = &mac->mac_phy;
4716         struct bwn_phy_g *pg = &phy->phy_g;
4717         struct bwn_softc *sc = mac->mac_sc;
4718         uint16_t i, tmp;
4719
4720         if (phy->rev == 1)
4721                 bwn_phy_init_b5(mac);
4722         else
4723                 bwn_phy_init_b6(mac);
4724
4725         if (phy->rev >= 2 || phy->gmode)
4726                 bwn_phy_init_a(mac);
4727
4728         if (phy->rev >= 2) {
4729                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4730                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4731         }
4732         if (phy->rev == 2) {
4733                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4734                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4735         }
4736         if (phy->rev > 5) {
4737                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4738                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4739         }
4740         if (phy->gmode || phy->rev >= 2) {
4741                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4742                 tmp &= BWN_PHYVER_VERSION;
4743                 if (tmp == 3 || tmp == 5) {
4744                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4745                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4746                 }
4747                 if (tmp == 5) {
4748                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4749                             0x1f00);
4750                 }
4751         }
4752         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4753                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4754         if (phy->rf_rev == 8) {
4755                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4756                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4757         }
4758         if (BWN_HAS_LOOPBACK(phy))
4759                 bwn_loopback_calcgain(mac);
4760
4761         if (phy->rf_rev != 8) {
4762                 if (pg->pg_initval == 0xffff)
4763                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4764                 else
4765                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4766         }
4767         bwn_lo_g_init(mac);
4768         if (BWN_HAS_TXMAG(phy)) {
4769                 BWN_RF_WRITE(mac, 0x52,
4770                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4771                     | pg->pg_loctl.tx_bias |
4772                     pg->pg_loctl.tx_magn);
4773         } else {
4774                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4775         }
4776         if (phy->rev >= 6) {
4777                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4778                     (pg->pg_loctl.tx_bias << 12));
4779         }
4780         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4781                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4782         else
4783                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4784         if (phy->rev < 2)
4785                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4786         else
4787                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4788         if (phy->gmode || phy->rev >= 2) {
4789                 bwn_lo_g_adjust(mac);
4790                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4791         }
4792
4793         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4794                 for (i = 0; i < 64; i++) {
4795                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4796                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4797                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4798                             -32), 31));
4799                 }
4800                 bwn_nrssi_threshold(mac);
4801         } else if (phy->gmode || phy->rev >= 2) {
4802                 if (pg->pg_nrssi[0] == -1000) {
4803                         KASSERT(pg->pg_nrssi[1] == -1000,
4804                             ("%s:%d: fail", __func__, __LINE__));
4805                         bwn_nrssi_slope_11g(mac);
4806                 } else
4807                         bwn_nrssi_threshold(mac);
4808         }
4809         if (phy->rf_rev == 8)
4810                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4811         bwn_phy_hwpctl_init(mac);
4812         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4813              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4814                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4815                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4816         }
4817 }
4818
4819 static uint8_t
4820 bwn_has_hwpctl(struct bwn_mac *mac)
4821 {
4822
4823         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4824                 return (0);
4825         return (mac->mac_phy.use_hwpctl(mac));
4826 }
4827
4828 static void
4829 bwn_phy_init_b5(struct bwn_mac *mac)
4830 {
4831         struct bwn_phy *phy = &mac->mac_phy;
4832         struct bwn_phy_g *pg = &phy->phy_g;
4833         struct bwn_softc *sc = mac->mac_sc;
4834         uint16_t offset, value;
4835         uint8_t old_channel;
4836
4837         if (phy->analog == 1)
4838                 BWN_RF_SET(mac, 0x007a, 0x0050);
4839         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4840             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4841                 value = 0x2120;
4842                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4843                         BWN_PHY_WRITE(mac, offset, value);
4844                         value += 0x202;
4845                 }
4846         }
4847         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4848         if (phy->rf_ver == 0x2050)
4849                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4850
4851         if (phy->gmode || phy->rev >= 2) {
4852                 if (phy->rf_ver == 0x2050) {
4853                         BWN_RF_SET(mac, 0x007a, 0x0020);
4854                         BWN_RF_SET(mac, 0x0051, 0x0004);
4855                 }
4856                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4857
4858                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4859                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4860
4861                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4862
4863                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4864                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4865                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4866         }
4867
4868         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4869                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4870
4871         if (phy->analog == 1) {
4872                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4873                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4874                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4875                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4876                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4877         } else
4878                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4879         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4880         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4881
4882         if (phy->analog == 1)
4883                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4884         else
4885                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4886
4887         if (phy->analog == 0)
4888                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4889
4890         old_channel = phy->chan;
4891         bwn_phy_g_switch_chan(mac, 7, 0);
4892
4893         if (phy->rf_ver != 0x2050) {
4894                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4895                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4896         }
4897
4898         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4899         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4900
4901         if (phy->rf_ver == 0x2050) {
4902                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4903                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4904         }
4905
4906         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4907         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4908         BWN_RF_SET(mac, 0x007a, 0x0007);
4909
4910         bwn_phy_g_switch_chan(mac, old_channel, 0);
4911         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4912         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4913         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4914
4915         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4916             pg->pg_txctl);
4917
4918         if (phy->rf_ver == 0x2050)
4919                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4920
4921         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4922 }
4923
4924 static void
4925 bwn_loopback_calcgain(struct bwn_mac *mac)
4926 {
4927         struct bwn_phy *phy = &mac->mac_phy;
4928         struct bwn_phy_g *pg = &phy->phy_g;
4929         struct bwn_softc *sc = mac->mac_sc;
4930         uint16_t backup_phy[16] = { 0 };
4931         uint16_t backup_radio[3];
4932         uint16_t backup_bband;
4933         uint16_t i, j, loop_i_max;
4934         uint16_t trsw_rx;
4935         uint16_t loop1_outer_done, loop1_inner_done;
4936
4937         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4938         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4939         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4940         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4941         if (phy->rev != 1) {
4942                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4943                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4944         }
4945         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4946         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4947         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4948         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4949         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4950         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4951         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4952         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4953         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4954         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4955         backup_bband = pg->pg_bbatt.att;
4956         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4957         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4958         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4959
4960         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4961         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4962         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4963         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4964         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4965         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4966         if (phy->rev != 1) {
4967                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4968                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4969                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4970                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4971         }
4972         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4973         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4974         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4975         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4976
4977         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4978         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4979         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4980
4981         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4982         if (phy->rev != 1) {
4983                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4984                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4985         }
4986         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4987
4988         if (phy->rf_rev == 8)
4989                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4990         else {
4991                 BWN_RF_WRITE(mac, 0x52, 0);
4992                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4993         }
4994         bwn_phy_g_set_bbatt(mac, 11);
4995
4996         if (phy->rev >= 3)
4997                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4998         else
4999                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5000         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5001
5002         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5003         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5004
5005         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5006         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5007
5008         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5009                 if (phy->rev >= 7) {
5010                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5011                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5012                 }
5013         }
5014         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5015
5016         j = 0;
5017         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5018         for (i = 0; i < loop_i_max; i++) {
5019                 for (j = 0; j < 16; j++) {
5020                         BWN_RF_WRITE(mac, 0x43, i);
5021                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5022                             (j << 8));
5023                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5024                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5025                         DELAY(20);
5026                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5027                                 goto done0;
5028                 }
5029         }
5030 done0:
5031         loop1_outer_done = i;
5032         loop1_inner_done = j;
5033         if (j >= 8) {
5034                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5035                 trsw_rx = 0x1b;
5036                 for (j = j - 8; j < 16; j++) {
5037                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5038                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5039                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5040                         DELAY(20);
5041                         trsw_rx -= 3;
5042                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5043                                 goto done1;
5044                 }
5045         } else
5046                 trsw_rx = 0x18;
5047 done1:
5048
5049         if (phy->rev != 1) {
5050                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5051                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5052         }
5053         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5054         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5055         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5056         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5057         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5058         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5059         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5060         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5061         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5062
5063         bwn_phy_g_set_bbatt(mac, backup_bband);
5064
5065         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5066         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5067         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5068
5069         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5070         DELAY(10);
5071         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5072         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5073         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5074         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5075
5076         pg->pg_max_lb_gain =
5077             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5078         pg->pg_trsw_rx_gain = trsw_rx * 2;
5079 }
5080
5081 static uint16_t
5082 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5083 {
5084         struct bwn_phy *phy = &mac->mac_phy;
5085         uint32_t tmp1 = 0, tmp2 = 0;
5086         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5087             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5088             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5089         static const uint8_t rcc_table[] = {
5090                 0x02, 0x03, 0x01, 0x0f,
5091                 0x06, 0x07, 0x05, 0x0f,
5092                 0x0a, 0x0b, 0x09, 0x0f,
5093                 0x0e, 0x0f, 0x0d, 0x0f,
5094         };
5095
5096         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5097             rfoverval = rfover = cck3 = 0;
5098         radio0 = BWN_RF_READ(mac, 0x43);
5099         radio1 = BWN_RF_READ(mac, 0x51);
5100         radio2 = BWN_RF_READ(mac, 0x52);
5101         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5102         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5103         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5104         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5105
5106         if (phy->type == BWN_PHYTYPE_B) {
5107                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5108                 reg0 = BWN_READ_2(mac, 0x3ec);
5109
5110                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5111                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5112         } else if (phy->gmode || phy->rev >= 2) {
5113                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5114                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5115                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5116                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5117                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5118                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5119
5120                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5121                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5122                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5123                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5124                 if (BWN_HAS_LOOPBACK(phy)) {
5125                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5126                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5127                         if (phy->rev >= 3)
5128                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5129                         else
5130                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5131                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5132                 }
5133
5134                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5135                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5136                         BWN_LPD(0, 1, 1)));
5137                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5138                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5139         }
5140         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5141
5142         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5143         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5144         reg1 = BWN_READ_2(mac, 0x3e6);
5145         reg2 = BWN_READ_2(mac, 0x3f4);
5146
5147         if (phy->analog == 0)
5148                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5149         else {
5150                 if (phy->analog >= 2)
5151                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5152                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5153                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5154         }
5155
5156         reg = BWN_RF_READ(mac, 0x60);
5157         index = (reg & 0x001e) >> 1;
5158         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5159
5160         if (phy->type == BWN_PHYTYPE_B)
5161                 BWN_RF_WRITE(mac, 0x78, 0x26);
5162         if (phy->gmode || phy->rev >= 2) {
5163                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5164                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5165                         BWN_LPD(0, 1, 1)));
5166         }
5167         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5168         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5169         if (phy->gmode || phy->rev >= 2) {
5170                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5171                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5172                         BWN_LPD(0, 0, 1)));
5173         }
5174         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5175         BWN_RF_SET(mac, 0x51, 0x0004);
5176         if (phy->rf_rev == 8)
5177                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5178         else {
5179                 BWN_RF_WRITE(mac, 0x52, 0);
5180                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5181         }
5182         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5183
5184         for (i = 0; i < 16; i++) {
5185                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5186                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5187                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5188                 if (phy->gmode || phy->rev >= 2) {
5189                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5190                             bwn_rf_2050_rfoverval(mac,
5191                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5192                 }
5193                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5194                 DELAY(10);
5195                 if (phy->gmode || phy->rev >= 2) {
5196                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5197                             bwn_rf_2050_rfoverval(mac,
5198                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5199                 }
5200                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5201                 DELAY(10);
5202                 if (phy->gmode || phy->rev >= 2) {
5203                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5204                             bwn_rf_2050_rfoverval(mac,
5205                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5206                 }
5207                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5208                 DELAY(20);
5209                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5210                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5211                 if (phy->gmode || phy->rev >= 2) {
5212                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5213                             bwn_rf_2050_rfoverval(mac,
5214                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5215                 }
5216                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5217         }
5218         DELAY(10);
5219
5220         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5221         tmp1++;
5222         tmp1 >>= 9;
5223
5224         for (i = 0; i < 16; i++) {
5225                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5226                 BWN_RF_WRITE(mac, 0x78, radio78);
5227                 DELAY(10);
5228                 for (j = 0; j < 16; j++) {
5229                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5230                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5231                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5232                         if (phy->gmode || phy->rev >= 2) {
5233                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5234                                     bwn_rf_2050_rfoverval(mac,
5235                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5236                         }
5237                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5238                         DELAY(10);
5239                         if (phy->gmode || phy->rev >= 2) {
5240                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5241                                     bwn_rf_2050_rfoverval(mac,
5242                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5243                         }
5244                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5245                         DELAY(10);
5246                         if (phy->gmode || phy->rev >= 2) {
5247                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5248                                     bwn_rf_2050_rfoverval(mac,
5249                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5250                         }
5251                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5252                         DELAY(10);
5253                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5254                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5255                         if (phy->gmode || phy->rev >= 2) {
5256                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5257                                     bwn_rf_2050_rfoverval(mac,
5258                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5259                         }
5260                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5261                 }
5262                 tmp2++;
5263                 tmp2 >>= 8;
5264                 if (tmp1 < tmp2)
5265                         break;
5266         }
5267
5268         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5269         BWN_RF_WRITE(mac, 0x51, radio1);
5270         BWN_RF_WRITE(mac, 0x52, radio2);
5271         BWN_RF_WRITE(mac, 0x43, radio0);
5272         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5273         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5274         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5275         BWN_WRITE_2(mac, 0x3e6, reg1);
5276         if (phy->analog != 0)
5277                 BWN_WRITE_2(mac, 0x3f4, reg2);
5278         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5279         bwn_spu_workaround(mac, phy->chan);
5280         if (phy->type == BWN_PHYTYPE_B) {
5281                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5282                 BWN_WRITE_2(mac, 0x3ec, reg0);
5283         } else if (phy->gmode) {
5284                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5285                             BWN_READ_2(mac, BWN_PHY_RADIO)
5286                             & 0x7fff);
5287                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5288                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5289                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5290                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5291                               analogoverval);
5292                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5293                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5294                 if (BWN_HAS_LOOPBACK(phy)) {
5295                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5296                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5297                 }
5298         }
5299
5300         return ((i > 15) ? radio78 : rcc);
5301 }
5302
5303 static void
5304 bwn_phy_init_b6(struct bwn_mac *mac)
5305 {
5306         struct bwn_phy *phy = &mac->mac_phy;
5307         struct bwn_phy_g *pg = &phy->phy_g;
5308         struct bwn_softc *sc = mac->mac_sc;
5309         uint16_t offset, val;
5310         uint8_t old_channel;
5311
5312         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5313             ("%s:%d: fail", __func__, __LINE__));
5314
5315         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5316         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5317         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5318                 BWN_RF_WRITE(mac, 0x51, 0x37);
5319                 BWN_RF_WRITE(mac, 0x52, 0x70);
5320                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5321                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5322                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5323                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5324                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5325                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5326                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5327                 bwn_hf_write(mac,
5328                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5329         }
5330         if (phy->rf_rev == 8) {
5331                 BWN_RF_WRITE(mac, 0x51, 0);
5332                 BWN_RF_WRITE(mac, 0x52, 0x40);
5333                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5334                 BWN_RF_WRITE(mac, 0x54, 0x98);
5335                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5336                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5337                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5338                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5339                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5340                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5341                 } else {
5342                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5343                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5344                 }
5345                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5346                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5347                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5348                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5349         }
5350         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5351                 BWN_PHY_WRITE(mac, offset, val);
5352                 val -= 0x0202;
5353         }
5354         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5355                 BWN_PHY_WRITE(mac, offset, val);
5356                 val -= 0x0202;
5357         }
5358         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5359                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5360                 val += 0x0202;
5361         }
5362         if (phy->type == BWN_PHYTYPE_G) {
5363                 BWN_RF_SET(mac, 0x007a, 0x0020);
5364                 BWN_RF_SET(mac, 0x0051, 0x0004);
5365                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5366                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5367                 BWN_PHY_WRITE(mac, 0x5b, 0);
5368                 BWN_PHY_WRITE(mac, 0x5c, 0);
5369         }
5370
5371         old_channel = phy->chan;
5372         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5373
5374         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5375         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5376         DELAY(40);
5377         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5378                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5379                 BWN_RF_WRITE(mac, 0x50, 0x20);
5380         }
5381         if (phy->rf_rev <= 2) {
5382                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5383                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5384                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5385                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5386         }
5387         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5388
5389         bwn_phy_g_switch_chan(mac, old_channel, 0);
5390
5391         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5392         if (phy->rf_rev >= 6)
5393                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5394         else
5395                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5396         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5397         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5398             pg->pg_txctl);
5399         if (phy->rf_rev <= 5)
5400                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5401         if (phy->rf_rev <= 2)
5402                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5403
5404         if (phy->analog == 4) {
5405                 BWN_WRITE_2(mac, 0x3e4, 9);
5406                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5407         } else
5408                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5409         if (phy->type == BWN_PHYTYPE_B)
5410                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5411         else if (phy->type == BWN_PHYTYPE_G)
5412                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5413 }
5414
5415 static void
5416 bwn_phy_init_a(struct bwn_mac *mac)
5417 {
5418         struct bwn_phy *phy = &mac->mac_phy;
5419         struct bwn_softc *sc = mac->mac_sc;
5420
5421         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5422             ("%s:%d: fail", __func__, __LINE__));
5423
5424         if (phy->rev >= 6) {
5425                 if (phy->type == BWN_PHYTYPE_A)
5426                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5427                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5428                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5429                 else
5430                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5431         }
5432
5433         bwn_wa_init(mac);
5434
5435         if (phy->type == BWN_PHYTYPE_G &&
5436             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5437                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5438 }
5439
5440 static void
5441 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5442 {
5443         int i;
5444
5445         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5446                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5447 }
5448
5449 static void
5450 bwn_wa_agc(struct bwn_mac *mac)
5451 {
5452         struct bwn_phy *phy = &mac->mac_phy;
5453
5454         if (phy->rev == 1) {
5455                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5456                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5457                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5458                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5460                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5461                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5462                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5463                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5464         } else {
5465                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5466                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5467                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5468                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5469         }
5470
5471         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5472             0x5700);
5473         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5474         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5475         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5476         BWN_RF_SET(mac, 0x7a, 0x0008);
5477         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5478         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5479         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5480         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5481         if (phy->rev == 1)
5482                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5483         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5484         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5485         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5486         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5487         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5488         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5491         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5492         if (phy->rev == 1) {
5493                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5494                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5495         } else {
5496                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5497                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5498                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5499                 if (phy->rev >= 6) {
5500                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5501                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5502                             (uint16_t)~0xf000, 0x3000);
5503                 }
5504         }
5505         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5506         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5507         if (phy->rev == 1) {
5508                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5509                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5510                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5511                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5512                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5513                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5514                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5515                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5516         } else {
5517                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5518                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5519                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5520                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5521         }
5522         if (phy->rev >= 6) {
5523                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5524                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5525         }
5526         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5527 }
5528
5529 static void
5530 bwn_wa_grev1(struct bwn_mac *mac)
5531 {
5532         struct bwn_phy *phy = &mac->mac_phy;
5533         int i;
5534         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5535         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5536         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5537
5538         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5539
5540         /* init CRSTHRES and ANTDWELL */
5541         if (phy->rev == 1) {
5542                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5543         } else if (phy->rev == 2) {
5544                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5545                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5546                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5547         } else {
5548                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5549                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5550                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5551                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5552         }
5553         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5554         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5555         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5556
5557         /* XXX support PHY-A??? */
5558         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5559                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5560                     bwn_tab_finefreqg[i]);
5561
5562         /* XXX support PHY-A??? */
5563         if (phy->rev == 1)
5564                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5565                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5566                             bwn_tab_noise_g1[i]);
5567         else
5568                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5569                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5570                             bwn_tab_noise_g2[i]);
5571
5572
5573         for (i = 0; i < N(bwn_tab_rotor); i++)
5574                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5575                     bwn_tab_rotor[i]);
5576
5577         /* XXX support PHY-A??? */
5578         if (phy->rev >= 6) {
5579                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5580                     BWN_PHY_ENCORE_EN)
5581                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5582                 else
5583                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5584         } else
5585                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5586
5587         for (i = 0; i < N(bwn_tab_retard); i++)
5588                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5589                     bwn_tab_retard[i]);
5590
5591         if (phy->rev == 1) {
5592                 for (i = 0; i < 16; i++)
5593                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5594                             i, 0x0020);
5595         } else {
5596                 for (i = 0; i < 32; i++)
5597                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5598         }
5599
5600         bwn_wa_agc(mac);
5601 }
5602
5603 static void
5604 bwn_wa_grev26789(struct bwn_mac *mac)
5605 {
5606         struct bwn_phy *phy = &mac->mac_phy;
5607         int i;
5608         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5609         uint16_t ofdmrev;
5610
5611         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5612
5613         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5614
5615         /* init CRSTHRES and ANTDWELL */
5616         if (phy->rev == 1)
5617                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5618         else if (phy->rev == 2) {
5619                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5620                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5621                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5622         } else {
5623                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5624                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5625                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5626                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5627         }
5628
5629         for (i = 0; i < 64; i++)
5630                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5631
5632         /* XXX support PHY-A??? */
5633         if (phy->rev == 1)
5634                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5635                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5636                             bwn_tab_noise_g1[i]);
5637         else
5638                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5639                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5640                             bwn_tab_noise_g2[i]);
5641
5642         /* XXX support PHY-A??? */
5643         if (phy->rev >= 6) {
5644                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5645                     BWN_PHY_ENCORE_EN)
5646                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5647                 else
5648                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5649         } else
5650                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5651
5652         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5653                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5654                     bwn_tab_sigmasqr2[i]);
5655
5656         if (phy->rev == 1) {
5657                 for (i = 0; i < 16; i++)
5658                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5659                             0x0020);
5660         } else {
5661                 for (i = 0; i < 32; i++)
5662                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5663         }
5664
5665         bwn_wa_agc(mac);
5666
5667         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5668         if (ofdmrev > 2) {
5669                 if (phy->type == BWN_PHYTYPE_A)
5670                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5671                 else
5672                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5673         } else {
5674                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5675                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5676                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5677         }
5678
5679         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5680         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5681 }
5682
5683 static void
5684 bwn_wa_init(struct bwn_mac *mac)
5685 {
5686         struct bwn_phy *phy = &mac->mac_phy;
5687         struct bwn_softc *sc = mac->mac_sc;
5688
5689         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5690
5691         switch (phy->rev) {
5692         case 1:
5693                 bwn_wa_grev1(mac);
5694                 break;
5695         case 2:
5696         case 6:
5697         case 7:
5698         case 8:
5699         case 9:
5700                 bwn_wa_grev26789(mac);
5701                 break;
5702         default:
5703                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5704         }
5705
5706         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5707             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5708             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5709                 if (phy->rev < 2) {
5710                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5711                             0x0002);
5712                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5713                             0x0001);
5714                 } else {
5715                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5716                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5717                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5718                              BWN_BFL_EXTLNA) &&
5719                             (phy->rev >= 7)) {
5720                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5721                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5722                                     0x0020, 0x0001);
5723                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5724                                     0x0021, 0x0001);
5725                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5726                                     0x0022, 0x0001);
5727                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5728                                     0x0023, 0x0000);
5729                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5730                                     0x0000, 0x0000);
5731                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5732                                     0x0003, 0x0002);
5733                         }
5734                 }
5735         }
5736         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5737                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5738                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5739         }
5740
5741         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5742         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5743 }
5744
5745 static void
5746 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5747     uint16_t value)
5748 {
5749         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5750         uint16_t addr;
5751
5752         addr = table + offset;
5753         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5754             (addr - 1 != pg->pg_ofdmtab_addr)) {
5755                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5756                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5757         }
5758         pg->pg_ofdmtab_addr = addr;
5759         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5760 }
5761
5762 static void
5763 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5764     uint32_t value)
5765 {
5766         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5767         uint16_t addr;
5768
5769         addr = table + offset;
5770         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5771             (addr - 1 != pg->pg_ofdmtab_addr)) {
5772                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5773                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5774         }
5775         pg->pg_ofdmtab_addr = addr;
5776
5777         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5778         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5779 }
5780
5781 static void
5782 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5783     uint16_t value)
5784 {
5785
5786         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5787         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5788 }
5789
5790 static void
5791 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5792 {
5793         struct bwn_phy *phy = &mac->mac_phy;
5794         struct bwn_softc *sc = mac->mac_sc;
5795         unsigned int i, max_loop;
5796         uint16_t value;
5797         uint32_t buffer[5] = {
5798                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5799         };
5800
5801         if (ofdm) {
5802                 max_loop = 0x1e;
5803                 buffer[0] = 0x000201cc;
5804         } else {
5805                 max_loop = 0xfa;
5806                 buffer[0] = 0x000b846e;
5807         }
5808
5809         BWN_ASSERT_LOCKED(mac->mac_sc);
5810
5811         for (i = 0; i < 5; i++)
5812                 bwn_ram_write(mac, i * 4, buffer[i]);
5813
5814         BWN_WRITE_2(mac, 0x0568, 0x0000);
5815         BWN_WRITE_2(mac, 0x07c0,
5816             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5817         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5818         BWN_WRITE_2(mac, 0x050c, value);
5819         if (phy->type == BWN_PHYTYPE_LP)
5820                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5821         BWN_WRITE_2(mac, 0x0508, 0x0000);
5822         BWN_WRITE_2(mac, 0x050a, 0x0000);
5823         BWN_WRITE_2(mac, 0x054c, 0x0000);
5824         BWN_WRITE_2(mac, 0x056a, 0x0014);
5825         BWN_WRITE_2(mac, 0x0568, 0x0826);
5826         BWN_WRITE_2(mac, 0x0500, 0x0000);
5827         if (phy->type == BWN_PHYTYPE_LP)
5828                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5829         else
5830                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5831
5832         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5833                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5834         for (i = 0x00; i < max_loop; i++) {
5835                 value = BWN_READ_2(mac, 0x050e);
5836                 if (value & 0x0080)
5837                         break;
5838                 DELAY(10);
5839         }
5840         for (i = 0x00; i < 0x0a; i++) {
5841                 value = BWN_READ_2(mac, 0x050e);
5842                 if (value & 0x0400)
5843                         break;
5844                 DELAY(10);
5845         }
5846         for (i = 0x00; i < 0x19; i++) {
5847                 value = BWN_READ_2(mac, 0x0690);
5848                 if (!(value & 0x0100))
5849                         break;
5850                 DELAY(10);
5851         }
5852         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5853                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5854 }
5855
5856 static void
5857 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5858 {
5859         uint32_t macctl;
5860
5861         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5862
5863         macctl = BWN_READ_4(mac, BWN_MACCTL);
5864         if (macctl & BWN_MACCTL_BIGENDIAN)
5865                 printf("TODO: need swap\n");
5866
5867         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5868         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5869         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5870 }
5871
5872 static void
5873 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5874 {
5875         uint16_t value;
5876
5877         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5878             ("%s:%d: fail", __func__, __LINE__));
5879
5880         value = (uint8_t) (ctl->q);
5881         value |= ((uint8_t) (ctl->i)) << 8;
5882         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5883 }
5884
5885 static uint16_t
5886 bwn_lo_calcfeed(struct bwn_mac *mac,
5887     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5888 {
5889         struct bwn_phy *phy = &mac->mac_phy;
5890         struct bwn_softc *sc = mac->mac_sc;
5891         uint16_t rfover;
5892         uint16_t feedthrough;
5893
5894         if (phy->gmode) {
5895                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5896                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5897
5898                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5899                     ("%s:%d: fail", __func__, __LINE__));
5900                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5901                     ("%s:%d: fail", __func__, __LINE__));
5902
5903                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5904
5905                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5906                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5907                     phy->rev > 6)
5908                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5909
5910                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5911                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5912                 DELAY(10);
5913                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5914                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5915                 DELAY(10);
5916                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5917                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5918                 DELAY(10);
5919                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5920         } else {
5921                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5922                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5923                 DELAY(10);
5924                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5925                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5926                 DELAY(10);
5927                 pga |= BWN_PHY_PGACTL_LPF;
5928                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5929         }
5930         DELAY(21);
5931         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5932
5933         return (feedthrough);
5934 }
5935
5936 static uint16_t
5937 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5938     uint16_t *value, uint16_t *pad_mix_gain)
5939 {
5940         struct bwn_phy *phy = &mac->mac_phy;
5941         uint16_t reg, v, padmix;
5942
5943         if (phy->type == BWN_PHYTYPE_B) {
5944                 v = 0x30;
5945                 if (phy->rf_rev <= 5) {
5946                         reg = 0x43;
5947                         padmix = 0;
5948                 } else {
5949                         reg = 0x52;
5950                         padmix = 5;
5951                 }
5952         } else {
5953                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5954                         reg = 0x43;
5955                         v = 0x10;
5956                         padmix = 2;
5957                 } else {
5958                         reg = 0x52;
5959                         v = 0x30;
5960                         padmix = 5;
5961                 }
5962         }
5963         if (value)
5964                 *value = v;
5965         if (pad_mix_gain)
5966                 *pad_mix_gain = padmix;
5967
5968         return (reg);
5969 }
5970
5971 static void
5972 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5973 {
5974         struct bwn_phy *phy = &mac->mac_phy;
5975         struct bwn_phy_g *pg = &phy->phy_g;
5976         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5977         uint16_t reg, mask;
5978         uint16_t trsw_rx, pga;
5979         uint16_t rf_pctl_reg;
5980
5981         static const uint8_t tx_bias_values[] = {
5982                 0x09, 0x08, 0x0a, 0x01, 0x00,
5983                 0x02, 0x05, 0x04, 0x06,
5984         };
5985         static const uint8_t tx_magn_values[] = {
5986                 0x70, 0x40,
5987         };
5988
5989         if (!BWN_HAS_LOOPBACK(phy)) {
5990                 rf_pctl_reg = 6;
5991                 trsw_rx = 2;
5992                 pga = 0;
5993         } else {
5994                 int lb_gain;
5995
5996                 trsw_rx = 0;
5997                 lb_gain = pg->pg_max_lb_gain / 2;
5998                 if (lb_gain > 10) {
5999                         rf_pctl_reg = 0;
6000                         pga = abs(10 - lb_gain) / 6;
6001                         pga = MIN(MAX(pga, 0), 15);
6002                 } else {
6003                         int cmp_val;
6004                         int tmp;
6005
6006                         pga = 0;
6007                         cmp_val = 0x24;
6008                         if ((phy->rev >= 2) &&
6009                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6010                                 cmp_val = 0x3c;
6011                         tmp = lb_gain;
6012                         if ((10 - lb_gain) < cmp_val)
6013                                 tmp = (10 - lb_gain);
6014                         if (tmp < 0)
6015                                 tmp += 6;
6016                         else
6017                                 tmp += 3;
6018                         cmp_val /= 4;
6019                         tmp /= 4;
6020                         if (tmp >= cmp_val)
6021                                 rf_pctl_reg = cmp_val;
6022                         else
6023                                 rf_pctl_reg = tmp;
6024                 }
6025         }
6026         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6027         bwn_phy_g_set_bbatt(mac, 2);
6028
6029         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6030         mask = ~mask;
6031         BWN_RF_MASK(mac, reg, mask);
6032
6033         if (BWN_HAS_TXMAG(phy)) {
6034                 int i, j;
6035                 int feedthrough;
6036                 int min_feedth = 0xffff;
6037                 uint8_t tx_magn, tx_bias;
6038
6039                 for (i = 0; i < N(tx_magn_values); i++) {
6040                         tx_magn = tx_magn_values[i];
6041                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6042                         for (j = 0; j < N(tx_bias_values); j++) {
6043                                 tx_bias = tx_bias_values[j];
6044                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6045                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6046                                     trsw_rx);
6047                                 if (feedthrough < min_feedth) {
6048                                         lo->tx_bias = tx_bias;
6049                                         lo->tx_magn = tx_magn;
6050                                         min_feedth = feedthrough;
6051                                 }
6052                                 if (lo->tx_bias == 0)
6053                                         break;
6054                         }
6055                         BWN_RF_WRITE(mac, 0x52,
6056                                           (BWN_RF_READ(mac, 0x52)
6057                                            & 0xff00) | lo->tx_bias | lo->
6058                                           tx_magn);
6059                 }
6060         } else {
6061                 lo->tx_magn = 0;
6062                 lo->tx_bias = 0;
6063                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6064         }
6065
6066         BWN_GETTIME(lo->txctl_measured_time);
6067 }
6068
6069 static void
6070 bwn_lo_get_powervector(struct bwn_mac *mac)
6071 {
6072         struct bwn_phy *phy = &mac->mac_phy;
6073         struct bwn_phy_g *pg = &phy->phy_g;
6074         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6075         int i;
6076         uint64_t tmp;
6077         uint64_t power_vector = 0;
6078
6079         for (i = 0; i < 8; i += 2) {
6080                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6081                 power_vector |= (tmp << (i * 8));
6082                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6083         }
6084         if (power_vector)
6085                 lo->power_vector = power_vector;
6086
6087         BWN_GETTIME(lo->pwr_vec_read_time);
6088 }
6089
6090 static void
6091 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6092     int use_trsw_rx)
6093 {
6094         struct bwn_phy *phy = &mac->mac_phy;
6095         struct bwn_phy_g *pg = &phy->phy_g;
6096         uint16_t tmp;
6097
6098         if (max_rx_gain < 0)
6099                 max_rx_gain = 0;
6100
6101         if (BWN_HAS_LOOPBACK(phy)) {
6102                 int trsw_rx = 0;
6103                 int trsw_rx_gain;
6104
6105                 if (use_trsw_rx) {
6106                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6107                         if (max_rx_gain >= trsw_rx_gain) {
6108                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6109                                 trsw_rx = 0x20;
6110                         }
6111                 } else
6112                         trsw_rx_gain = max_rx_gain;
6113                 if (trsw_rx_gain < 9) {
6114                         pg->pg_lna_lod_gain = 0;
6115                 } else {
6116                         pg->pg_lna_lod_gain = 1;
6117                         trsw_rx_gain -= 8;
6118                 }
6119                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6120                 pg->pg_pga_gain = trsw_rx_gain / 3;
6121                 if (pg->pg_pga_gain >= 5) {
6122                         pg->pg_pga_gain -= 5;
6123                         pg->pg_lna_gain = 2;
6124                 } else
6125                         pg->pg_lna_gain = 0;
6126         } else {
6127                 pg->pg_lna_gain = 0;
6128                 pg->pg_trsw_rx_gain = 0x20;
6129                 if (max_rx_gain >= 0x14) {
6130                         pg->pg_lna_lod_gain = 1;
6131                         pg->pg_pga_gain = 2;
6132                 } else if (max_rx_gain >= 0x12) {
6133                         pg->pg_lna_lod_gain = 1;
6134                         pg->pg_pga_gain = 1;
6135                 } else if (max_rx_gain >= 0xf) {
6136                         pg->pg_lna_lod_gain = 1;
6137                         pg->pg_pga_gain = 0;
6138                 } else {
6139                         pg->pg_lna_lod_gain = 0;
6140                         pg->pg_pga_gain = 0;
6141                 }
6142         }
6143
6144         tmp = BWN_RF_READ(mac, 0x7a);
6145         if (pg->pg_lna_lod_gain == 0)
6146                 tmp &= ~0x0008;
6147         else
6148                 tmp |= 0x0008;
6149         BWN_RF_WRITE(mac, 0x7a, tmp);
6150 }
6151
6152 static void
6153 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6154 {
6155         struct bwn_phy *phy = &mac->mac_phy;
6156         struct bwn_phy_g *pg = &phy->phy_g;
6157         struct bwn_softc *sc = mac->mac_sc;
6158         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6159         struct timespec ts;
6160         uint16_t tmp;
6161
6162         if (bwn_has_hwpctl(mac)) {
6163                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6164                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6165                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6166                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6167                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6168
6169                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6170                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6171                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6172                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6173         }
6174         if (phy->type == BWN_PHYTYPE_B &&
6175             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6176                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6177                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6178         }
6179         if (phy->rev >= 2) {
6180                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6181                 sav->phy_analogoverval =
6182                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6183                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6184                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6185                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6186                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6187                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6188
6189                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6190                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6191                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6192                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6193                 if (phy->type == BWN_PHYTYPE_G) {
6194                         if ((phy->rev >= 7) &&
6195                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6196                              BWN_BFL_EXTLNA)) {
6197                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6198                         } else {
6199                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6200                         }
6201                 } else {
6202                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6203                 }
6204                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6205         }
6206         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6207         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6208         sav->rf0 = BWN_RF_READ(mac, 0x43);
6209         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6210         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6211         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6212         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6213         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6214
6215         if (!BWN_HAS_TXMAG(phy)) {
6216                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6217                 sav->rf2 &= 0x00f0;
6218         }
6219         if (phy->type == BWN_PHYTYPE_B) {
6220                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6221                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6222                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6223                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6224         } else {
6225                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6226                             | 0x8000);
6227         }
6228         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6229                     & 0xf000);
6230
6231         tmp =
6232             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6233         BWN_PHY_WRITE(mac, tmp, 0x007f);
6234
6235         tmp = sav->phy_syncctl;
6236         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6237         tmp = sav->rf1;
6238         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6239
6240         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6241         if (phy->type == BWN_PHYTYPE_G ||
6242             (phy->type == BWN_PHYTYPE_B &&
6243              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6244                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6245         } else
6246                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6247         if (phy->rev >= 2)
6248                 bwn_dummy_transmission(mac, 0, 1);
6249         bwn_phy_g_switch_chan(mac, 6, 0);
6250         BWN_RF_READ(mac, 0x51);
6251         if (phy->type == BWN_PHYTYPE_G)
6252                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6253
6254         nanouptime(&ts);
6255         if (time_before(lo->txctl_measured_time,
6256             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6257                 bwn_lo_measure_txctl_values(mac);
6258
6259         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6260                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6261         else {
6262                 if (phy->type == BWN_PHYTYPE_B)
6263                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6264                 else
6265                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6266         }
6267 }
6268
6269 static void
6270 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6271 {
6272         struct bwn_phy *phy = &mac->mac_phy;
6273         struct bwn_phy_g *pg = &phy->phy_g;
6274         uint16_t tmp;
6275
6276         if (phy->rev >= 2) {
6277                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6278                 tmp = (pg->pg_pga_gain << 8);
6279                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6280                 DELAY(5);
6281                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6282                 DELAY(2);
6283                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6284         } else {
6285                 tmp = (pg->pg_pga_gain | 0xefa0);
6286                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6287         }
6288         if (phy->type == BWN_PHYTYPE_G) {
6289                 if (phy->rev >= 3)
6290                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6291                 else
6292                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6293                 if (phy->rev >= 2)
6294                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6295                 else
6296                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6297         }
6298         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6299         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6300         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6301         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6302         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6303         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6304         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6305         if (!BWN_HAS_TXMAG(phy)) {
6306                 tmp = sav->rf2;
6307                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6308         }
6309         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6310         if (phy->type == BWN_PHYTYPE_B &&
6311             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6312                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6313                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6314         }
6315         if (phy->rev >= 2) {
6316                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6317                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6318                               sav->phy_analogoverval);
6319                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6320                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6321                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6322                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6323                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6324         }
6325         if (bwn_has_hwpctl(mac)) {
6326                 tmp = (sav->phy_lomask & 0xbfff);
6327                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6328                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6329                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6330                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6331                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6332         }
6333         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6334 }
6335
6336 static int
6337 bwn_lo_probe_loctl(struct bwn_mac *mac,
6338     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6339 {
6340         struct bwn_phy *phy = &mac->mac_phy;
6341         struct bwn_phy_g *pg = &phy->phy_g;
6342         struct bwn_loctl orig, test;
6343         struct bwn_loctl prev = { -100, -100 };
6344         static const struct bwn_loctl modifiers[] = {
6345                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6346                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6347         };
6348         int begin, end, lower = 0, i;
6349         uint16_t feedth;
6350
6351         if (d->curstate == 0) {
6352                 begin = 1;
6353                 end = 8;
6354         } else if (d->curstate % 2 == 0) {
6355                 begin = d->curstate - 1;
6356                 end = d->curstate + 1;
6357         } else {
6358                 begin = d->curstate - 2;
6359                 end = d->curstate + 2;
6360         }
6361         if (begin < 1)
6362                 begin += 8;
6363         if (end > 8)
6364                 end -= 8;
6365
6366         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6367         i = begin;
6368         d->curstate = i;
6369         while (1) {
6370                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6371                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6372                 test.i += modifiers[i - 1].i * d->multipler;
6373                 test.q += modifiers[i - 1].q * d->multipler;
6374                 if ((test.i != prev.i || test.q != prev.q) &&
6375                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6376                         bwn_lo_write(mac, &test);
6377                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6378                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6379                         if (feedth < d->feedth) {
6380                                 memcpy(probe, &test,
6381                                     sizeof(struct bwn_loctl));
6382                                 lower = 1;
6383                                 d->feedth = feedth;
6384                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6385                                         break;
6386                         }
6387                 }
6388                 memcpy(&prev, &test, sizeof(prev));
6389                 if (i == end)
6390                         break;
6391                 if (i == 8)
6392                         i = 1;
6393                 else
6394                         i++;
6395                 d->curstate = i;
6396         }
6397
6398         return (lower);
6399 }
6400
6401 static void
6402 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6403 {
6404         struct bwn_phy *phy = &mac->mac_phy;
6405         struct bwn_phy_g *pg = &phy->phy_g;
6406         struct bwn_lo_g_sm d;
6407         struct bwn_loctl probe;
6408         int lower, repeat, cnt = 0;
6409         uint16_t feedth;
6410
6411         d.nmeasure = 0;
6412         d.multipler = 1;
6413         if (BWN_HAS_LOOPBACK(phy))
6414                 d.multipler = 3;
6415
6416         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6417         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6418
6419         do {
6420                 bwn_lo_write(mac, &d.loctl);
6421                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6422                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6423                 if (feedth < 0x258) {
6424                         if (feedth >= 0x12c)
6425                                 *rxgain += 6;
6426                         else
6427                                 *rxgain += 3;
6428                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6429                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6430                 }
6431                 d.feedth = feedth;
6432                 d.curstate = 0;
6433                 do {
6434                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6435                             ("%s:%d: fail", __func__, __LINE__));
6436                         memcpy(&probe, &d.loctl,
6437                                sizeof(struct bwn_loctl));
6438                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6439                         if (!lower)
6440                                 break;
6441                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6442                                 break;
6443                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6444                         d.nmeasure++;
6445                 } while (d.nmeasure < 24);
6446                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6447
6448                 if (BWN_HAS_LOOPBACK(phy)) {
6449                         if (d.feedth > 0x1194)
6450                                 *rxgain -= 6;
6451                         else if (d.feedth < 0x5dc)
6452                                 *rxgain += 3;
6453                         if (cnt == 0) {
6454                                 if (d.feedth <= 0x5dc) {
6455                                         d.multipler = 1;
6456                                         cnt++;
6457                                 } else
6458                                         d.multipler = 2;
6459                         } else if (cnt == 2)
6460                                 d.multipler = 1;
6461                 }
6462                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6463         } while (++cnt < repeat);
6464 }
6465
6466 static struct bwn_lo_calib *
6467 bwn_lo_calibset(struct bwn_mac *mac,
6468     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6469 {
6470         struct bwn_phy *phy = &mac->mac_phy;
6471         struct bwn_phy_g *pg = &phy->phy_g;
6472         struct bwn_loctl loctl = { 0, 0 };
6473         struct bwn_lo_calib *cal;
6474         struct bwn_lo_g_value sval = { 0 };
6475         int rxgain;
6476         uint16_t pad, reg, value;
6477
6478         sval.old_channel = phy->chan;
6479         bwn_mac_suspend(mac);
6480         bwn_lo_save(mac, &sval);
6481
6482         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6483         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6484         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6485
6486         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6487         if (rfatt->padmix)
6488                 rxgain -= pad;
6489         if (BWN_HAS_LOOPBACK(phy))
6490                 rxgain += pg->pg_max_lb_gain;
6491         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6492         bwn_phy_g_set_bbatt(mac, bbatt->att);
6493         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6494
6495         bwn_lo_restore(mac, &sval);
6496         bwn_mac_enable(mac);
6497
6498         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6499         if (!cal) {
6500                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6501                 return (NULL);
6502         }
6503         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6504         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6505         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6506
6507         BWN_GETTIME(cal->calib_time);
6508
6509         return (cal);
6510 }
6511
6512 static struct bwn_lo_calib *
6513 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6514     const struct bwn_rfatt *rfatt)
6515 {
6516         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6517         struct bwn_lo_calib *c;
6518
6519         TAILQ_FOREACH(c, &lo->calib_list, list) {
6520                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6521                         continue;
6522                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6523                         continue;
6524                 return (c);
6525         }
6526
6527         c = bwn_lo_calibset(mac, bbatt, rfatt);
6528         if (!c)
6529                 return (NULL);
6530         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6531
6532         return (c);
6533 }
6534
6535 static void
6536 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6537 {
6538         struct bwn_phy *phy = &mac->mac_phy;
6539         struct bwn_phy_g *pg = &phy->phy_g;
6540         struct bwn_softc *sc = mac->mac_sc;
6541         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6542         const struct bwn_rfatt *rfatt;
6543         const struct bwn_bbatt *bbatt;
6544         uint64_t pvector;
6545         int i;
6546         int rf_offset, bb_offset;
6547         uint8_t changed = 0;
6548
6549         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6550         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6551             ("%s:%d: fail", __func__, __LINE__));
6552
6553         pvector = lo->power_vector;
6554         if (!update && !pvector)
6555                 return;
6556
6557         bwn_mac_suspend(mac);
6558
6559         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6560                 struct bwn_lo_calib *cal;
6561                 int idx;
6562                 uint16_t val;
6563
6564                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6565                         continue;
6566                 bb_offset = i / lo->rfatt.len;
6567                 rf_offset = i % lo->rfatt.len;
6568                 bbatt = &(lo->bbatt.array[bb_offset]);
6569                 rfatt = &(lo->rfatt.array[rf_offset]);
6570
6571                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6572                 if (!cal) {
6573                         device_printf(sc->sc_dev, "LO: Could not "
6574                             "calibrate DC table entry\n");
6575                         continue;
6576                 }
6577                 val = (uint8_t)(cal->ctl.q);
6578                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6579                 free(cal, M_DEVBUF);
6580
6581                 idx = i / 2;
6582                 if (i % 2)
6583                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6584                             | ((val & 0x00ff) << 8);
6585                 else
6586                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6587                             | (val & 0x00ff);
6588                 changed = 1;
6589         }
6590         if (changed) {
6591                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6592                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6593         }
6594         bwn_mac_enable(mac);
6595 }
6596
6597 static void
6598 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6599 {
6600
6601         if (!rf->padmix)
6602                 return;
6603         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6604                 rf->att = 4;
6605 }
6606
6607 static void
6608 bwn_lo_g_adjust(struct bwn_mac *mac)
6609 {
6610         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6611         struct bwn_lo_calib *cal;
6612         struct bwn_rfatt rf;
6613
6614         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6615         bwn_lo_fixup_rfatt(&rf);
6616
6617         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6618         if (!cal)
6619                 return;
6620         bwn_lo_write(mac, &cal->ctl);
6621 }
6622
6623 static void
6624 bwn_lo_g_init(struct bwn_mac *mac)
6625 {
6626
6627         if (!bwn_has_hwpctl(mac))
6628                 return;
6629
6630         bwn_lo_get_powervector(mac);
6631         bwn_phy_g_dc_lookup_init(mac, 1);
6632 }
6633
6634 static void
6635 bwn_mac_suspend(struct bwn_mac *mac)
6636 {
6637         struct bwn_softc *sc = mac->mac_sc;
6638         int i;
6639         uint32_t tmp;
6640
6641         KASSERT(mac->mac_suspended >= 0,
6642             ("%s:%d: fail", __func__, __LINE__));
6643
6644         if (mac->mac_suspended == 0) {
6645                 bwn_psctl(mac, BWN_PS_AWAKE);
6646                 BWN_WRITE_4(mac, BWN_MACCTL,
6647                             BWN_READ_4(mac, BWN_MACCTL)
6648                             & ~BWN_MACCTL_ON);
6649                 BWN_READ_4(mac, BWN_MACCTL);
6650                 for (i = 35; i; i--) {
6651                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6652                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6653                                 goto out;
6654                         DELAY(10);
6655                 }
6656                 for (i = 40; i; i--) {
6657                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6658                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6659                                 goto out;
6660                         DELAY(1000);
6661                 }
6662                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6663         }
6664 out:
6665         mac->mac_suspended++;
6666 }
6667
6668 static void
6669 bwn_mac_enable(struct bwn_mac *mac)
6670 {
6671         struct bwn_softc *sc = mac->mac_sc;
6672         uint16_t state;
6673
6674         state = bwn_shm_read_2(mac, BWN_SHARED,
6675             BWN_SHARED_UCODESTAT);
6676         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6677             state != BWN_SHARED_UCODESTAT_SLEEP)
6678                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6679
6680         mac->mac_suspended--;
6681         KASSERT(mac->mac_suspended >= 0,
6682             ("%s:%d: fail", __func__, __LINE__));
6683         if (mac->mac_suspended == 0) {
6684                 BWN_WRITE_4(mac, BWN_MACCTL,
6685                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6686                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6687                 BWN_READ_4(mac, BWN_MACCTL);
6688                 BWN_READ_4(mac, BWN_INTR_REASON);
6689                 bwn_psctl(mac, 0);
6690         }
6691 }
6692
6693 static void
6694 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6695 {
6696         struct bwn_softc *sc = mac->mac_sc;
6697         int i;
6698         uint16_t ucstat;
6699
6700         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6701             ("%s:%d: fail", __func__, __LINE__));
6702         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6703             ("%s:%d: fail", __func__, __LINE__));
6704
6705         /* XXX forcibly awake and hwps-off */
6706
6707         BWN_WRITE_4(mac, BWN_MACCTL,
6708             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6709             ~BWN_MACCTL_HWPS);
6710         BWN_READ_4(mac, BWN_MACCTL);
6711         if (siba_get_revid(sc->sc_dev) >= 5) {
6712                 for (i = 0; i < 100; i++) {
6713                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6714                             BWN_SHARED_UCODESTAT);
6715                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6716                                 break;
6717                         DELAY(10);
6718                 }
6719         }
6720 }
6721
6722 static int16_t
6723 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6724 {
6725
6726         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6727         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6728 }
6729
6730 static void
6731 bwn_nrssi_threshold(struct bwn_mac *mac)
6732 {
6733         struct bwn_phy *phy = &mac->mac_phy;
6734         struct bwn_phy_g *pg = &phy->phy_g;
6735         struct bwn_softc *sc = mac->mac_sc;
6736         int32_t a, b;
6737         int16_t tmp16;
6738         uint16_t tmpu16;
6739
6740         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6741
6742         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6743                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6744                         a = 0x13;
6745                         b = 0x12;
6746                 } else {
6747                         a = 0xe;
6748                         b = 0x11;
6749                 }
6750
6751                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6752                 a += (pg->pg_nrssi[0] << 6);
6753                 a += (a < 32) ? 31 : 32;
6754                 a = a >> 6;
6755                 a = MIN(MAX(a, -31), 31);
6756
6757                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6758                 b += (pg->pg_nrssi[0] << 6);
6759                 if (b < 32)
6760                         b += 31;
6761                 else
6762                         b += 32;
6763                 b = b >> 6;
6764                 b = MIN(MAX(b, -31), 31);
6765
6766                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6767                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6768                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6769                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6770                 return;
6771         }
6772
6773         tmp16 = bwn_nrssi_read(mac, 0x20);
6774         if (tmp16 >= 0x20)
6775                 tmp16 -= 0x40;
6776         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6777 }
6778
6779 static void
6780 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6781 {
6782 #define SAVE_RF_MAX             3
6783 #define SAVE_PHY_COMM_MAX       4
6784 #define SAVE_PHY3_MAX           8
6785         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6786                 { 0x7a, 0x52, 0x43 };
6787         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6788                 { 0x15, 0x5a, 0x59, 0x58 };
6789         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6790                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6791                 0x0801, 0x0060, 0x0014, 0x0478
6792         };
6793         struct bwn_phy *phy = &mac->mac_phy;
6794         struct bwn_phy_g *pg = &phy->phy_g;
6795         int32_t i, tmp32, phy3_idx = 0;
6796         uint16_t delta, tmp;
6797         uint16_t save_rf[SAVE_RF_MAX];
6798         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6799         uint16_t save_phy3[SAVE_PHY3_MAX];
6800         uint16_t ant_div, phy0, chan_ex;
6801         int16_t nrssi0, nrssi1;
6802
6803         KASSERT(phy->type == BWN_PHYTYPE_G,
6804             ("%s:%d: fail", __func__, __LINE__));
6805
6806         if (phy->rf_rev >= 9)
6807                 return;
6808         if (phy->rf_rev == 8)
6809                 bwn_nrssi_offset(mac);
6810
6811         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6812         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6813
6814         /*
6815          * Save RF/PHY registers for later restoration
6816          */
6817         ant_div = BWN_READ_2(mac, 0x03e2);
6818         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6819         for (i = 0; i < SAVE_RF_MAX; ++i)
6820                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6821         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6822                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6823
6824         phy0 = BWN_READ_2(mac, BWN_PHY0);
6825         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6826         if (phy->rev >= 3) {
6827                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6828                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6829                 BWN_PHY_WRITE(mac, 0x002e, 0);
6830                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6831                 switch (phy->rev) {
6832                 case 4:
6833                 case 6:
6834                 case 7:
6835                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6836                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6837                         break;
6838                 case 3:
6839                 case 5:
6840                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6841                         break;
6842                 }
6843                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6844                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6845         }
6846         /*
6847          * Calculate nrssi0
6848          */
6849         BWN_RF_SET(mac, 0x007a, 0x0070);
6850         bwn_set_all_gains(mac, 0, 8, 0);
6851         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6852         if (phy->rev >= 2) {
6853                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6854                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6855         }
6856         BWN_RF_SET(mac, 0x007a, 0x0080);
6857         DELAY(20);
6858
6859         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6860         if (nrssi0 >= 0x0020)
6861                 nrssi0 -= 0x0040;
6862
6863         /*
6864          * Calculate nrssi1
6865          */
6866         BWN_RF_MASK(mac, 0x007a, 0x007f);
6867         if (phy->rev >= 2)
6868                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6869
6870         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6871             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6872         BWN_RF_SET(mac, 0x007a, 0x000f);
6873         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6874         if (phy->rev >= 2) {
6875                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6876                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6877         }
6878
6879         bwn_set_all_gains(mac, 3, 0, 1);
6880         if (phy->rf_rev == 8) {
6881                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6882         } else {
6883                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6884                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6885                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6886                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6887         }
6888         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6889         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6890         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6891         DELAY(20);
6892         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6893
6894         /*
6895          * Install calculated narrow RSSI values
6896          */
6897         if (nrssi1 >= 0x0020)
6898                 nrssi1 -= 0x0040;
6899         if (nrssi0 == nrssi1)
6900                 pg->pg_nrssi_slope = 0x00010000;
6901         else
6902                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6903         if (nrssi0 >= -4) {
6904                 pg->pg_nrssi[0] = nrssi1;
6905                 pg->pg_nrssi[1] = nrssi0;
6906         }
6907
6908         /*
6909          * Restore saved RF/PHY registers
6910          */
6911         if (phy->rev >= 3) {
6912                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6913                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6914                             save_phy3[phy3_idx]);
6915                 }
6916         }
6917         if (phy->rev >= 2) {
6918                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6919                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6920         }
6921
6922         for (i = 0; i < SAVE_RF_MAX; ++i)
6923                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6924
6925         BWN_WRITE_2(mac, 0x03e2, ant_div);
6926         BWN_WRITE_2(mac, 0x03e6, phy0);
6927         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6928
6929         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6930                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6931
6932         bwn_spu_workaround(mac, phy->chan);
6933         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6934         bwn_set_original_gains(mac);
6935         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6936         if (phy->rev >= 3) {
6937                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6938                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6939                             save_phy3[phy3_idx]);
6940                 }
6941         }
6942
6943         delta = 0x1f - pg->pg_nrssi[0];
6944         for (i = 0; i < 64; i++) {
6945                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6946                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6947                 pg->pg_nrssi_lt[i] = tmp32;
6948         }
6949
6950         bwn_nrssi_threshold(mac);
6951 #undef SAVE_RF_MAX
6952 #undef SAVE_PHY_COMM_MAX
6953 #undef SAVE_PHY3_MAX
6954 }
6955
6956 static void
6957 bwn_nrssi_offset(struct bwn_mac *mac)
6958 {
6959 #define SAVE_RF_MAX             2
6960 #define SAVE_PHY_COMM_MAX       10
6961 #define SAVE_PHY6_MAX           8
6962         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6963                 { 0x7a, 0x43 };
6964         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6965                 0x0001, 0x0811, 0x0812, 0x0814,
6966                 0x0815, 0x005a, 0x0059, 0x0058,
6967                 0x000a, 0x0003
6968         };
6969         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6970                 0x002e, 0x002f, 0x080f, 0x0810,
6971                 0x0801, 0x0060, 0x0014, 0x0478
6972         };
6973         struct bwn_phy *phy = &mac->mac_phy;
6974         int i, phy6_idx = 0;
6975         uint16_t save_rf[SAVE_RF_MAX];
6976         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6977         uint16_t save_phy6[SAVE_PHY6_MAX];
6978         int16_t nrssi;
6979         uint16_t saved = 0xffff;
6980
6981         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6982                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6983         for (i = 0; i < SAVE_RF_MAX; ++i)
6984                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6985
6986         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6987         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6988         BWN_PHY_SET(mac, 0x0811, 0x000c);
6989         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6990         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6991         if (phy->rev >= 6) {
6992                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6993                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6994
6995                 BWN_PHY_WRITE(mac, 0x002e, 0);
6996                 BWN_PHY_WRITE(mac, 0x002f, 0);
6997                 BWN_PHY_WRITE(mac, 0x080f, 0);
6998                 BWN_PHY_WRITE(mac, 0x0810, 0);
6999                 BWN_PHY_SET(mac, 0x0478, 0x0100);
7000                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7001                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7002                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7003         }
7004         BWN_RF_SET(mac, 0x007a, 0x0070);
7005         BWN_RF_SET(mac, 0x007a, 0x0080);
7006         DELAY(30);
7007
7008         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7009         if (nrssi >= 0x20)
7010                 nrssi -= 0x40;
7011         if (nrssi == 31) {
7012                 for (i = 7; i >= 4; i--) {
7013                         BWN_RF_WRITE(mac, 0x007b, i);
7014                         DELAY(20);
7015                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7016                             0x003f);
7017                         if (nrssi >= 0x20)
7018                                 nrssi -= 0x40;
7019                         if (nrssi < 31 && saved == 0xffff)
7020                                 saved = i;
7021                 }
7022                 if (saved == 0xffff)
7023                         saved = 4;
7024         } else {
7025                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7026                 if (phy->rev != 1) {
7027                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7028                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7029                 }
7030                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7031                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7032                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7033                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7034                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7035                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7036                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7037                 if (phy->rev == 0)
7038                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7039                 else
7040                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7041                 if (phy->rev != 1) {
7042                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7043                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7044                 }
7045                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7046                 BWN_RF_SET(mac, 0x007a, 0x000f);
7047                 bwn_set_all_gains(mac, 3, 0, 1);
7048                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7049                 DELAY(30);
7050                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7051                 if (nrssi >= 0x20)
7052                         nrssi -= 0x40;
7053                 if (nrssi == -32) {
7054                         for (i = 0; i < 4; i++) {
7055                                 BWN_RF_WRITE(mac, 0x007b, i);
7056                                 DELAY(20);
7057                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7058                                     0x047f) >> 8) & 0x003f);
7059                                 if (nrssi >= 0x20)
7060                                         nrssi -= 0x40;
7061                                 if (nrssi > -31 && saved == 0xffff)
7062                                         saved = i;
7063                         }
7064                         if (saved == 0xffff)
7065                                 saved = 3;
7066                 } else
7067                         saved = 0;
7068         }
7069         BWN_RF_WRITE(mac, 0x007b, saved);
7070
7071         /*
7072          * Restore saved RF/PHY registers
7073          */
7074         if (phy->rev >= 6) {
7075                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7076                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7077                             save_phy6[phy6_idx]);
7078                 }
7079         }
7080         if (phy->rev != 1) {
7081                 for (i = 3; i < 5; i++)
7082                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7083                             save_phy_comm[i]);
7084         }
7085         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7086                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7087
7088         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7089                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7090
7091         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7092         BWN_PHY_SET(mac, 0x0429, 0x8000);
7093         bwn_set_original_gains(mac);
7094         if (phy->rev >= 6) {
7095                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7096                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7097                             save_phy6[phy6_idx]);
7098                 }
7099         }
7100
7101         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7102         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7103         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7104 }
7105
7106 static void
7107 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7108     int16_t third)
7109 {
7110         struct bwn_phy *phy = &mac->mac_phy;
7111         uint16_t i;
7112         uint16_t start = 0x08, end = 0x18;
7113         uint16_t tmp;
7114         uint16_t table;
7115
7116         if (phy->rev <= 1) {
7117                 start = 0x10;
7118                 end = 0x20;
7119         }
7120
7121         table = BWN_OFDMTAB_GAINX;
7122         if (phy->rev <= 1)
7123                 table = BWN_OFDMTAB_GAINX_R1;
7124         for (i = 0; i < 4; i++)
7125                 bwn_ofdmtab_write_2(mac, table, i, first);
7126
7127         for (i = start; i < end; i++)
7128                 bwn_ofdmtab_write_2(mac, table, i, second);
7129
7130         if (third != -1) {
7131                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7132                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7133                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7134                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7135         }
7136         bwn_dummy_transmission(mac, 0, 1);
7137 }
7138
7139 static void
7140 bwn_set_original_gains(struct bwn_mac *mac)
7141 {
7142         struct bwn_phy *phy = &mac->mac_phy;
7143         uint16_t i, tmp;
7144         uint16_t table;
7145         uint16_t start = 0x0008, end = 0x0018;
7146
7147         if (phy->rev <= 1) {
7148                 start = 0x0010;
7149                 end = 0x0020;
7150         }
7151
7152         table = BWN_OFDMTAB_GAINX;
7153         if (phy->rev <= 1)
7154                 table = BWN_OFDMTAB_GAINX_R1;
7155         for (i = 0; i < 4; i++) {
7156                 tmp = (i & 0xfffc);
7157                 tmp |= (i & 0x0001) << 1;
7158                 tmp |= (i & 0x0002) >> 1;
7159
7160                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7161         }
7162
7163         for (i = start; i < end; i++)
7164                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7165
7166         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7167         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7168         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7169         bwn_dummy_transmission(mac, 0, 1);
7170 }
7171
7172 static void
7173 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7174 {
7175         struct bwn_phy *phy = &mac->mac_phy;
7176         struct bwn_phy_g *pg = &phy->phy_g;
7177         struct bwn_rfatt old_rfatt, rfatt;
7178         struct bwn_bbatt old_bbatt, bbatt;
7179         struct bwn_softc *sc = mac->mac_sc;
7180         uint8_t old_txctl = 0;
7181
7182         KASSERT(phy->type == BWN_PHYTYPE_G,
7183             ("%s:%d: fail", __func__, __LINE__));
7184
7185         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7186             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7187                 return;
7188
7189         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7190
7191         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7192
7193         if (!phy->gmode)
7194                 return;
7195         bwn_hwpctl_early_init(mac);
7196         if (pg->pg_curtssi == 0) {
7197                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7198                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7199                 } else {
7200                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7201                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7202                         old_txctl = pg->pg_txctl;
7203
7204                         bbatt.att = 11;
7205                         if (phy->rf_rev == 8) {
7206                                 rfatt.att = 15;
7207                                 rfatt.padmix = 1;
7208                         } else {
7209                                 rfatt.att = 9;
7210                                 rfatt.padmix = 0;
7211                         }
7212                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7213                 }
7214                 bwn_dummy_transmission(mac, 0, 1);
7215                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7216                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7217                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7218                 else
7219                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7220                             &old_rfatt, old_txctl);
7221         }
7222         bwn_hwpctl_init_gphy(mac);
7223
7224         /* clear TSSI */
7225         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7226         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7227         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7228         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7229 }
7230
7231 static void
7232 bwn_hwpctl_early_init(struct bwn_mac *mac)
7233 {
7234         struct bwn_phy *phy = &mac->mac_phy;
7235
7236         if (!bwn_has_hwpctl(mac)) {
7237                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7238                 return;
7239         }
7240
7241         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7242         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7243         BWN_PHY_SET(mac, 0x047c, 0x0002);
7244         BWN_PHY_SET(mac, 0x047a, 0xf000);
7245         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7246                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7247                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7248                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7249                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7250                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7251         } else {
7252                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7253                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7254                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7255                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7256                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7257                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7258                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7259         }
7260 }
7261
7262 static void
7263 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7264 {
7265         struct bwn_phy *phy = &mac->mac_phy;
7266         struct bwn_phy_g *pg = &phy->phy_g;
7267         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7268         int i;
7269         uint16_t nr_written = 0, tmp, value;
7270         uint8_t rf, bb;
7271
7272         if (!bwn_has_hwpctl(mac)) {
7273                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7274                 return;
7275         }
7276
7277         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7278             (pg->pg_idletssi - pg->pg_curtssi));
7279         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7280             (pg->pg_idletssi - pg->pg_curtssi));
7281
7282         for (i = 0; i < 32; i++)
7283                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7284         for (i = 32; i < 64; i++)
7285                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7286         for (i = 0; i < 64; i += 2) {
7287                 value = (uint16_t) pg->pg_tssi2dbm[i];
7288                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7289                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7290         }
7291
7292         for (rf = 0; rf < lo->rfatt.len; rf++) {
7293                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7294                         if (nr_written >= 0x40)
7295                                 return;
7296                         tmp = lo->bbatt.array[bb].att;
7297                         tmp <<= 8;
7298                         if (phy->rf_rev == 8)
7299                                 tmp |= 0x50;
7300                         else
7301                                 tmp |= 0x40;
7302                         tmp |= lo->rfatt.array[rf].att;
7303                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7304                         nr_written++;
7305                 }
7306         }
7307
7308         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7309         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7310
7311         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7312         BWN_PHY_SET(mac, 0x0478, 0x0800);
7313         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7314         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7315
7316         bwn_phy_g_dc_lookup_init(mac, 1);
7317         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7318 }
7319
7320 static void
7321 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7322 {
7323         struct bwn_softc *sc = mac->mac_sc;
7324
7325         if (spu != 0)
7326                 bwn_spu_workaround(mac, channel);
7327
7328         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7329
7330         if (channel == 14) {
7331                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7332                         bwn_hf_write(mac,
7333                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7334                 else
7335                         bwn_hf_write(mac,
7336                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7337                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7338                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7339                 return;
7340         }
7341
7342         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7343             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7344 }
7345
7346 static uint16_t
7347 bwn_phy_g_chan2freq(uint8_t channel)
7348 {
7349         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7350
7351         KASSERT(channel >= 1 && channel <= 14,
7352             ("%s:%d: fail", __func__, __LINE__));
7353
7354         return (bwn_phy_g_rf_channels[channel - 1]);
7355 }
7356
7357 static void
7358 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7359     const struct bwn_rfatt *rfatt, uint8_t txctl)
7360 {
7361         struct bwn_phy *phy = &mac->mac_phy;
7362         struct bwn_phy_g *pg = &phy->phy_g;
7363         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7364         uint16_t bb, rf;
7365         uint16_t tx_bias, tx_magn;
7366
7367         bb = bbatt->att;
7368         rf = rfatt->att;
7369         tx_bias = lo->tx_bias;
7370         tx_magn = lo->tx_magn;
7371         if (tx_bias == 0xff)
7372                 tx_bias = 0;
7373
7374         pg->pg_txctl = txctl;
7375         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7376         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7377         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7378         bwn_phy_g_set_bbatt(mac, bb);
7379         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7380         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7381                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7382         else {
7383                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7384                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7385         }
7386         if (BWN_HAS_TXMAG(phy))
7387                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7388         else
7389                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7390         bwn_lo_g_adjust(mac);
7391 }
7392
7393 static void
7394 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7395     uint16_t bbatt)
7396 {
7397         struct bwn_phy *phy = &mac->mac_phy;
7398
7399         if (phy->analog == 0) {
7400                 BWN_WRITE_2(mac, BWN_PHY0,
7401                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7402                 return;
7403         }
7404         if (phy->analog > 1) {
7405                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7406                 return;
7407         }
7408         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7409 }
7410
7411 static uint16_t
7412 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7413 {
7414         struct bwn_phy *phy = &mac->mac_phy;
7415         struct bwn_phy_g *pg = &phy->phy_g;
7416         struct bwn_softc *sc = mac->mac_sc;
7417         int max_lb_gain;
7418         uint16_t extlna;
7419         uint16_t i;
7420
7421         if (phy->gmode == 0)
7422                 return (0);
7423
7424         if (BWN_HAS_LOOPBACK(phy)) {
7425                 max_lb_gain = pg->pg_max_lb_gain;
7426                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7427                 if (max_lb_gain >= 0x46) {
7428                         extlna = 0x3000;
7429                         max_lb_gain -= 0x46;
7430                 } else if (max_lb_gain >= 0x3a) {
7431                         extlna = 0x1000;
7432                         max_lb_gain -= 0x3a;
7433                 } else if (max_lb_gain >= 0x2e) {
7434                         extlna = 0x2000;
7435                         max_lb_gain -= 0x2e;
7436                 } else {
7437                         extlna = 0;
7438                         max_lb_gain -= 0x10;
7439                 }
7440
7441                 for (i = 0; i < 16; i++) {
7442                         max_lb_gain -= (i * 6);
7443                         if (max_lb_gain < 6)
7444                                 break;
7445                 }
7446
7447                 if ((phy->rev < 7) ||
7448                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7449                         if (reg == BWN_PHY_RFOVER) {
7450                                 return (0x1b3);
7451                         } else if (reg == BWN_PHY_RFOVERVAL) {
7452                                 extlna |= (i << 8);
7453                                 switch (lpd) {
7454                                 case BWN_LPD(0, 1, 1):
7455                                         return (0x0f92);
7456                                 case BWN_LPD(0, 0, 1):
7457                                 case BWN_LPD(1, 0, 1):
7458                                         return (0x0092 | extlna);
7459                                 case BWN_LPD(1, 0, 0):
7460                                         return (0x0093 | extlna);
7461                                 }
7462                                 KASSERT(0 == 1,
7463                                     ("%s:%d: fail", __func__, __LINE__));
7464                         }
7465                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7466                 } else {
7467                         if (reg == BWN_PHY_RFOVER)
7468                                 return (0x9b3);
7469                         if (reg == BWN_PHY_RFOVERVAL) {
7470                                 if (extlna)
7471                                         extlna |= 0x8000;
7472                                 extlna |= (i << 8);
7473                                 switch (lpd) {
7474                                 case BWN_LPD(0, 1, 1):
7475                                         return (0x8f92);
7476                                 case BWN_LPD(0, 0, 1):
7477                                         return (0x8092 | extlna);
7478                                 case BWN_LPD(1, 0, 1):
7479                                         return (0x2092 | extlna);
7480                                 case BWN_LPD(1, 0, 0):
7481                                         return (0x2093 | extlna);
7482                                 }
7483                                 KASSERT(0 == 1,
7484                                     ("%s:%d: fail", __func__, __LINE__));
7485                         }
7486                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7487                 }
7488                 return (0);
7489         }
7490
7491         if ((phy->rev < 7) ||
7492             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7493                 if (reg == BWN_PHY_RFOVER) {
7494                         return (0x1b3);
7495                 } else if (reg == BWN_PHY_RFOVERVAL) {
7496                         switch (lpd) {
7497                         case BWN_LPD(0, 1, 1):
7498                                 return (0x0fb2);
7499                         case BWN_LPD(0, 0, 1):
7500                                 return (0x00b2);
7501                         case BWN_LPD(1, 0, 1):
7502                                 return (0x30b2);
7503                         case BWN_LPD(1, 0, 0):
7504                                 return (0x30b3);
7505                         }
7506                         KASSERT(0 == 1,
7507                             ("%s:%d: fail", __func__, __LINE__));
7508                 }
7509                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7510         } else {
7511                 if (reg == BWN_PHY_RFOVER) {
7512                         return (0x9b3);
7513                 } else if (reg == BWN_PHY_RFOVERVAL) {
7514                         switch (lpd) {
7515                         case BWN_LPD(0, 1, 1):
7516                                 return (0x8fb2);
7517                         case BWN_LPD(0, 0, 1):
7518                                 return (0x80b2);
7519                         case BWN_LPD(1, 0, 1):
7520                                 return (0x20b2);
7521                         case BWN_LPD(1, 0, 0):
7522                                 return (0x20b3);
7523                         }
7524                         KASSERT(0 == 1,
7525                             ("%s:%d: fail", __func__, __LINE__));
7526                 }
7527                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7528         }
7529         return (0);
7530 }
7531
7532 static void
7533 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7534 {
7535
7536         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7537                 return;
7538         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7539             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7540         DELAY(1000);
7541         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7542 }
7543
7544 static int
7545 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7546 {
7547         struct bwn_softc *sc = mac->mac_sc;
7548         struct bwn_fw *fw = &mac->mac_fw;
7549         const uint8_t rev = siba_get_revid(sc->sc_dev);
7550         const char *filename;
7551         uint32_t high;
7552         int error;
7553
7554         /* microcode */
7555         if (rev >= 5 && rev <= 10)
7556                 filename = "ucode5";
7557         else if (rev >= 11 && rev <= 12)
7558                 filename = "ucode11";
7559         else if (rev == 13)
7560                 filename = "ucode13";
7561         else if (rev == 14)
7562                 filename = "ucode14";
7563         else if (rev >= 15)
7564                 filename = "ucode15";
7565         else {
7566                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7567                 bwn_release_firmware(mac);
7568                 return (EOPNOTSUPP);
7569         }
7570         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7571         if (error) {
7572                 bwn_release_firmware(mac);
7573                 return (error);
7574         }
7575
7576         /* PCM */
7577         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7578         if (rev >= 5 && rev <= 10) {
7579                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7580                 if (error == ENOENT)
7581                         fw->no_pcmfile = 1;
7582                 else if (error) {
7583                         bwn_release_firmware(mac);
7584                         return (error);
7585                 }
7586         } else if (rev < 11) {
7587                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7588                 return (EOPNOTSUPP);
7589         }
7590
7591         /* initvals */
7592         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7593         switch (mac->mac_phy.type) {
7594         case BWN_PHYTYPE_A:
7595                 if (rev < 5 || rev > 10)
7596                         goto fail1;
7597                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7598                         filename = "a0g1initvals5";
7599                 else
7600                         filename = "a0g0initvals5";
7601                 break;
7602         case BWN_PHYTYPE_G:
7603                 if (rev >= 5 && rev <= 10)
7604                         filename = "b0g0initvals5";
7605                 else if (rev >= 13)
7606                         filename = "b0g0initvals13";
7607                 else
7608                         goto fail1;
7609                 break;
7610         case BWN_PHYTYPE_LP:
7611                 if (rev == 13)
7612                         filename = "lp0initvals13";
7613                 else if (rev == 14)
7614                         filename = "lp0initvals14";
7615                 else if (rev >= 15)
7616                         filename = "lp0initvals15";
7617                 else
7618                         goto fail1;
7619                 break;
7620         case BWN_PHYTYPE_N:
7621                 if (rev >= 11 && rev <= 12)
7622                         filename = "n0initvals11";
7623                 else
7624                         goto fail1;
7625                 break;
7626         default:
7627                 goto fail1;
7628         }
7629         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7630         if (error) {
7631                 bwn_release_firmware(mac);
7632                 return (error);
7633         }
7634
7635         /* bandswitch initvals */
7636         switch (mac->mac_phy.type) {
7637         case BWN_PHYTYPE_A:
7638                 if (rev >= 5 && rev <= 10) {
7639                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7640                                 filename = "a0g1bsinitvals5";
7641                         else
7642                                 filename = "a0g0bsinitvals5";
7643                 } else if (rev >= 11)
7644                         filename = NULL;
7645                 else
7646                         goto fail1;
7647                 break;
7648         case BWN_PHYTYPE_G:
7649                 if (rev >= 5 && rev <= 10)
7650                         filename = "b0g0bsinitvals5";
7651                 else if (rev >= 11)
7652                         filename = NULL;
7653                 else
7654                         goto fail1;
7655                 break;
7656         case BWN_PHYTYPE_LP:
7657                 if (rev == 13)
7658                         filename = "lp0bsinitvals13";
7659                 else if (rev == 14)
7660                         filename = "lp0bsinitvals14";
7661                 else if (rev >= 15)
7662                         filename = "lp0bsinitvals15";
7663                 else
7664                         goto fail1;
7665                 break;
7666         case BWN_PHYTYPE_N:
7667                 if (rev >= 11 && rev <= 12)
7668                         filename = "n0bsinitvals11";
7669                 else
7670                         goto fail1;
7671                 break;
7672         default:
7673                 goto fail1;
7674         }
7675         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7676         if (error) {
7677                 bwn_release_firmware(mac);
7678                 return (error);
7679         }
7680         return (0);
7681 fail1:
7682         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7683         bwn_release_firmware(mac);
7684         return (EOPNOTSUPP);
7685 }
7686
7687 static int
7688 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7689     const char *name, struct bwn_fwfile *bfw)
7690 {
7691         const struct bwn_fwhdr *hdr;
7692         struct bwn_softc *sc = mac->mac_sc;
7693         const struct firmware *fw;
7694         char namebuf[64];
7695
7696         if (name == NULL) {
7697                 bwn_do_release_fw(bfw);
7698                 return (0);
7699         }
7700         if (bfw->filename != NULL) {
7701                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7702                         return (0);
7703                 bwn_do_release_fw(bfw);
7704         }
7705
7706         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7707             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7708             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7709         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7710         fw = firmware_get(namebuf);
7711         if (fw == NULL) {
7712                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7713                     namebuf);
7714                 return (ENOENT);
7715         }
7716         if (fw->datasize < sizeof(struct bwn_fwhdr))
7717                 goto fail;
7718         hdr = (const struct bwn_fwhdr *)(fw->data);
7719         switch (hdr->type) {
7720         case BWN_FWTYPE_UCODE:
7721         case BWN_FWTYPE_PCM:
7722                 if (be32toh(hdr->size) !=
7723                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7724                         goto fail;
7725                 /* FALLTHROUGH */
7726         case BWN_FWTYPE_IV:
7727                 if (hdr->ver != 1)
7728                         goto fail;
7729                 break;
7730         default:
7731                 goto fail;
7732         }
7733         bfw->filename = name;
7734         bfw->fw = fw;
7735         bfw->type = type;
7736         return (0);
7737 fail:
7738         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7739         if (fw != NULL)
7740                 firmware_put(fw, FIRMWARE_UNLOAD);
7741         return (EPROTO);
7742 }
7743
7744 static void
7745 bwn_release_firmware(struct bwn_mac *mac)
7746 {
7747
7748         bwn_do_release_fw(&mac->mac_fw.ucode);
7749         bwn_do_release_fw(&mac->mac_fw.pcm);
7750         bwn_do_release_fw(&mac->mac_fw.initvals);
7751         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7752 }
7753
7754 static void
7755 bwn_do_release_fw(struct bwn_fwfile *bfw)
7756 {
7757
7758         if (bfw->fw != NULL)
7759                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7760         bfw->fw = NULL;
7761         bfw->filename = NULL;
7762 }
7763
7764 static int
7765 bwn_fw_loaducode(struct bwn_mac *mac)
7766 {
7767 #define GETFWOFFSET(fwp, offset)        \
7768         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7769 #define GETFWSIZE(fwp, offset)  \
7770         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7771         struct bwn_softc *sc = mac->mac_sc;
7772         const uint32_t *data;
7773         unsigned int i;
7774         uint32_t ctl;
7775         uint16_t date, fwcaps, time;
7776         int error = 0;
7777
7778         ctl = BWN_READ_4(mac, BWN_MACCTL);
7779         ctl |= BWN_MACCTL_MCODE_JMP0;
7780         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7781             __LINE__));
7782         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7783         for (i = 0; i < 64; i++)
7784                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7785         for (i = 0; i < 4096; i += 2)
7786                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7787
7788         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7789         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7790         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7791              i++) {
7792                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7793                 DELAY(10);
7794         }
7795
7796         if (mac->mac_fw.pcm.fw) {
7797                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7798                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7799                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7800                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7801                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7802                     sizeof(struct bwn_fwhdr)); i++) {
7803                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7804                         DELAY(10);
7805                 }
7806         }
7807
7808         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7809         BWN_WRITE_4(mac, BWN_MACCTL,
7810             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7811             BWN_MACCTL_MCODE_RUN);
7812
7813         for (i = 0; i < 21; i++) {
7814                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7815                         break;
7816                 if (i >= 20) {
7817                         device_printf(sc->sc_dev, "ucode timeout\n");
7818                         error = ENXIO;
7819                         goto error;
7820                 }
7821                 DELAY(50000);
7822         }
7823         BWN_READ_4(mac, BWN_INTR_REASON);
7824
7825         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7826         if (mac->mac_fw.rev <= 0x128) {
7827                 device_printf(sc->sc_dev, "the firmware is too old\n");
7828                 error = EOPNOTSUPP;
7829                 goto error;
7830         }
7831         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7832             BWN_SHARED_UCODE_PATCH);
7833         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7834         mac->mac_fw.opensource = (date == 0xffff);
7835         if (bwn_wme != 0)
7836                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7837         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7838
7839         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7840         if (mac->mac_fw.opensource == 0) {
7841                 device_printf(sc->sc_dev,
7842                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7843                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7844                 if (mac->mac_fw.no_pcmfile)
7845                         device_printf(sc->sc_dev,
7846                             "no HW crypto acceleration due to pcm5\n");
7847         } else {
7848                 mac->mac_fw.patch = time;
7849                 fwcaps = bwn_fwcaps_read(mac);
7850                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7851                         device_printf(sc->sc_dev,
7852                             "disabling HW crypto acceleration\n");
7853                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7854                 }
7855                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7856                         device_printf(sc->sc_dev, "disabling WME support\n");
7857                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7858                 }
7859         }
7860
7861         if (BWN_ISOLDFMT(mac))
7862                 device_printf(sc->sc_dev, "using old firmware image\n");
7863
7864         return (0);
7865
7866 error:
7867         BWN_WRITE_4(mac, BWN_MACCTL,
7868             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7869             BWN_MACCTL_MCODE_JMP0);
7870
7871         return (error);
7872 #undef GETFWSIZE
7873 #undef GETFWOFFSET
7874 }
7875
7876 /* OpenFirmware only */
7877 static uint16_t
7878 bwn_fwcaps_read(struct bwn_mac *mac)
7879 {
7880
7881         KASSERT(mac->mac_fw.opensource == 1,
7882             ("%s:%d: fail", __func__, __LINE__));
7883         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7884 }
7885
7886 static int
7887 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7888     size_t count, size_t array_size)
7889 {
7890 #define GET_NEXTIV16(iv)                                                \
7891         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7892             sizeof(uint16_t) + sizeof(uint16_t)))
7893 #define GET_NEXTIV32(iv)                                                \
7894         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7895             sizeof(uint16_t) + sizeof(uint32_t)))
7896         struct bwn_softc *sc = mac->mac_sc;
7897         const struct bwn_fwinitvals *iv;
7898         uint16_t offset;
7899         size_t i;
7900         uint8_t bit32;
7901
7902         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7903             ("%s:%d: fail", __func__, __LINE__));
7904         iv = ivals;
7905         for (i = 0; i < count; i++) {
7906                 if (array_size < sizeof(iv->offset_size))
7907                         goto fail;
7908                 array_size -= sizeof(iv->offset_size);
7909                 offset = be16toh(iv->offset_size);
7910                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7911                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7912                 if (offset >= 0x1000)
7913                         goto fail;
7914                 if (bit32) {
7915                         if (array_size < sizeof(iv->data.d32))
7916                                 goto fail;
7917                         array_size -= sizeof(iv->data.d32);
7918                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7919                         iv = GET_NEXTIV32(iv);
7920                 } else {
7921
7922                         if (array_size < sizeof(iv->data.d16))
7923                                 goto fail;
7924                         array_size -= sizeof(iv->data.d16);
7925                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7926
7927                         iv = GET_NEXTIV16(iv);
7928                 }
7929         }
7930         if (array_size != 0)
7931                 goto fail;
7932         return (0);
7933 fail:
7934         device_printf(sc->sc_dev, "initvals: invalid format\n");
7935         return (EPROTO);
7936 #undef GET_NEXTIV16
7937 #undef GET_NEXTIV32
7938 }
7939
7940 static int
7941 bwn_switch_channel(struct bwn_mac *mac, int chan)
7942 {
7943         struct bwn_phy *phy = &(mac->mac_phy);
7944         struct bwn_softc *sc = mac->mac_sc;
7945         struct ifnet *ifp = sc->sc_ifp;
7946         struct ieee80211com *ic = ifp->if_l2com;
7947         uint16_t channelcookie, savedcookie;
7948         int error;
7949
7950         if (chan == 0xffff)
7951                 chan = phy->get_default_chan(mac);
7952
7953         channelcookie = chan;
7954         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7955                 channelcookie |= 0x100;
7956         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7957         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7958         error = phy->switch_channel(mac, chan);
7959         if (error)
7960                 goto fail;
7961
7962         mac->mac_phy.chan = chan;
7963         DELAY(8000);
7964         return (0);
7965 fail:
7966         device_printf(sc->sc_dev, "failed to switch channel\n");
7967         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7968         return (error);
7969 }
7970
7971 static uint16_t
7972 bwn_ant2phy(int antenna)
7973 {
7974
7975         switch (antenna) {
7976         case BWN_ANT0:
7977                 return (BWN_TX_PHY_ANT0);
7978         case BWN_ANT1:
7979                 return (BWN_TX_PHY_ANT1);
7980         case BWN_ANT2:
7981                 return (BWN_TX_PHY_ANT2);
7982         case BWN_ANT3:
7983                 return (BWN_TX_PHY_ANT3);
7984         case BWN_ANTAUTO:
7985                 return (BWN_TX_PHY_ANT01AUTO);
7986         }
7987         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7988         return (0);
7989 }
7990
7991 static void
7992 bwn_wme_load(struct bwn_mac *mac)
7993 {
7994         struct bwn_softc *sc = mac->mac_sc;
7995         int i;
7996
7997         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7998             ("%s:%d: fail", __func__, __LINE__));
7999
8000         bwn_mac_suspend(mac);
8001         for (i = 0; i < N(sc->sc_wmeParams); i++)
8002                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8003                     bwn_wme_shm_offsets[i]);
8004         bwn_mac_enable(mac);
8005 }
8006
8007 static void
8008 bwn_wme_loadparams(struct bwn_mac *mac,
8009     const struct wmeParams *p, uint16_t shm_offset)
8010 {
8011 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8012         struct bwn_softc *sc = mac->mac_sc;
8013         uint16_t params[BWN_NR_WMEPARAMS];
8014         int slot, tmp;
8015         unsigned int i;
8016
8017         slot = BWN_READ_2(mac, BWN_RNG) &
8018             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8019
8020         memset(&params, 0, sizeof(params));
8021
8022         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8023             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8024             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8025
8026         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8027         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8028         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8029         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8030         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8031         params[BWN_WMEPARAM_BSLOTS] = slot;
8032         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8033
8034         for (i = 0; i < N(params); i++) {
8035                 if (i == BWN_WMEPARAM_STATUS) {
8036                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8037                             shm_offset + (i * 2));
8038                         tmp |= 0x100;
8039                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8040                             tmp);
8041                 } else {
8042                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8043                             params[i]);
8044                 }
8045         }
8046 }
8047
8048 static void
8049 bwn_mac_write_bssid(struct bwn_mac *mac)
8050 {
8051         struct bwn_softc *sc = mac->mac_sc;
8052         uint32_t tmp;
8053         int i;
8054         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8055
8056         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8057         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8058         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8059             IEEE80211_ADDR_LEN);
8060
8061         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8062                 tmp = (uint32_t) (mac_bssid[i + 0]);
8063                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8064                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8065                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8066                 bwn_ram_write(mac, 0x20 + i, tmp);
8067         }
8068 }
8069
8070 static void
8071 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8072     const uint8_t *macaddr)
8073 {
8074         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8075         uint16_t data;
8076
8077         if (!mac)
8078                 macaddr = zero;
8079
8080         offset |= 0x0020;
8081         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8082
8083         data = macaddr[0];
8084         data |= macaddr[1] << 8;
8085         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8086         data = macaddr[2];
8087         data |= macaddr[3] << 8;
8088         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8089         data = macaddr[4];
8090         data |= macaddr[5] << 8;
8091         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8092 }
8093
8094 static void
8095 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8096     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8097 {
8098         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8099         uint8_t per_sta_keys_start = 8;
8100
8101         if (BWN_SEC_NEWAPI(mac))
8102                 per_sta_keys_start = 4;
8103
8104         KASSERT(index < mac->mac_max_nr_keys,
8105             ("%s:%d: fail", __func__, __LINE__));
8106         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8107             ("%s:%d: fail", __func__, __LINE__));
8108
8109         if (index >= per_sta_keys_start)
8110                 bwn_key_macwrite(mac, index, NULL);
8111         if (key)
8112                 memcpy(buf, key, key_len);
8113         bwn_key_write(mac, index, algorithm, buf);
8114         if (index >= per_sta_keys_start)
8115                 bwn_key_macwrite(mac, index, mac_addr);
8116
8117         mac->mac_key[index].algorithm = algorithm;
8118 }
8119
8120 static void
8121 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8122 {
8123         struct bwn_softc *sc = mac->mac_sc;
8124         uint32_t addrtmp[2] = { 0, 0 };
8125         uint8_t start = 8;
8126
8127         if (BWN_SEC_NEWAPI(mac))
8128                 start = 4;
8129
8130         KASSERT(index >= start,
8131             ("%s:%d: fail", __func__, __LINE__));
8132         index -= start;
8133
8134         if (addr) {
8135                 addrtmp[0] = addr[0];
8136                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8137                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8138                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8139                 addrtmp[1] = addr[4];
8140                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8141         }
8142
8143         if (siba_get_revid(sc->sc_dev) >= 5) {
8144                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8145                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8146         } else {
8147                 if (index >= 8) {
8148                         bwn_shm_write_4(mac, BWN_SHARED,
8149                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8150                         bwn_shm_write_2(mac, BWN_SHARED,
8151                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8152                 }
8153         }
8154 }
8155
8156 static void
8157 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8158     const uint8_t *key)
8159 {
8160         unsigned int i;
8161         uint32_t offset;
8162         uint16_t kidx, value;
8163
8164         kidx = BWN_SEC_KEY2FW(mac, index);
8165         bwn_shm_write_2(mac, BWN_SHARED,
8166             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8167
8168         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8169         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8170                 value = key[i];
8171                 value |= (uint16_t)(key[i + 1]) << 8;
8172                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8173         }
8174 }
8175
8176 static void
8177 bwn_phy_exit(struct bwn_mac *mac)
8178 {
8179
8180         mac->mac_phy.rf_onoff(mac, 0);
8181         if (mac->mac_phy.exit != NULL)
8182                 mac->mac_phy.exit(mac);
8183 }
8184
8185 static void
8186 bwn_dma_free(struct bwn_mac *mac)
8187 {
8188         struct bwn_dma *dma;
8189
8190         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8191                 return;
8192         dma = &mac->mac_method.dma;
8193
8194         bwn_dma_ringfree(&dma->rx);
8195         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8196         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8197         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8198         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8199         bwn_dma_ringfree(&dma->mcast);
8200 }
8201
8202 static void
8203 bwn_core_stop(struct bwn_mac *mac)
8204 {
8205         struct bwn_softc *sc = mac->mac_sc;
8206
8207         BWN_ASSERT_LOCKED(sc);
8208
8209         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8210                 return;
8211
8212         callout_stop(&sc->sc_rfswitch_ch);
8213         callout_stop(&sc->sc_task_ch);
8214         callout_stop(&sc->sc_watchdog_ch);
8215         sc->sc_watchdog_timer = 0;
8216         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8217         BWN_READ_4(mac, BWN_INTR_MASK);
8218         bwn_mac_suspend(mac);
8219
8220         mac->mac_status = BWN_MAC_STATUS_INITED;
8221 }
8222
8223 static int
8224 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8225 {
8226         struct bwn_mac *up_dev = NULL;
8227         struct bwn_mac *down_dev;
8228         struct bwn_mac *mac;
8229         int err, status;
8230         uint8_t gmode;
8231
8232         BWN_ASSERT_LOCKED(sc);
8233
8234         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8235                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8236                     mac->mac_phy.supports_2ghz) {
8237                         up_dev = mac;
8238                         gmode = 1;
8239                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8240                     mac->mac_phy.supports_5ghz) {
8241                         up_dev = mac;
8242                         gmode = 0;
8243                 } else {
8244                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8245                         return (EINVAL);
8246                 }
8247                 if (up_dev != NULL)
8248                         break;
8249         }
8250         if (up_dev == NULL) {
8251                 device_printf(sc->sc_dev, "Could not find a device\n");
8252                 return (ENODEV);
8253         }
8254         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8255                 return (0);
8256
8257         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8258             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8259
8260         down_dev = sc->sc_curmac;
8261         status = down_dev->mac_status;
8262         if (status >= BWN_MAC_STATUS_STARTED)
8263                 bwn_core_stop(down_dev);
8264         if (status >= BWN_MAC_STATUS_INITED)
8265                 bwn_core_exit(down_dev);
8266
8267         if (down_dev != up_dev)
8268                 bwn_phy_reset(down_dev);
8269
8270         up_dev->mac_phy.gmode = gmode;
8271         if (status >= BWN_MAC_STATUS_INITED) {
8272                 err = bwn_core_init(up_dev);
8273                 if (err) {
8274                         device_printf(sc->sc_dev,
8275                             "fatal: failed to initialize for %s-GHz\n",
8276                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8277                         goto fail;
8278                 }
8279         }
8280         if (status >= BWN_MAC_STATUS_STARTED)
8281                 bwn_core_start(up_dev);
8282         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8283         sc->sc_curmac = up_dev;
8284
8285         return (0);
8286 fail:
8287         sc->sc_curmac = NULL;
8288         return (err);
8289 }
8290
8291 static void
8292 bwn_rf_turnon(struct bwn_mac *mac)
8293 {
8294
8295         bwn_mac_suspend(mac);
8296         mac->mac_phy.rf_onoff(mac, 1);
8297         mac->mac_phy.rf_on = 1;
8298         bwn_mac_enable(mac);
8299 }
8300
8301 static void
8302 bwn_rf_turnoff(struct bwn_mac *mac)
8303 {
8304
8305         bwn_mac_suspend(mac);
8306         mac->mac_phy.rf_onoff(mac, 0);
8307         mac->mac_phy.rf_on = 0;
8308         bwn_mac_enable(mac);
8309 }
8310
8311 static void
8312 bwn_phy_reset(struct bwn_mac *mac)
8313 {
8314         struct bwn_softc *sc = mac->mac_sc;
8315
8316         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8317             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8318              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8319         DELAY(1000);
8320         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8321             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8322             BWN_TGSLOW_PHYRESET);
8323         DELAY(1000);
8324 }
8325
8326 static int
8327 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8328 {
8329         struct bwn_vap *bvp = BWN_VAP(vap);
8330         struct ieee80211com *ic= vap->iv_ic;
8331         struct ifnet *ifp = ic->ic_ifp;
8332         enum ieee80211_state ostate = vap->iv_state;
8333         struct bwn_softc *sc = ifp->if_softc;
8334         struct bwn_mac *mac = sc->sc_curmac;
8335         int error;
8336
8337         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8338             ieee80211_state_name[vap->iv_state],
8339             ieee80211_state_name[nstate]);
8340
8341         error = bvp->bv_newstate(vap, nstate, arg);
8342         if (error != 0)
8343                 return (error);
8344
8345         BWN_LOCK(sc);
8346
8347         bwn_led_newstate(mac, nstate);
8348
8349         /*
8350          * Clear the BSSID when we stop a STA
8351          */
8352         if (vap->iv_opmode == IEEE80211_M_STA) {
8353                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8354                         /*
8355                          * Clear out the BSSID.  If we reassociate to
8356                          * the same AP, this will reinialize things
8357                          * correctly...
8358                          */
8359                         if (ic->ic_opmode == IEEE80211_M_STA &&
8360                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8361                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8362                                 bwn_set_macaddr(mac);
8363                         }
8364                 }
8365         }
8366
8367         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8368             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8369                 /* XXX nothing to do? */
8370         } else if (nstate == IEEE80211_S_RUN) {
8371                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8372                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8373                 bwn_set_opmode(mac);
8374                 bwn_set_pretbtt(mac);
8375                 bwn_spu_setdelay(mac, 0);
8376                 bwn_set_macaddr(mac);
8377         }
8378
8379         BWN_UNLOCK(sc);
8380
8381         return (error);
8382 }
8383
8384 static void
8385 bwn_set_pretbtt(struct bwn_mac *mac)
8386 {
8387         struct bwn_softc *sc = mac->mac_sc;
8388         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8389         uint16_t pretbtt;
8390
8391         if (ic->ic_opmode == IEEE80211_M_IBSS)
8392                 pretbtt = 2;
8393         else
8394                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8395         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8396         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8397 }
8398
8399 static int
8400 bwn_intr(void *arg)
8401 {
8402         struct bwn_mac *mac = arg;
8403         struct bwn_softc *sc = mac->mac_sc;
8404         uint32_t reason;
8405
8406         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8407             (sc->sc_flags & BWN_FLAG_INVALID))
8408                 return (FILTER_STRAY);
8409
8410         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8411         if (reason == 0xffffffff)       /* shared IRQ */
8412                 return (FILTER_STRAY);
8413         reason &= mac->mac_intr_mask;
8414         if (reason == 0)
8415                 return (FILTER_HANDLED);
8416
8417         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8418         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8419         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8420         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8421         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8422         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8423         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8424         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8425         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8426         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8427         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8428
8429         /* Disable interrupts. */
8430         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8431
8432         mac->mac_reason_intr = reason;
8433
8434         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8435         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8436
8437         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8438         return (FILTER_HANDLED);
8439 }
8440
8441 static void
8442 bwn_intrtask(void *arg, int npending)
8443 {
8444         struct bwn_mac *mac = arg;
8445         struct bwn_softc *sc = mac->mac_sc;
8446         struct ifnet *ifp = sc->sc_ifp;
8447         uint32_t merged = 0;
8448         int i, tx = 0, rx = 0;
8449
8450         BWN_LOCK(sc);
8451         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8452             (sc->sc_flags & BWN_FLAG_INVALID)) {
8453                 BWN_UNLOCK(sc);
8454                 return;
8455         }
8456
8457         for (i = 0; i < N(mac->mac_reason); i++)
8458                 merged |= mac->mac_reason[i];
8459
8460         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8461                 device_printf(sc->sc_dev, "MAC trans error\n");
8462
8463         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8464                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8465                 mac->mac_phy.txerrors--;
8466                 if (mac->mac_phy.txerrors == 0) {
8467                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8468                         bwn_restart(mac, "PHY TX errors");
8469                 }
8470         }
8471
8472         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8473                 if (merged & BWN_DMAINTR_FATALMASK) {
8474                         device_printf(sc->sc_dev,
8475                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8476                             mac->mac_reason[0], mac->mac_reason[1],
8477                             mac->mac_reason[2], mac->mac_reason[3],
8478                             mac->mac_reason[4], mac->mac_reason[5]);
8479                         bwn_restart(mac, "DMA error");
8480                         BWN_UNLOCK(sc);
8481                         return;
8482                 }
8483                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8484                         device_printf(sc->sc_dev,
8485                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8486                             mac->mac_reason[0], mac->mac_reason[1],
8487                             mac->mac_reason[2], mac->mac_reason[3],
8488                             mac->mac_reason[4], mac->mac_reason[5]);
8489                 }
8490         }
8491
8492         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8493                 bwn_intr_ucode_debug(mac);
8494         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8495                 bwn_intr_tbtt_indication(mac);
8496         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8497                 bwn_intr_atim_end(mac);
8498         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8499                 bwn_intr_beacon(mac);
8500         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8501                 bwn_intr_pmq(mac);
8502         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8503                 bwn_intr_noise(mac);
8504
8505         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8506                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8507                         bwn_dma_rx(mac->mac_method.dma.rx);
8508                         rx = 1;
8509                 }
8510         } else
8511                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8512
8513         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8514         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8515         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518
8519         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8520                 bwn_intr_txeof(mac);
8521                 tx = 1;
8522         }
8523
8524         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8525
8526         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8527                 int evt = BWN_LED_EVENT_NONE;
8528
8529                 if (tx && rx) {
8530                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8531                                 evt = BWN_LED_EVENT_RX;
8532                         else
8533                                 evt = BWN_LED_EVENT_TX;
8534                 } else if (tx) {
8535                         evt = BWN_LED_EVENT_TX;
8536                 } else if (rx) {
8537                         evt = BWN_LED_EVENT_RX;
8538                 } else if (rx == 0) {
8539                         evt = BWN_LED_EVENT_POLL;
8540                 }
8541
8542                 if (evt != BWN_LED_EVENT_NONE)
8543                         bwn_led_event(mac, evt);
8544        }
8545
8546         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8547                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8548                         bwn_start_locked(ifp);
8549         }
8550
8551         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8552         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8553
8554         BWN_UNLOCK(sc);
8555 }
8556
8557 static void
8558 bwn_restart(struct bwn_mac *mac, const char *msg)
8559 {
8560         struct bwn_softc *sc = mac->mac_sc;
8561         struct ifnet *ifp = sc->sc_ifp;
8562         struct ieee80211com *ic = ifp->if_l2com;
8563
8564         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8565                 return;
8566
8567         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8568         ieee80211_runtask(ic, &mac->mac_hwreset);
8569 }
8570
8571 static void
8572 bwn_intr_ucode_debug(struct bwn_mac *mac)
8573 {
8574         struct bwn_softc *sc = mac->mac_sc;
8575         uint16_t reason;
8576
8577         if (mac->mac_fw.opensource == 0)
8578                 return;
8579
8580         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8581         switch (reason) {
8582         case BWN_DEBUGINTR_PANIC:
8583                 bwn_handle_fwpanic(mac);
8584                 break;
8585         case BWN_DEBUGINTR_DUMP_SHM:
8586                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8587                 break;
8588         case BWN_DEBUGINTR_DUMP_REGS:
8589                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8590                 break;
8591         case BWN_DEBUGINTR_MARKER:
8592                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8593                 break;
8594         default:
8595                 device_printf(sc->sc_dev,
8596                     "ucode debug unknown reason: %#x\n", reason);
8597         }
8598
8599         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8600             BWN_DEBUGINTR_ACK);
8601 }
8602
8603 static void
8604 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8605 {
8606         struct bwn_softc *sc = mac->mac_sc;
8607         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8608
8609         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8610                 bwn_psctl(mac, 0);
8611         if (ic->ic_opmode == IEEE80211_M_IBSS)
8612                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8613 }
8614
8615 static void
8616 bwn_intr_atim_end(struct bwn_mac *mac)
8617 {
8618
8619         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8620                 BWN_WRITE_4(mac, BWN_MACCMD,
8621                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8622                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8623         }
8624 }
8625
8626 static void
8627 bwn_intr_beacon(struct bwn_mac *mac)
8628 {
8629         struct bwn_softc *sc = mac->mac_sc;
8630         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8631         uint32_t cmd, beacon0, beacon1;
8632
8633         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8634             ic->ic_opmode == IEEE80211_M_MBSS)
8635                 return;
8636
8637         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8638
8639         cmd = BWN_READ_4(mac, BWN_MACCMD);
8640         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8641         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8642
8643         if (beacon0 && beacon1) {
8644                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8645                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8646                 return;
8647         }
8648
8649         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8650                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8651                 bwn_load_beacon0(mac);
8652                 bwn_load_beacon1(mac);
8653                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8654                 cmd |= BWN_MACCMD_BEACON0_VALID;
8655                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8656         } else {
8657                 if (!beacon0) {
8658                         bwn_load_beacon0(mac);
8659                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8660                         cmd |= BWN_MACCMD_BEACON0_VALID;
8661                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8662                 } else if (!beacon1) {
8663                         bwn_load_beacon1(mac);
8664                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8665                         cmd |= BWN_MACCMD_BEACON1_VALID;
8666                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8667                 }
8668         }
8669 }
8670
8671 static void
8672 bwn_intr_pmq(struct bwn_mac *mac)
8673 {
8674         uint32_t tmp;
8675
8676         while (1) {
8677                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8678                 if (!(tmp & 0x00000008))
8679                         break;
8680         }
8681         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8682 }
8683
8684 static void
8685 bwn_intr_noise(struct bwn_mac *mac)
8686 {
8687         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8688         uint16_t tmp;
8689         uint8_t noise[4];
8690         uint8_t i, j;
8691         int32_t average;
8692
8693         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8694                 return;
8695
8696         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8697         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8698         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8699             noise[3] == 0x7f)
8700                 goto new;
8701
8702         KASSERT(mac->mac_noise.noi_nsamples < 8,
8703             ("%s:%d: fail", __func__, __LINE__));
8704         i = mac->mac_noise.noi_nsamples;
8705         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8706         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8707         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8708         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8709         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8710         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8711         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8712         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8713         mac->mac_noise.noi_nsamples++;
8714         if (mac->mac_noise.noi_nsamples == 8) {
8715                 average = 0;
8716                 for (i = 0; i < 8; i++) {
8717                         for (j = 0; j < 4; j++)
8718                                 average += mac->mac_noise.noi_samples[i][j];
8719                 }
8720                 average = (((average / 32) * 125) + 64) / 128;
8721                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8722                 if (tmp >= 8)
8723                         average += 2;
8724                 else
8725                         average -= 25;
8726                 average -= (tmp == 8) ? 72 : 48;
8727
8728                 mac->mac_stats.link_noise = average;
8729                 mac->mac_noise.noi_running = 0;
8730                 return;
8731         }
8732 new:
8733         bwn_noise_gensample(mac);
8734 }
8735
8736 static int
8737 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8738 {
8739         struct bwn_mac *mac = prq->prq_mac;
8740         struct bwn_softc *sc = mac->mac_sc;
8741         unsigned int i;
8742
8743         BWN_ASSERT_LOCKED(sc);
8744
8745         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8746                 return (0);
8747
8748         for (i = 0; i < 5000; i++) {
8749                 if (bwn_pio_rxeof(prq) == 0)
8750                         break;
8751         }
8752         if (i >= 5000)
8753                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8754         return ((i > 0) ? 1 : 0);
8755 }
8756
8757 static void
8758 bwn_dma_rx(struct bwn_dma_ring *dr)
8759 {
8760         int slot, curslot;
8761
8762         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8763         curslot = dr->get_curslot(dr);
8764         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8765             ("%s:%d: fail", __func__, __LINE__));
8766
8767         slot = dr->dr_curslot;
8768         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8769                 bwn_dma_rxeof(dr, &slot);
8770
8771         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8772             BUS_DMASYNC_PREWRITE);
8773
8774         dr->set_curslot(dr, slot);
8775         dr->dr_curslot = slot;
8776 }
8777
8778 static void
8779 bwn_intr_txeof(struct bwn_mac *mac)
8780 {
8781         struct bwn_txstatus stat;
8782         uint32_t stat0, stat1;
8783         uint16_t tmp;
8784
8785         BWN_ASSERT_LOCKED(mac->mac_sc);
8786
8787         while (1) {
8788                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8789                 if (!(stat0 & 0x00000001))
8790                         break;
8791                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8792
8793                 stat.cookie = (stat0 >> 16);
8794                 stat.seq = (stat1 & 0x0000ffff);
8795                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8796                 tmp = (stat0 & 0x0000ffff);
8797                 stat.framecnt = ((tmp & 0xf000) >> 12);
8798                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8799                 stat.sreason = ((tmp & 0x001c) >> 2);
8800                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8801                 stat.im = (tmp & 0x0040) ? 1 : 0;
8802                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8803                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8804
8805                 bwn_handle_txeof(mac, &stat);
8806         }
8807 }
8808
8809 static void
8810 bwn_hwreset(void *arg, int npending)
8811 {
8812         struct bwn_mac *mac = arg;
8813         struct bwn_softc *sc = mac->mac_sc;
8814         int error = 0;
8815         int prev_status;
8816
8817         BWN_LOCK(sc);
8818
8819         prev_status = mac->mac_status;
8820         if (prev_status >= BWN_MAC_STATUS_STARTED)
8821                 bwn_core_stop(mac);
8822         if (prev_status >= BWN_MAC_STATUS_INITED)
8823                 bwn_core_exit(mac);
8824
8825         if (prev_status >= BWN_MAC_STATUS_INITED) {
8826                 error = bwn_core_init(mac);
8827                 if (error)
8828                         goto out;
8829         }
8830         if (prev_status >= BWN_MAC_STATUS_STARTED)
8831                 bwn_core_start(mac);
8832 out:
8833         if (error) {
8834                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8835                 sc->sc_curmac = NULL;
8836         }
8837         BWN_UNLOCK(sc);
8838 }
8839
8840 static void
8841 bwn_handle_fwpanic(struct bwn_mac *mac)
8842 {
8843         struct bwn_softc *sc = mac->mac_sc;
8844         uint16_t reason;
8845
8846         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8847         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8848
8849         if (reason == BWN_FWPANIC_RESTART)
8850                 bwn_restart(mac, "ucode panic");
8851 }
8852
8853 static void
8854 bwn_load_beacon0(struct bwn_mac *mac)
8855 {
8856
8857         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8858 }
8859
8860 static void
8861 bwn_load_beacon1(struct bwn_mac *mac)
8862 {
8863
8864         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8865 }
8866
8867 static uint32_t
8868 bwn_jssi_read(struct bwn_mac *mac)
8869 {
8870         uint32_t val = 0;
8871
8872         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8873         val <<= 16;
8874         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8875
8876         return (val);
8877 }
8878
8879 static void
8880 bwn_noise_gensample(struct bwn_mac *mac)
8881 {
8882         uint32_t jssi = 0x7f7f7f7f;
8883
8884         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8885         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8886         BWN_WRITE_4(mac, BWN_MACCMD,
8887             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8888 }
8889
8890 static int
8891 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8892 {
8893         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8894
8895         return (dr->dr_numslots - dr->dr_usedslot);
8896 }
8897
8898 static int
8899 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8900 {
8901         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8902
8903         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8904             ("%s:%d: fail", __func__, __LINE__));
8905         if (slot == dr->dr_numslots - 1)
8906                 return (0);
8907         return (slot + 1);
8908 }
8909
8910 static void
8911 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8912 {
8913         struct bwn_mac *mac = dr->dr_mac;
8914         struct bwn_softc *sc = mac->mac_sc;
8915         struct bwn_dma *dma = &mac->mac_method.dma;
8916         struct bwn_dmadesc_generic *desc;
8917         struct bwn_dmadesc_meta *meta;
8918         struct bwn_rxhdr4 *rxhdr;
8919         struct ifnet *ifp = sc->sc_ifp;
8920         struct mbuf *m;
8921         uint32_t macstat;
8922         int32_t tmp;
8923         int cnt = 0;
8924         uint16_t len;
8925
8926         dr->getdesc(dr, *slot, &desc, &meta);
8927
8928         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8929         m = meta->mt_m;
8930
8931         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8932                 ifp->if_ierrors++;
8933                 return;
8934         }
8935
8936         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8937         len = le16toh(rxhdr->frame_len);
8938         if (len <= 0) {
8939                 ifp->if_ierrors++;
8940                 return;
8941         }
8942         if (bwn_dma_check_redzone(dr, m)) {
8943                 device_printf(sc->sc_dev, "redzone error.\n");
8944                 bwn_dma_set_redzone(dr, m);
8945                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8946                     BUS_DMASYNC_PREWRITE);
8947                 return;
8948         }
8949         if (len > dr->dr_rx_bufsize) {
8950                 tmp = len;
8951                 while (1) {
8952                         dr->getdesc(dr, *slot, &desc, &meta);
8953                         bwn_dma_set_redzone(dr, meta->mt_m);
8954                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8955                             BUS_DMASYNC_PREWRITE);
8956                         *slot = bwn_dma_nextslot(dr, *slot);
8957                         cnt++;
8958                         tmp -= dr->dr_rx_bufsize;
8959                         if (tmp <= 0)
8960                                 break;
8961                 }
8962                 device_printf(sc->sc_dev, "too small buffer "
8963                        "(len %u buffer %u dropped %d)\n",
8964                        len, dr->dr_rx_bufsize, cnt);
8965                 return;
8966         }
8967         macstat = le32toh(rxhdr->mac_status);
8968         if (macstat & BWN_RX_MAC_FCSERR) {
8969                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8970                         device_printf(sc->sc_dev, "RX drop\n");
8971                         return;
8972                 }
8973         }
8974
8975         m->m_pkthdr.rcvif = ifp;
8976         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8977         m_adj(m, dr->dr_frameoffset);
8978
8979         bwn_rxeof(dr->dr_mac, m, rxhdr);
8980 }
8981
8982 static void
8983 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8984 {
8985         struct bwn_dma_ring *dr;
8986         struct bwn_dmadesc_generic *desc;
8987         struct bwn_dmadesc_meta *meta;
8988         struct bwn_pio_txqueue *tq;
8989         struct bwn_pio_txpkt *tp = NULL;
8990         struct bwn_softc *sc = mac->mac_sc;
8991         struct bwn_stats *stats = &mac->mac_stats;
8992         struct ieee80211_node *ni;
8993         struct ieee80211vap *vap;
8994         int retrycnt = 0, slot;
8995
8996         BWN_ASSERT_LOCKED(mac->mac_sc);
8997
8998         if (status->im)
8999                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9000         if (status->ampdu)
9001                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9002         if (status->rtscnt) {
9003                 if (status->rtscnt == 0xf)
9004                         stats->rtsfail++;
9005                 else
9006                         stats->rts++;
9007         }
9008
9009         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9010                 if (status->ack) {
9011                         dr = bwn_dma_parse_cookie(mac, status,
9012                             status->cookie, &slot);
9013                         if (dr == NULL) {
9014                                 device_printf(sc->sc_dev,
9015                                     "failed to parse cookie\n");
9016                                 return;
9017                         }
9018                         while (1) {
9019                                 dr->getdesc(dr, slot, &desc, &meta);
9020                                 if (meta->mt_islast) {
9021                                         ni = meta->mt_ni;
9022                                         vap = ni->ni_vap;
9023                                         ieee80211_ratectl_tx_complete(vap, ni,
9024                                             status->ack ?
9025                                               IEEE80211_RATECTL_TX_SUCCESS :
9026                                               IEEE80211_RATECTL_TX_FAILURE,
9027                                             &retrycnt, 0);
9028                                         break;
9029                                 }
9030                                 slot = bwn_dma_nextslot(dr, slot);
9031                         }
9032                 }
9033                 bwn_dma_handle_txeof(mac, status);
9034         } else {
9035                 if (status->ack) {
9036                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9037                         if (tq == NULL) {
9038                                 device_printf(sc->sc_dev,
9039                                     "failed to parse cookie\n");
9040                                 return;
9041                         }
9042                         ni = tp->tp_ni;
9043                         vap = ni->ni_vap;
9044                         ieee80211_ratectl_tx_complete(vap, ni,
9045                             status->ack ?
9046                               IEEE80211_RATECTL_TX_SUCCESS :
9047                               IEEE80211_RATECTL_TX_FAILURE,
9048                             &retrycnt, 0);
9049                 }
9050                 bwn_pio_handle_txeof(mac, status);
9051         }
9052
9053         bwn_phy_txpower_check(mac, 0);
9054 }
9055
9056 static uint8_t
9057 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9058 {
9059         struct bwn_mac *mac = prq->prq_mac;
9060         struct bwn_softc *sc = mac->mac_sc;
9061         struct bwn_rxhdr4 rxhdr;
9062         struct ifnet *ifp = sc->sc_ifp;
9063         struct mbuf *m;
9064         uint32_t ctl32, macstat, v32;
9065         unsigned int i, padding;
9066         uint16_t ctl16, len, totlen, v16;
9067         unsigned char *mp;
9068         char *data;
9069
9070         memset(&rxhdr, 0, sizeof(rxhdr));
9071
9072         if (prq->prq_rev >= 8) {
9073                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9074                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9075                         return (0);
9076                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9077                     BWN_PIO8_RXCTL_FRAMEREADY);
9078                 for (i = 0; i < 10; i++) {
9079                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9080                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9081                                 goto ready;
9082                         DELAY(10);
9083                 }
9084         } else {
9085                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9086                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9087                         return (0);
9088                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9089                     BWN_PIO_RXCTL_FRAMEREADY);
9090                 for (i = 0; i < 10; i++) {
9091                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9092                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9093                                 goto ready;
9094                         DELAY(10);
9095                 }
9096         }
9097         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9098         return (1);
9099 ready:
9100         if (prq->prq_rev >= 8)
9101                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9102                     prq->prq_base + BWN_PIO8_RXDATA);
9103         else
9104                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9105                     prq->prq_base + BWN_PIO_RXDATA);
9106         len = le16toh(rxhdr.frame_len);
9107         if (len > 0x700) {
9108                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9109                 goto error;
9110         }
9111         if (len == 0) {
9112                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9113                 goto error;
9114         }
9115
9116         macstat = le32toh(rxhdr.mac_status);
9117         if (macstat & BWN_RX_MAC_FCSERR) {
9118                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9119                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9120                         goto error;
9121                 }
9122         }
9123
9124         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9125         totlen = len + padding;
9126         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9127         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9128         if (m == NULL) {
9129                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9130                 goto error;
9131         }
9132         mp = mtod(m, unsigned char *);
9133         if (prq->prq_rev >= 8) {
9134                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9135                     prq->prq_base + BWN_PIO8_RXDATA);
9136                 if (totlen & 3) {
9137                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9138                         data = &(mp[totlen - 1]);
9139                         switch (totlen & 3) {
9140                         case 3:
9141                                 *data = (v32 >> 16);
9142                                 data--;
9143                         case 2:
9144                                 *data = (v32 >> 8);
9145                                 data--;
9146                         case 1:
9147                                 *data = v32;
9148                         }
9149                 }
9150         } else {
9151                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9152                     prq->prq_base + BWN_PIO_RXDATA);
9153                 if (totlen & 1) {
9154                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9155                         mp[totlen - 1] = v16;
9156                 }
9157         }
9158
9159         m->m_pkthdr.rcvif = ifp;
9160         m->m_len = m->m_pkthdr.len = totlen;
9161
9162         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9163
9164         return (1);
9165 error:
9166         if (prq->prq_rev >= 8)
9167                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9168                     BWN_PIO8_RXCTL_DATAREADY);
9169         else
9170                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9171         return (1);
9172 }
9173
9174 static int
9175 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9176     struct bwn_dmadesc_meta *meta, int init)
9177 {
9178         struct bwn_mac *mac = dr->dr_mac;
9179         struct bwn_dma *dma = &mac->mac_method.dma;
9180         struct bwn_rxhdr4 *hdr;
9181         bus_dmamap_t map;
9182         bus_addr_t paddr;
9183         struct mbuf *m;
9184         int error;
9185
9186         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9187         if (m == NULL) {
9188                 error = ENOBUFS;
9189
9190                 /*
9191                  * If the NIC is up and running, we need to:
9192                  * - Clear RX buffer's header.
9193                  * - Restore RX descriptor settings.
9194                  */
9195                 if (init)
9196                         return (error);
9197                 else
9198                         goto back;
9199         }
9200         m->m_len = m->m_pkthdr.len = MCLBYTES;
9201
9202         bwn_dma_set_redzone(dr, m);
9203
9204         /*
9205          * Try to load RX buf into temporary DMA map
9206          */
9207         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9208             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9209         if (error) {
9210                 m_freem(m);
9211
9212                 /*
9213                  * See the comment above
9214                  */
9215                 if (init)
9216                         return (error);
9217                 else
9218                         goto back;
9219         }
9220
9221         if (!init)
9222                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9223         meta->mt_m = m;
9224         meta->mt_paddr = paddr;
9225
9226         /*
9227          * Swap RX buf's DMA map with the loaded temporary one
9228          */
9229         map = meta->mt_dmap;
9230         meta->mt_dmap = dr->dr_spare_dmap;
9231         dr->dr_spare_dmap = map;
9232
9233 back:
9234         /*
9235          * Clear RX buf header
9236          */
9237         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9238         bzero(hdr, sizeof(*hdr));
9239         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9240             BUS_DMASYNC_PREWRITE);
9241
9242         /*
9243          * Setup RX buf descriptor
9244          */
9245         dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9246             sizeof(*hdr), 0, 0, 0);
9247         return (error);
9248 }
9249
9250 static void
9251 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9252                  bus_size_t mapsz __unused, int error)
9253 {
9254
9255         if (!error) {
9256                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9257                 *((bus_addr_t *)arg) = seg->ds_addr;
9258         }
9259 }
9260
9261 static int
9262 bwn_hwrate2ieeerate(int rate)
9263 {
9264
9265         switch (rate) {
9266         case BWN_CCK_RATE_1MB:
9267                 return (2);
9268         case BWN_CCK_RATE_2MB:
9269                 return (4);
9270         case BWN_CCK_RATE_5MB:
9271                 return (11);
9272         case BWN_CCK_RATE_11MB:
9273                 return (22);
9274         case BWN_OFDM_RATE_6MB:
9275                 return (12);
9276         case BWN_OFDM_RATE_9MB:
9277                 return (18);
9278         case BWN_OFDM_RATE_12MB:
9279                 return (24);
9280         case BWN_OFDM_RATE_18MB:
9281                 return (36);
9282         case BWN_OFDM_RATE_24MB:
9283                 return (48);
9284         case BWN_OFDM_RATE_36MB:
9285                 return (72);
9286         case BWN_OFDM_RATE_48MB:
9287                 return (96);
9288         case BWN_OFDM_RATE_54MB:
9289                 return (108);
9290         default:
9291                 printf("Ooops\n");
9292                 return (0);
9293         }
9294 }
9295
9296 static void
9297 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9298 {
9299         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9300         struct bwn_plcp6 *plcp;
9301         struct bwn_softc *sc = mac->mac_sc;
9302         struct ieee80211_frame_min *wh;
9303         struct ieee80211_node *ni;
9304         struct ifnet *ifp = sc->sc_ifp;
9305         struct ieee80211com *ic = ifp->if_l2com;
9306         uint32_t macstat;
9307         int padding, rate, rssi = 0, noise = 0, type;
9308         uint16_t phytype, phystat0, phystat3, chanstat;
9309         unsigned char *mp = mtod(m, unsigned char *);
9310         static int rx_mac_dec_rpt = 0;
9311
9312         BWN_ASSERT_LOCKED(sc);
9313
9314         phystat0 = le16toh(rxhdr->phy_status0);
9315         phystat3 = le16toh(rxhdr->phy_status3);
9316         macstat = le32toh(rxhdr->mac_status);
9317         chanstat = le16toh(rxhdr->channel);
9318         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9319
9320         if (macstat & BWN_RX_MAC_FCSERR)
9321                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9322         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9323                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9324         if (macstat & BWN_RX_MAC_DECERR)
9325                 goto drop;
9326
9327         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9328         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9329                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9330                     m->m_pkthdr.len);
9331                 goto drop;
9332         }
9333         plcp = (struct bwn_plcp6 *)(mp + padding);
9334         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9335         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9336                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9337                     m->m_pkthdr.len);
9338                 goto drop;
9339         }
9340         wh = mtod(m, struct ieee80211_frame_min *);
9341
9342         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9343                 device_printf(sc->sc_dev,
9344                     "RX decryption attempted (old %d keyidx %#x)\n",
9345                     BWN_ISOLDFMT(mac),
9346                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9347
9348         /* XXX calculating RSSI & noise & antenna */
9349
9350         if (phystat0 & BWN_RX_PHYST0_OFDM)
9351                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9352                     phytype == BWN_PHYTYPE_A);
9353         else
9354                 rate = bwn_plcp_get_cckrate(mac, plcp);
9355         if (rate == -1) {
9356                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9357                         goto drop;
9358         }
9359         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9360
9361         /* RX radio tap */
9362         if (ieee80211_radiotap_active(ic))
9363                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9364         m_adj(m, -IEEE80211_CRC_LEN);
9365
9366         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9367         noise = mac->mac_stats.link_noise;
9368
9369         ifp->if_ipackets++;
9370
9371         BWN_UNLOCK(sc);
9372
9373         ni = ieee80211_find_rxnode(ic, wh);
9374         if (ni != NULL) {
9375                 type = ieee80211_input(ni, m, rssi, noise);
9376                 ieee80211_free_node(ni);
9377         } else
9378                 type = ieee80211_input_all(ic, m, rssi, noise);
9379
9380         BWN_LOCK(sc);
9381         return;
9382 drop:
9383         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9384 }
9385
9386 static void
9387 bwn_dma_handle_txeof(struct bwn_mac *mac,
9388     const struct bwn_txstatus *status)
9389 {
9390         struct bwn_dma *dma = &mac->mac_method.dma;
9391         struct bwn_dma_ring *dr;
9392         struct bwn_dmadesc_generic *desc;
9393         struct bwn_dmadesc_meta *meta;
9394         struct bwn_softc *sc = mac->mac_sc;
9395         struct ieee80211_node *ni;
9396         struct ifnet *ifp = sc->sc_ifp;
9397         struct mbuf *m;
9398         int slot;
9399
9400         BWN_ASSERT_LOCKED(sc);
9401
9402         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9403         if (dr == NULL) {
9404                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9405                 return;
9406         }
9407         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9408
9409         while (1) {
9410                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9411                     ("%s:%d: fail", __func__, __LINE__));
9412                 dr->getdesc(dr, slot, &desc, &meta);
9413
9414                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9415                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9416                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9417                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9418
9419                 if (meta->mt_islast) {
9420                         KASSERT(meta->mt_m != NULL,
9421                             ("%s:%d: fail", __func__, __LINE__));
9422
9423                         ni = meta->mt_ni;
9424                         m = meta->mt_m;
9425                         if (ni != NULL) {
9426                                 /*
9427                                  * Do any tx complete callback. Note this must
9428                                  * be done before releasing the node reference.
9429                                  */
9430                                 if (m->m_flags & M_TXCB)
9431                                         ieee80211_process_callback(ni, m, 0);
9432                                 ieee80211_free_node(ni);
9433                                 meta->mt_ni = NULL;
9434                         }
9435                         m_freem(m);
9436                         meta->mt_m = NULL;
9437                 } else {
9438                         KASSERT(meta->mt_m == NULL,
9439                             ("%s:%d: fail", __func__, __LINE__));
9440                 }
9441
9442                 dr->dr_usedslot--;
9443                 if (meta->mt_islast) {
9444                         ifp->if_opackets++;
9445                         break;
9446                 }
9447                 slot = bwn_dma_nextslot(dr, slot);
9448         }
9449         sc->sc_watchdog_timer = 0;
9450         if (dr->dr_stop) {
9451                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9452                     ("%s:%d: fail", __func__, __LINE__));
9453                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9454                 dr->dr_stop = 0;
9455         }
9456 }
9457
9458 static void
9459 bwn_pio_handle_txeof(struct bwn_mac *mac,
9460     const struct bwn_txstatus *status)
9461 {
9462         struct bwn_pio_txqueue *tq;
9463         struct bwn_pio_txpkt *tp = NULL;
9464         struct bwn_softc *sc = mac->mac_sc;
9465         struct ifnet *ifp = sc->sc_ifp;
9466
9467         BWN_ASSERT_LOCKED(sc);
9468
9469         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9470         if (tq == NULL)
9471                 return;
9472
9473         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9474         tq->tq_free++;
9475
9476         if (tp->tp_ni != NULL) {
9477                 /*
9478                  * Do any tx complete callback.  Note this must
9479                  * be done before releasing the node reference.
9480                  */
9481                 if (tp->tp_m->m_flags & M_TXCB)
9482                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9483                 ieee80211_free_node(tp->tp_ni);
9484                 tp->tp_ni = NULL;
9485         }
9486         m_freem(tp->tp_m);
9487         tp->tp_m = NULL;
9488         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9489
9490         ifp->if_opackets++;
9491
9492         sc->sc_watchdog_timer = 0;
9493         if (tq->tq_stop) {
9494                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9495                 tq->tq_stop = 0;
9496         }
9497 }
9498
9499 static void
9500 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9501 {
9502         struct bwn_softc *sc = mac->mac_sc;
9503         struct bwn_phy *phy = &mac->mac_phy;
9504         struct ifnet *ifp = sc->sc_ifp;
9505         struct ieee80211com *ic = ifp->if_l2com;
9506         unsigned long now;
9507         int result;
9508
9509         BWN_GETTIME(now);
9510
9511         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9512                 return;
9513         phy->nexttime = now + 2 * 1000;
9514
9515         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9516             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9517                 return;
9518
9519         if (phy->recalc_txpwr != NULL) {
9520                 result = phy->recalc_txpwr(mac,
9521                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9522                 if (result == BWN_TXPWR_RES_DONE)
9523                         return;
9524                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9525                     ("%s: fail", __func__));
9526                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9527
9528                 ieee80211_runtask(ic, &mac->mac_txpower);
9529         }
9530 }
9531
9532 static uint16_t
9533 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9534 {
9535
9536         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9537 }
9538
9539 static uint32_t
9540 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9541 {
9542
9543         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9544 }
9545
9546 static void
9547 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9548 {
9549
9550         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9551 }
9552
9553 static void
9554 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9555 {
9556
9557         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9558 }
9559
9560 static int
9561 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9562 {
9563
9564         switch (rate) {
9565         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9566         case 12:
9567                 return (BWN_OFDM_RATE_6MB);
9568         case 18:
9569                 return (BWN_OFDM_RATE_9MB);
9570         case 24:
9571                 return (BWN_OFDM_RATE_12MB);
9572         case 36:
9573                 return (BWN_OFDM_RATE_18MB);
9574         case 48:
9575                 return (BWN_OFDM_RATE_24MB);
9576         case 72:
9577                 return (BWN_OFDM_RATE_36MB);
9578         case 96:
9579                 return (BWN_OFDM_RATE_48MB);
9580         case 108:
9581                 return (BWN_OFDM_RATE_54MB);
9582         /* CCK rates (NB: not IEEE std, device-specific) */
9583         case 2:
9584                 return (BWN_CCK_RATE_1MB);
9585         case 4:
9586                 return (BWN_CCK_RATE_2MB);
9587         case 11:
9588                 return (BWN_CCK_RATE_5MB);
9589         case 22:
9590                 return (BWN_CCK_RATE_11MB);
9591         }
9592
9593         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9594         return (BWN_CCK_RATE_1MB);
9595 }
9596
9597 static int
9598 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9599     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9600 {
9601         const struct bwn_phy *phy = &mac->mac_phy;
9602         struct bwn_softc *sc = mac->mac_sc;
9603         struct ieee80211_frame *wh;
9604         struct ieee80211_frame *protwh;
9605         struct ieee80211_frame_cts *cts;
9606         struct ieee80211_frame_rts *rts;
9607         const struct ieee80211_txparam *tp;
9608         struct ieee80211vap *vap = ni->ni_vap;
9609         struct ifnet *ifp = sc->sc_ifp;
9610         struct ieee80211com *ic = ifp->if_l2com;
9611         struct mbuf *mprot;
9612         unsigned int len;
9613         uint32_t macctl = 0;
9614         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9615         uint16_t phyctl = 0;
9616         uint8_t rate, rate_fb;
9617
9618         wh = mtod(m, struct ieee80211_frame *);
9619         memset(txhdr, 0, sizeof(*txhdr));
9620
9621         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9622         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9623         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9624
9625         /*
9626          * Find TX rate
9627          */
9628         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9629         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9630                 rate = rate_fb = tp->mgmtrate;
9631         else if (ismcast)
9632                 rate = rate_fb = tp->mcastrate;
9633         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9634                 rate = rate_fb = tp->ucastrate;
9635         else {
9636                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9637                 rate = ni->ni_txrate;
9638
9639                 if (rix > 0)
9640                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9641                             IEEE80211_RATE_VAL;
9642                 else
9643                         rate_fb = rate;
9644         }
9645
9646         sc->sc_tx_rate = rate;
9647
9648         rate = bwn_ieeerate2hwrate(sc, rate);
9649         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9650
9651         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9652             bwn_plcp_getcck(rate);
9653         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9654         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9655
9656         if ((rate_fb == rate) ||
9657             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9658             (*(u_int16_t *)wh->i_dur == htole16(0)))
9659                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9660         else
9661                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9662                     m->m_pkthdr.len, rate, isshort);
9663
9664         /* XXX TX encryption */
9665         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9666             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9667             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9668             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9669         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9670             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9671
9672         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9673             BWN_TX_EFT_FB_CCK;
9674         txhdr->chan = phy->chan;
9675         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9676             BWN_TX_PHY_ENC_CCK;
9677         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9678              rate == BWN_CCK_RATE_11MB))
9679                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9680
9681         /* XXX TX antenna selection */
9682
9683         switch (bwn_antenna_sanitize(mac, 0)) {
9684         case 0:
9685                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9686                 break;
9687         case 1:
9688                 phyctl |= BWN_TX_PHY_ANT0;
9689                 break;
9690         case 2:
9691                 phyctl |= BWN_TX_PHY_ANT1;
9692                 break;
9693         case 3:
9694                 phyctl |= BWN_TX_PHY_ANT2;
9695                 break;
9696         case 4:
9697                 phyctl |= BWN_TX_PHY_ANT3;
9698                 break;
9699         default:
9700                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9701         }
9702
9703         if (!ismcast)
9704                 macctl |= BWN_TX_MAC_ACK;
9705
9706         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9707         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9708             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9709                 macctl |= BWN_TX_MAC_LONGFRAME;
9710
9711         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9712                 /* XXX RTS rate is always 1MB??? */
9713                 rts_rate = BWN_CCK_RATE_1MB;
9714                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9715
9716                 protdur = ieee80211_compute_duration(ic->ic_rt,
9717                     m->m_pkthdr.len, rate, isshort) +
9718                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9719
9720                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9721                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9722                             (txhdr->body.old.rts_frame) :
9723                             (txhdr->body.new.rts_frame));
9724                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9725                             protdur);
9726                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9727                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9728                             mprot->m_pkthdr.len);
9729                         m_freem(mprot);
9730                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9731                         len = sizeof(struct ieee80211_frame_cts);
9732                 } else {
9733                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9734                             (txhdr->body.old.rts_frame) :
9735                             (txhdr->body.new.rts_frame));
9736                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9737                             isshort);
9738                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9739                             wh->i_addr2, protdur);
9740                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9741                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9742                             mprot->m_pkthdr.len);
9743                         m_freem(mprot);
9744                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9745                         len = sizeof(struct ieee80211_frame_rts);
9746                 }
9747                 len += IEEE80211_CRC_LEN;
9748                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9749                     &txhdr->body.old.rts_plcp :
9750                     &txhdr->body.new.rts_plcp), len, rts_rate);
9751                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9752                     rts_rate_fb);
9753
9754                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9755                     (&txhdr->body.old.rts_frame) :
9756                     (&txhdr->body.new.rts_frame));
9757                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9758
9759                 if (BWN_ISOFDMRATE(rts_rate)) {
9760                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9761                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9762                 } else {
9763                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9764                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9765                 }
9766                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9767                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9768         }
9769
9770         if (BWN_ISOLDFMT(mac))
9771                 txhdr->body.old.cookie = htole16(cookie);
9772         else
9773                 txhdr->body.new.cookie = htole16(cookie);
9774
9775         txhdr->macctl = htole32(macctl);
9776         txhdr->phyctl = htole16(phyctl);
9777
9778         /*
9779          * TX radio tap
9780          */
9781         if (ieee80211_radiotap_active_vap(vap)) {
9782                 sc->sc_tx_th.wt_flags = 0;
9783                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9784                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9785                 if (isshort &&
9786                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9787                      rate == BWN_CCK_RATE_11MB))
9788                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9789                 sc->sc_tx_th.wt_rate = rate;
9790
9791                 ieee80211_radiotap_tx(vap, m);
9792         }
9793
9794         return (0);
9795 }
9796
9797 static void
9798 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9799     const uint8_t rate)
9800 {
9801         uint32_t d, plen;
9802         uint8_t *raw = plcp->o.raw;
9803
9804         if (BWN_ISOFDMRATE(rate)) {
9805                 d = bwn_plcp_getofdm(rate);
9806                 KASSERT(!(octets & 0xf000),
9807                     ("%s:%d: fail", __func__, __LINE__));
9808                 d |= (octets << 5);
9809                 plcp->o.data = htole32(d);
9810         } else {
9811                 plen = octets * 16 / rate;
9812                 if ((octets * 16 % rate) > 0) {
9813                         plen++;
9814                         if ((rate == BWN_CCK_RATE_11MB)
9815                             && ((octets * 8 % 11) < 4)) {
9816                                 raw[1] = 0x84;
9817                         } else
9818                                 raw[1] = 0x04;
9819                 } else
9820                         raw[1] = 0x04;
9821                 plcp->o.data |= htole32(plen << 16);
9822                 raw[0] = bwn_plcp_getcck(rate);
9823         }
9824 }
9825
9826 static uint8_t
9827 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9828 {
9829         struct bwn_softc *sc = mac->mac_sc;
9830         uint8_t mask;
9831
9832         if (n == 0)
9833                 return (0);
9834         if (mac->mac_phy.gmode)
9835                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9836         else
9837                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9838         if (!(mask & (1 << (n - 1))))
9839                 return (0);
9840         return (n);
9841 }
9842
9843 static uint8_t
9844 bwn_get_fbrate(uint8_t bitrate)
9845 {
9846         switch (bitrate) {
9847         case BWN_CCK_RATE_1MB:
9848                 return (BWN_CCK_RATE_1MB);
9849         case BWN_CCK_RATE_2MB:
9850                 return (BWN_CCK_RATE_1MB);
9851         case BWN_CCK_RATE_5MB:
9852                 return (BWN_CCK_RATE_2MB);
9853         case BWN_CCK_RATE_11MB:
9854                 return (BWN_CCK_RATE_5MB);
9855         case BWN_OFDM_RATE_6MB:
9856                 return (BWN_CCK_RATE_5MB);
9857         case BWN_OFDM_RATE_9MB:
9858                 return (BWN_OFDM_RATE_6MB);
9859         case BWN_OFDM_RATE_12MB:
9860                 return (BWN_OFDM_RATE_9MB);
9861         case BWN_OFDM_RATE_18MB:
9862                 return (BWN_OFDM_RATE_12MB);
9863         case BWN_OFDM_RATE_24MB:
9864                 return (BWN_OFDM_RATE_18MB);
9865         case BWN_OFDM_RATE_36MB:
9866                 return (BWN_OFDM_RATE_24MB);
9867         case BWN_OFDM_RATE_48MB:
9868                 return (BWN_OFDM_RATE_36MB);
9869         case BWN_OFDM_RATE_54MB:
9870                 return (BWN_OFDM_RATE_48MB);
9871         }
9872         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9873         return (0);
9874 }
9875
9876 static uint32_t
9877 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9878     uint32_t ctl, const void *_data, int len)
9879 {
9880         struct bwn_softc *sc = mac->mac_sc;
9881         uint32_t value = 0;
9882         const uint8_t *data = _data;
9883
9884         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9885             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9886         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9887
9888         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9889             tq->tq_base + BWN_PIO8_TXDATA);
9890         if (len & 3) {
9891                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9892                     BWN_PIO8_TXCTL_24_31);
9893                 data = &(data[len - 1]);
9894                 switch (len & 3) {
9895                 case 3:
9896                         ctl |= BWN_PIO8_TXCTL_16_23;
9897                         value |= (uint32_t)(*data) << 16;
9898                         data--;
9899                 case 2:
9900                         ctl |= BWN_PIO8_TXCTL_8_15;
9901                         value |= (uint32_t)(*data) << 8;
9902                         data--;
9903                 case 1:
9904                         value |= (uint32_t)(*data);
9905                 }
9906                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9907                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9908         }
9909
9910         return (ctl);
9911 }
9912
9913 static void
9914 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9915     uint16_t offset, uint32_t value)
9916 {
9917
9918         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9919 }
9920
9921 static uint16_t
9922 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9923     uint16_t ctl, const void *_data, int len)
9924 {
9925         struct bwn_softc *sc = mac->mac_sc;
9926         const uint8_t *data = _data;
9927
9928         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9929         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9930
9931         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9932             tq->tq_base + BWN_PIO_TXDATA);
9933         if (len & 1) {
9934                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9935                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9936                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9937         }
9938
9939         return (ctl);
9940 }
9941
9942 static uint16_t
9943 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9944     uint16_t ctl, struct mbuf *m0)
9945 {
9946         int i, j = 0;
9947         uint16_t data = 0;
9948         const uint8_t *buf;
9949         struct mbuf *m = m0;
9950
9951         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9952         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9953
9954         for (; m != NULL; m = m->m_next) {
9955                 buf = mtod(m, const uint8_t *);
9956                 for (i = 0; i < m->m_len; i++) {
9957                         if (!((j++) % 2))
9958                                 data |= buf[i];
9959                         else {
9960                                 data |= (buf[i] << 8);
9961                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9962                                 data = 0;
9963                         }
9964                 }
9965         }
9966         if (m0->m_pkthdr.len % 2) {
9967                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9968                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9969                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9970         }
9971
9972         return (ctl);
9973 }
9974
9975 static void
9976 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9977 {
9978
9979         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9980                 return;
9981         BWN_WRITE_2(mac, 0x684, 510 + time);
9982         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9983 }
9984
9985 static struct bwn_dma_ring *
9986 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9987 {
9988
9989         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9990                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9991
9992         switch (prio) {
9993         case 3:
9994                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9995         case 2:
9996                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9997         case 0:
9998                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9999         case 1:
10000                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10001         }
10002         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10003         return (NULL);
10004 }
10005
10006 static int
10007 bwn_dma_getslot(struct bwn_dma_ring *dr)
10008 {
10009         int slot;
10010
10011         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10012
10013         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10014         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10015         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10016
10017         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10018         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10019         dr->dr_curslot = slot;
10020         dr->dr_usedslot++;
10021
10022         return (slot);
10023 }
10024
10025 static int
10026 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10027 {
10028         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10029         unsigned int a, b, c, d;
10030         unsigned int avg;
10031         uint32_t tmp;
10032
10033         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10034         a = tmp & 0xff;
10035         b = (tmp >> 8) & 0xff;
10036         c = (tmp >> 16) & 0xff;
10037         d = (tmp >> 24) & 0xff;
10038         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10039             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10040                 return (ENOENT);
10041         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10042             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10043             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10044
10045         if (ofdm) {
10046                 a = (a + 32) & 0x3f;
10047                 b = (b + 32) & 0x3f;
10048                 c = (c + 32) & 0x3f;
10049                 d = (d + 32) & 0x3f;
10050         }
10051
10052         avg = (a + b + c + d + 2) / 4;
10053         if (ofdm) {
10054                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10055                     & BWN_HF_4DB_CCK_POWERBOOST)
10056                         avg = (avg >= 13) ? (avg - 13) : 0;
10057         }
10058         return (avg);
10059 }
10060
10061 static void
10062 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10063 {
10064         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10065         int rfatt = *rfattp;
10066         int bbatt = *bbattp;
10067
10068         while (1) {
10069                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10070                         break;
10071                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10072                         break;
10073                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10074                         break;
10075                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10076                         break;
10077                 if (bbatt > lo->bbatt.max) {
10078                         bbatt -= 4;
10079                         rfatt += 1;
10080                         continue;
10081                 }
10082                 if (bbatt < lo->bbatt.min) {
10083                         bbatt += 4;
10084                         rfatt -= 1;
10085                         continue;
10086                 }
10087                 if (rfatt > lo->rfatt.max) {
10088                         rfatt -= 1;
10089                         bbatt += 4;
10090                         continue;
10091                 }
10092                 if (rfatt < lo->rfatt.min) {
10093                         rfatt += 1;
10094                         bbatt -= 4;
10095                         continue;
10096                 }
10097                 break;
10098         }
10099
10100         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10101         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10102 }
10103
10104 static void
10105 bwn_phy_lock(struct bwn_mac *mac)
10106 {
10107         struct bwn_softc *sc = mac->mac_sc;
10108         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10109
10110         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10111             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10112
10113         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10114                 bwn_psctl(mac, BWN_PS_AWAKE);
10115 }
10116
10117 static void
10118 bwn_phy_unlock(struct bwn_mac *mac)
10119 {
10120         struct bwn_softc *sc = mac->mac_sc;
10121         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10122
10123         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10124             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10125
10126         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10127                 bwn_psctl(mac, 0);
10128 }
10129
10130 static void
10131 bwn_rf_lock(struct bwn_mac *mac)
10132 {
10133
10134         BWN_WRITE_4(mac, BWN_MACCTL,
10135             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10136         BWN_READ_4(mac, BWN_MACCTL);
10137         DELAY(10);
10138 }
10139
10140 static void
10141 bwn_rf_unlock(struct bwn_mac *mac)
10142 {
10143
10144         BWN_READ_2(mac, BWN_PHYVER);
10145         BWN_WRITE_4(mac, BWN_MACCTL,
10146             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10147 }
10148
10149 static struct bwn_pio_txqueue *
10150 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10151     struct bwn_pio_txpkt **pack)
10152 {
10153         struct bwn_pio *pio = &mac->mac_method.pio;
10154         struct bwn_pio_txqueue *tq = NULL;
10155         unsigned int index;
10156
10157         switch (cookie & 0xf000) {
10158         case 0x1000:
10159                 tq = &pio->wme[WME_AC_BK];
10160                 break;
10161         case 0x2000:
10162                 tq = &pio->wme[WME_AC_BE];
10163                 break;
10164         case 0x3000:
10165                 tq = &pio->wme[WME_AC_VI];
10166                 break;
10167         case 0x4000:
10168                 tq = &pio->wme[WME_AC_VO];
10169                 break;
10170         case 0x5000:
10171                 tq = &pio->mcast;
10172                 break;
10173         }
10174         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10175         if (tq == NULL)
10176                 return (NULL);
10177         index = (cookie & 0x0fff);
10178         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10179         if (index >= N(tq->tq_pkts))
10180                 return (NULL);
10181         *pack = &tq->tq_pkts[index];
10182         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10183         return (tq);
10184 }
10185
10186 static void
10187 bwn_txpwr(void *arg, int npending)
10188 {
10189         struct bwn_mac *mac = arg;
10190         struct bwn_softc *sc = mac->mac_sc;
10191
10192         BWN_LOCK(sc);
10193         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10194             mac->mac_phy.set_txpwr != NULL)
10195                 mac->mac_phy.set_txpwr(mac);
10196         BWN_UNLOCK(sc);
10197 }
10198
10199 static void
10200 bwn_task_15s(struct bwn_mac *mac)
10201 {
10202         uint16_t reg;
10203
10204         if (mac->mac_fw.opensource) {
10205                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10206                 if (reg) {
10207                         bwn_restart(mac, "fw watchdog");
10208                         return;
10209                 }
10210                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10211         }
10212         if (mac->mac_phy.task_15s)
10213                 mac->mac_phy.task_15s(mac);
10214
10215         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10216 }
10217
10218 static void
10219 bwn_task_30s(struct bwn_mac *mac)
10220 {
10221
10222         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10223                 return;
10224         mac->mac_noise.noi_running = 1;
10225         mac->mac_noise.noi_nsamples = 0;
10226
10227         bwn_noise_gensample(mac);
10228 }
10229
10230 static void
10231 bwn_task_60s(struct bwn_mac *mac)
10232 {
10233
10234         if (mac->mac_phy.task_60s)
10235                 mac->mac_phy.task_60s(mac);
10236         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10237 }
10238
10239 static void
10240 bwn_tasks(void *arg)
10241 {
10242         struct bwn_mac *mac = arg;
10243         struct bwn_softc *sc = mac->mac_sc;
10244
10245         BWN_ASSERT_LOCKED(sc);
10246         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10247                 return;
10248
10249         if (mac->mac_task_state % 4 == 0)
10250                 bwn_task_60s(mac);
10251         if (mac->mac_task_state % 2 == 0)
10252                 bwn_task_30s(mac);
10253         bwn_task_15s(mac);
10254
10255         mac->mac_task_state++;
10256         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10257 }
10258
10259 static int
10260 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10261 {
10262         struct bwn_softc *sc = mac->mac_sc;
10263
10264         KASSERT(a == 0, ("not support APHY\n"));
10265
10266         switch (plcp->o.raw[0] & 0xf) {
10267         case 0xb:
10268                 return (BWN_OFDM_RATE_6MB);
10269         case 0xf:
10270                 return (BWN_OFDM_RATE_9MB);
10271         case 0xa:
10272                 return (BWN_OFDM_RATE_12MB);
10273         case 0xe:
10274                 return (BWN_OFDM_RATE_18MB);
10275         case 0x9:
10276                 return (BWN_OFDM_RATE_24MB);
10277         case 0xd:
10278                 return (BWN_OFDM_RATE_36MB);
10279         case 0x8:
10280                 return (BWN_OFDM_RATE_48MB);
10281         case 0xc:
10282                 return (BWN_OFDM_RATE_54MB);
10283         }
10284         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10285             plcp->o.raw[0] & 0xf);
10286         return (-1);
10287 }
10288
10289 static int
10290 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10291 {
10292         struct bwn_softc *sc = mac->mac_sc;
10293
10294         switch (plcp->o.raw[0]) {
10295         case 0x0a:
10296                 return (BWN_CCK_RATE_1MB);
10297         case 0x14:
10298                 return (BWN_CCK_RATE_2MB);
10299         case 0x37:
10300                 return (BWN_CCK_RATE_5MB);
10301         case 0x6e:
10302                 return (BWN_CCK_RATE_11MB);
10303         }
10304         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10305         return (-1);
10306 }
10307
10308 static void
10309 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10310     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10311     int rssi, int noise)
10312 {
10313         struct bwn_softc *sc = mac->mac_sc;
10314         const struct ieee80211_frame_min *wh;
10315         uint64_t tsf;
10316         uint16_t low_mactime_now;
10317
10318         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10319                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10320
10321         wh = mtod(m, const struct ieee80211_frame_min *);
10322         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10323                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10324
10325         bwn_tsf_read(mac, &tsf);
10326         low_mactime_now = tsf;
10327         tsf = tsf & ~0xffffULL;
10328         tsf += le16toh(rxhdr->mac_time);
10329         if (low_mactime_now < le16toh(rxhdr->mac_time))
10330                 tsf -= 0x10000;
10331
10332         sc->sc_rx_th.wr_tsf = tsf;
10333         sc->sc_rx_th.wr_rate = rate;
10334         sc->sc_rx_th.wr_antsignal = rssi;
10335         sc->sc_rx_th.wr_antnoise = noise;
10336 }
10337
10338 static void
10339 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10340 {
10341         uint32_t low, high;
10342
10343         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10344             ("%s:%d: fail", __func__, __LINE__));
10345
10346         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10347         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10348         *tsf = high;
10349         *tsf <<= 32;
10350         *tsf |= low;
10351 }
10352
10353 static int
10354 bwn_dma_attach(struct bwn_mac *mac)
10355 {
10356         struct bwn_dma *dma = &mac->mac_method.dma;
10357         struct bwn_softc *sc = mac->mac_sc;
10358         bus_addr_t lowaddr = 0;
10359         int error;
10360
10361         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10362                 return (0);
10363
10364         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10365
10366         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10367
10368         dma->dmatype = bwn_dma_gettype(mac);
10369         if (dma->dmatype == BWN_DMA_30BIT)
10370                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10371         else if (dma->dmatype == BWN_DMA_32BIT)
10372                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10373         else
10374                 lowaddr = BUS_SPACE_MAXADDR;
10375
10376         /*
10377          * Create top level DMA tag
10378          */
10379         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10380                                BWN_ALIGN, 0,            /* alignment, bounds */
10381                                lowaddr,                 /* lowaddr */
10382                                BUS_SPACE_MAXADDR,       /* highaddr */
10383                                NULL, NULL,              /* filter, filterarg */
10384                                MAXBSIZE,                /* maxsize */
10385                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10386                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10387                                0,                       /* flags */
10388                                NULL, NULL,              /* lockfunc, lockarg */
10389                                &dma->parent_dtag);
10390         if (error) {
10391                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10392                 return (error);
10393         }
10394
10395         /*
10396          * Create TX/RX mbuf DMA tag
10397          */
10398         error = bus_dma_tag_create(dma->parent_dtag,
10399                                 1,
10400                                 0,
10401                                 BUS_SPACE_MAXADDR,
10402                                 BUS_SPACE_MAXADDR,
10403                                 NULL, NULL,
10404                                 MCLBYTES,
10405                                 1,
10406                                 BUS_SPACE_MAXSIZE_32BIT,
10407                                 0,
10408                                 NULL, NULL,
10409                                 &dma->rxbuf_dtag);
10410         if (error) {
10411                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10412                 goto fail0;
10413         }
10414         error = bus_dma_tag_create(dma->parent_dtag,
10415                                 1,
10416                                 0,
10417                                 BUS_SPACE_MAXADDR,
10418                                 BUS_SPACE_MAXADDR,
10419                                 NULL, NULL,
10420                                 MCLBYTES,
10421                                 1,
10422                                 BUS_SPACE_MAXSIZE_32BIT,
10423                                 0,
10424                                 NULL, NULL,
10425                                 &dma->txbuf_dtag);
10426         if (error) {
10427                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10428                 goto fail1;
10429         }
10430
10431         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10432         if (!dma->wme[WME_AC_BK])
10433                 goto fail2;
10434
10435         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10436         if (!dma->wme[WME_AC_BE])
10437                 goto fail3;
10438
10439         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10440         if (!dma->wme[WME_AC_VI])
10441                 goto fail4;
10442
10443         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10444         if (!dma->wme[WME_AC_VO])
10445                 goto fail5;
10446
10447         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10448         if (!dma->mcast)
10449                 goto fail6;
10450         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10451         if (!dma->rx)
10452                 goto fail7;
10453
10454         return (error);
10455
10456 fail7:  bwn_dma_ringfree(&dma->mcast);
10457 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10458 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10459 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10460 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10461 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10462 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10463 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10464         return (error);
10465 }
10466
10467 static struct bwn_dma_ring *
10468 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10469     uint16_t cookie, int *slot)
10470 {
10471         struct bwn_dma *dma = &mac->mac_method.dma;
10472         struct bwn_dma_ring *dr;
10473         struct bwn_softc *sc = mac->mac_sc;
10474
10475         BWN_ASSERT_LOCKED(mac->mac_sc);
10476
10477         switch (cookie & 0xf000) {
10478         case 0x1000:
10479                 dr = dma->wme[WME_AC_BK];
10480                 break;
10481         case 0x2000:
10482                 dr = dma->wme[WME_AC_BE];
10483                 break;
10484         case 0x3000:
10485                 dr = dma->wme[WME_AC_VI];
10486                 break;
10487         case 0x4000:
10488                 dr = dma->wme[WME_AC_VO];
10489                 break;
10490         case 0x5000:
10491                 dr = dma->mcast;
10492                 break;
10493         default:
10494                 dr = NULL;
10495                 KASSERT(0 == 1,
10496                     ("invalid cookie value %d", cookie & 0xf000));
10497         }
10498         *slot = (cookie & 0x0fff);
10499         if (*slot < 0 || *slot >= dr->dr_numslots) {
10500                 /*
10501                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10502                  * that it occurs events which have same H/W sequence numbers.
10503                  * When it's occurred just prints a WARNING msgs and ignores.
10504                  */
10505                 KASSERT(status->seq == dma->lastseq,
10506                     ("%s:%d: fail", __func__, __LINE__));
10507                 device_printf(sc->sc_dev,
10508                     "out of slot ranges (0 < %d < %d)\n", *slot,
10509                     dr->dr_numslots);
10510                 return (NULL);
10511         }
10512         dma->lastseq = status->seq;
10513         return (dr);
10514 }
10515
10516 static void
10517 bwn_dma_stop(struct bwn_mac *mac)
10518 {
10519         struct bwn_dma *dma;
10520
10521         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10522                 return;
10523         dma = &mac->mac_method.dma;
10524
10525         bwn_dma_ringstop(&dma->rx);
10526         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10527         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10528         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10529         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10530         bwn_dma_ringstop(&dma->mcast);
10531 }
10532
10533 static void
10534 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10535 {
10536
10537         if (dr == NULL)
10538                 return;
10539
10540         bwn_dma_cleanup(*dr);
10541 }
10542
10543 static void
10544 bwn_pio_stop(struct bwn_mac *mac)
10545 {
10546         struct bwn_pio *pio;
10547
10548         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10549                 return;
10550         pio = &mac->mac_method.pio;
10551
10552         bwn_destroy_queue_tx(&pio->mcast);
10553         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10554         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10555         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10556         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10557 }
10558
10559 static void
10560 bwn_led_attach(struct bwn_mac *mac)
10561 {
10562         struct bwn_softc *sc = mac->mac_sc;
10563         const uint8_t *led_act = NULL;
10564         uint16_t val[BWN_LED_MAX];
10565         int i;
10566
10567         sc->sc_led_idle = (2350 * hz) / 1000;
10568         sc->sc_led_blink = 1;
10569
10570         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10571                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10572                     bwn_vendor_led_act[i].vid) {
10573                         led_act = bwn_vendor_led_act[i].led_act;
10574                         break;
10575                 }
10576         }
10577         if (led_act == NULL)
10578                 led_act = bwn_default_led_act;
10579
10580         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10581         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10582         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10583         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10584
10585         for (i = 0; i < BWN_LED_MAX; ++i) {
10586                 struct bwn_led *led = &sc->sc_leds[i];
10587
10588                 if (val[i] == 0xff) {
10589                         led->led_act = led_act[i];
10590                 } else {
10591                         if (val[i] & BWN_LED_ACT_LOW)
10592                                 led->led_flags |= BWN_LED_F_ACTLOW;
10593                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10594                 }
10595                 led->led_mask = (1 << i);
10596
10597                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10598                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10599                     led->led_act == BWN_LED_ACT_BLINK) {
10600                         led->led_flags |= BWN_LED_F_BLINK;
10601                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10602                                 led->led_flags |= BWN_LED_F_POLLABLE;
10603                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10604                                 led->led_flags |= BWN_LED_F_SLOW;
10605
10606                         if (sc->sc_blink_led == NULL) {
10607                                 sc->sc_blink_led = led;
10608                                 if (led->led_flags & BWN_LED_F_SLOW)
10609                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10610                         }
10611                 }
10612
10613                 DPRINTF(sc, BWN_DEBUG_LED,
10614                     "%dth led, act %d, lowact %d\n", i,
10615                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10616         }
10617         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10618 }
10619
10620 static __inline uint16_t
10621 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10622 {
10623
10624         if (led->led_flags & BWN_LED_F_ACTLOW)
10625                 on = !on;
10626         if (on)
10627                 val |= led->led_mask;
10628         else
10629                 val &= ~led->led_mask;
10630         return val;
10631 }
10632
10633 static void
10634 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10635 {
10636         struct bwn_softc *sc = mac->mac_sc;
10637         struct ifnet *ifp = sc->sc_ifp;
10638         struct ieee80211com *ic = ifp->if_l2com;
10639         uint16_t val;
10640         int i;
10641
10642         if (nstate == IEEE80211_S_INIT) {
10643                 callout_stop(&sc->sc_led_blink_ch);
10644                 sc->sc_led_blinking = 0;
10645         }
10646
10647         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10648                 return;
10649
10650         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10651         for (i = 0; i < BWN_LED_MAX; ++i) {
10652                 struct bwn_led *led = &sc->sc_leds[i];
10653                 int on;
10654
10655                 if (led->led_act == BWN_LED_ACT_UNKN ||
10656                     led->led_act == BWN_LED_ACT_NULL)
10657                         continue;
10658
10659                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10660                     nstate != IEEE80211_S_INIT)
10661                         continue;
10662
10663                 switch (led->led_act) {
10664                 case BWN_LED_ACT_ON:    /* Always on */
10665                         on = 1;
10666                         break;
10667                 case BWN_LED_ACT_OFF:   /* Always off */
10668                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10669                         on = 0;
10670                         break;
10671                 default:
10672                         on = 1;
10673                         switch (nstate) {
10674                         case IEEE80211_S_INIT:
10675                                 on = 0;
10676                                 break;
10677                         case IEEE80211_S_RUN:
10678                                 if (led->led_act == BWN_LED_ACT_11G &&
10679                                     ic->ic_curmode != IEEE80211_MODE_11G)
10680                                         on = 0;
10681                                 break;
10682                         default:
10683                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10684                                         on = 0;
10685                                 break;
10686                         }
10687                         break;
10688                 }
10689
10690                 val = bwn_led_onoff(led, val, on);
10691         }
10692         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10693 }
10694
10695 static void
10696 bwn_led_event(struct bwn_mac *mac, int event)
10697 {
10698         struct bwn_softc *sc = mac->mac_sc;
10699         struct bwn_led *led = sc->sc_blink_led;
10700         int rate;
10701
10702         if (event == BWN_LED_EVENT_POLL) {
10703                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10704                         return;
10705                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10706                         return;
10707         }
10708
10709         sc->sc_led_ticks = ticks;
10710         if (sc->sc_led_blinking)
10711                 return;
10712
10713         switch (event) {
10714         case BWN_LED_EVENT_RX:
10715                 rate = sc->sc_rx_rate;
10716                 break;
10717         case BWN_LED_EVENT_TX:
10718                 rate = sc->sc_tx_rate;
10719                 break;
10720         case BWN_LED_EVENT_POLL:
10721                 rate = 0;
10722                 break;
10723         default:
10724                 panic("unknown LED event %d\n", event);
10725                 break;
10726         }
10727         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10728             bwn_led_duration[rate].off_dur);
10729 }
10730
10731 static void
10732 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10733 {
10734         struct bwn_softc *sc = mac->mac_sc;
10735         struct bwn_led *led = sc->sc_blink_led;
10736         uint16_t val;
10737
10738         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10739         val = bwn_led_onoff(led, val, 1);
10740         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10741
10742         if (led->led_flags & BWN_LED_F_SLOW) {
10743                 BWN_LED_SLOWDOWN(on_dur);
10744                 BWN_LED_SLOWDOWN(off_dur);
10745         }
10746
10747         sc->sc_led_blinking = 1;
10748         sc->sc_led_blink_offdur = off_dur;
10749
10750         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10751 }
10752
10753 static void
10754 bwn_led_blink_next(void *arg)
10755 {
10756         struct bwn_mac *mac = arg;
10757         struct bwn_softc *sc = mac->mac_sc;
10758         uint16_t val;
10759
10760         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10761         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10762         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10763
10764         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10765             bwn_led_blink_end, mac);
10766 }
10767
10768 static void
10769 bwn_led_blink_end(void *arg)
10770 {
10771         struct bwn_mac *mac = arg;
10772         struct bwn_softc *sc = mac->mac_sc;
10773
10774         sc->sc_led_blinking = 0;
10775 }
10776
10777 static int
10778 bwn_suspend(device_t dev)
10779 {
10780         struct bwn_softc *sc = device_get_softc(dev);
10781
10782         bwn_stop(sc, 1);
10783         return (0);
10784 }
10785
10786 static int
10787 bwn_resume(device_t dev)
10788 {
10789         struct bwn_softc *sc = device_get_softc(dev);
10790         struct ifnet *ifp = sc->sc_ifp;
10791
10792         if (ifp->if_flags & IFF_UP)
10793                 bwn_init(sc);
10794         return (0);
10795 }
10796
10797 static void
10798 bwn_rfswitch(void *arg)
10799 {
10800         struct bwn_softc *sc = arg;
10801         struct bwn_mac *mac = sc->sc_curmac;
10802         int cur = 0, prev = 0;
10803
10804         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10805             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10806
10807         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10808                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10809                         & BWN_RF_HWENABLED_HI_MASK))
10810                         cur = 1;
10811         } else {
10812                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10813                     & BWN_RF_HWENABLED_LO_MASK)
10814                         cur = 1;
10815         }
10816
10817         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10818                 prev = 1;
10819
10820         if (cur != prev) {
10821                 if (cur)
10822                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10823                 else
10824                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10825
10826                 device_printf(sc->sc_dev,
10827                     "status of RF switch is changed to %s\n",
10828                     cur ? "ON" : "OFF");
10829                 if (cur != mac->mac_phy.rf_on) {
10830                         if (cur)
10831                                 bwn_rf_turnon(mac);
10832                         else
10833                                 bwn_rf_turnoff(mac);
10834                 }
10835         }
10836
10837         callout_schedule(&sc->sc_rfswitch_ch, hz);
10838 }
10839
10840 static void
10841 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10842 {
10843         struct bwn_phy *phy = &mac->mac_phy;
10844         struct bwn_phy_lp *plp = &phy->phy_lp;
10845
10846         plp->plp_antenna = BWN_ANT_DEFAULT;
10847 }
10848
10849 static int
10850 bwn_phy_lp_init(struct bwn_mac *mac)
10851 {
10852         static const struct bwn_stxtable tables[] = {
10853                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10854                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10855                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10856                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10857                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10858                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10859                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10860                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10861                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10862                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10863                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10864                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10865                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10866                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10867                 { 2, 11, 0x40, 0, 0x0f }
10868         };
10869         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10870         struct bwn_softc *sc = mac->mac_sc;
10871         const struct bwn_stxtable *st;
10872         struct ifnet *ifp = sc->sc_ifp;
10873         struct ieee80211com *ic = ifp->if_l2com;
10874         int i, error;
10875         uint16_t tmp;
10876
10877         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10878         bwn_phy_lp_bbinit(mac);
10879
10880         /* initialize RF */
10881         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10882         DELAY(1);
10883         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10884         DELAY(1);
10885
10886         if (mac->mac_phy.rf_ver == 0x2062)
10887                 bwn_phy_lp_b2062_init(mac);
10888         else {
10889                 bwn_phy_lp_b2063_init(mac);
10890
10891                 /* synchronize stx table. */
10892                 for (i = 0; i < N(tables); i++) {
10893                         st = &tables[i];
10894                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10895                         tmp >>= st->st_rfshift;
10896                         tmp <<= st->st_physhift;
10897                         BWN_PHY_SETMASK(mac,
10898                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10899                             ~(st->st_mask << st->st_physhift), tmp);
10900                 }
10901
10902                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10903                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10904         }
10905
10906         /* calibrate RC */
10907         if (mac->mac_phy.rev >= 2)
10908                 bwn_phy_lp_rxcal_r2(mac);
10909         else if (!plp->plp_rccap) {
10910                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10911                         bwn_phy_lp_rccal_r12(mac);
10912         } else
10913                 bwn_phy_lp_set_rccap(mac);
10914
10915         error = bwn_phy_lp_switch_channel(mac, 7);
10916         if (error)
10917                 device_printf(sc->sc_dev,
10918                     "failed to change channel 7 (%d)\n", error);
10919         bwn_phy_lp_txpctl_init(mac);
10920         bwn_phy_lp_calib(mac);
10921         return (0);
10922 }
10923
10924 static uint16_t
10925 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10926 {
10927
10928         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10929         return (BWN_READ_2(mac, BWN_PHYDATA));
10930 }
10931
10932 static void
10933 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10934 {
10935
10936         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10937         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10938 }
10939
10940 static void
10941 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10942     uint16_t set)
10943 {
10944
10945         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10946         BWN_WRITE_2(mac, BWN_PHYDATA,
10947             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10948 }
10949
10950 static uint16_t
10951 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10952 {
10953
10954         KASSERT(reg != 1, ("unaccessible register %d", reg));
10955         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10956                 reg |= 0x100;
10957         if (mac->mac_phy.rev >= 2)
10958                 reg |= 0x200;
10959         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10960         return BWN_READ_2(mac, BWN_RFDATALO);
10961 }
10962
10963 static void
10964 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10965 {
10966
10967         KASSERT(reg != 1, ("unaccessible register %d", reg));
10968         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10969         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10970 }
10971
10972 static void
10973 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10974 {
10975
10976         if (on) {
10977                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10978                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10979                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10980                 return;
10981         }
10982
10983         if (mac->mac_phy.rev >= 2) {
10984                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10985                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10986                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10987                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10988                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10989                 return;
10990         }
10991
10992         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10993         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10994         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10995         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10996 }
10997
10998 static int
10999 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11000 {
11001         struct bwn_phy *phy = &mac->mac_phy;
11002         struct bwn_phy_lp *plp = &phy->phy_lp;
11003         int error;
11004
11005         if (phy->rf_ver == 0x2063) {
11006                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11007                 if (error)
11008                         return (error);
11009         } else {
11010                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11011                 if (error)
11012                         return (error);
11013                 bwn_phy_lp_set_anafilter(mac, chan);
11014                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11015         }
11016
11017         plp->plp_chan = chan;
11018         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11019         return (0);
11020 }
11021
11022 static uint32_t
11023 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11024 {
11025         struct bwn_softc *sc = mac->mac_sc;
11026         struct ifnet *ifp = sc->sc_ifp;
11027         struct ieee80211com *ic = ifp->if_l2com;
11028
11029         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11030 }
11031
11032 static void
11033 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11034 {
11035         struct bwn_phy *phy = &mac->mac_phy;
11036         struct bwn_phy_lp *plp = &phy->phy_lp;
11037
11038         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11039                 return;
11040
11041         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11042         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11043         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11044         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11045         plp->plp_antenna = antenna;
11046 }
11047
11048 static void
11049 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11050 {
11051
11052         bwn_phy_lp_calib(mac);
11053 }
11054
11055 static void
11056 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11057 {
11058         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11059         struct bwn_softc *sc = mac->mac_sc;
11060         struct ifnet *ifp = sc->sc_ifp;
11061         struct ieee80211com *ic = ifp->if_l2com;
11062
11063         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11064                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11065                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11066                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11067                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11068                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11069                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11070                 return;
11071         }
11072
11073         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11074         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11075         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11076         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11077         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11078         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11079         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11080         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11081 }
11082
11083 static void
11084 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11085 {
11086
11087         bwn_phy_lp_tblinit(mac);
11088         if (mac->mac_phy.rev >= 2)
11089                 bwn_phy_lp_bbinit_r2(mac);
11090         else
11091                 bwn_phy_lp_bbinit_r01(mac);
11092 }
11093
11094 static void
11095 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11096 {
11097         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11098         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11099         struct bwn_softc *sc = mac->mac_sc;
11100         struct ifnet *ifp = sc->sc_ifp;
11101         struct ieee80211com *ic = ifp->if_l2com;
11102
11103         bwn_phy_lp_set_txgain(mac,
11104             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11105         bwn_phy_lp_set_bbmult(mac, 150);
11106 }
11107
11108 static void
11109 bwn_phy_lp_calib(struct bwn_mac *mac)
11110 {
11111         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11112         struct bwn_softc *sc = mac->mac_sc;
11113         struct ifnet *ifp = sc->sc_ifp;
11114         struct ieee80211com *ic = ifp->if_l2com;
11115         const struct bwn_rxcompco *rc = NULL;
11116         struct bwn_txgain ogain;
11117         int i, omode, oafeovr, orf, obbmult;
11118         uint8_t mode, fc = 0;
11119
11120         if (plp->plp_chanfullcal != plp->plp_chan) {
11121                 plp->plp_chanfullcal = plp->plp_chan;
11122                 fc = 1;
11123         }
11124
11125         bwn_mac_suspend(mac);
11126
11127         /* BlueTooth Coexistance Override */
11128         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11129         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11130
11131         if (mac->mac_phy.rev >= 2)
11132                 bwn_phy_lp_digflt_save(mac);
11133         bwn_phy_lp_get_txpctlmode(mac);
11134         mode = plp->plp_txpctlmode;
11135         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11136         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11137                 bwn_phy_lp_bugfix(mac);
11138         if (mac->mac_phy.rev >= 2 && fc == 1) {
11139                 bwn_phy_lp_get_txpctlmode(mac);
11140                 omode = plp->plp_txpctlmode;
11141                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11142                 if (oafeovr)
11143                         ogain = bwn_phy_lp_get_txgain(mac);
11144                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11145                 obbmult = bwn_phy_lp_get_bbmult(mac);
11146                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11147                 if (oafeovr)
11148                         bwn_phy_lp_set_txgain(mac, &ogain);
11149                 bwn_phy_lp_set_bbmult(mac, obbmult);
11150                 bwn_phy_lp_set_txpctlmode(mac, omode);
11151                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11152         }
11153         bwn_phy_lp_set_txpctlmode(mac, mode);
11154         if (mac->mac_phy.rev >= 2)
11155                 bwn_phy_lp_digflt_restore(mac);
11156
11157         /* do RX IQ Calculation; assumes that noise is true. */
11158         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11159                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11160                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11161                                 rc = &bwn_rxcompco_5354[i];
11162                 }
11163         } else if (mac->mac_phy.rev >= 2)
11164                 rc = &bwn_rxcompco_r2;
11165         else {
11166                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11167                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11168                                 rc = &bwn_rxcompco_r12[i];
11169                 }
11170         }
11171         if (rc == NULL)
11172                 goto fail;
11173
11174         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11175         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11176
11177         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11178
11179         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11180                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11181                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11182         } else {
11183                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11184                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11185         }
11186
11187         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11188         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11189         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11190         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11191         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11192         bwn_phy_lp_set_deaf(mac, 0);
11193         /* XXX no checking return value? */
11194         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11195         bwn_phy_lp_clear_deaf(mac, 0);
11196         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11197         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11198         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11199
11200         /* disable RX GAIN override. */
11201         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11202         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11203         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11204         if (mac->mac_phy.rev >= 2) {
11205                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11206                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11207                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11208                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11209                 }
11210         } else {
11211                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11212         }
11213
11214         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11215         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11216 fail:
11217         bwn_mac_enable(mac);
11218 }
11219
11220 static void
11221 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11222 {
11223
11224         if (on) {
11225                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11226                 return;
11227         }
11228
11229         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11230         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11231 }
11232
11233 static int
11234 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11235 {
11236         static const struct bwn_b206x_chan *bc = NULL;
11237         struct bwn_softc *sc = mac->mac_sc;
11238         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11239             tmp[6];
11240         uint16_t old, scale, tmp16;
11241         int i, div;
11242
11243         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11244                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11245                         bc = &bwn_b2063_chantable[i];
11246                         break;
11247                 }
11248         }
11249         if (bc == NULL)
11250                 return (EINVAL);
11251
11252         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11253         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11254         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11255         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11256         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11257         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11258         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11259         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11260         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11261         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11262         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11263         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11264
11265         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11266         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11267
11268         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11269         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11270         freqref = freqxtal * 3;
11271         div = (freqxtal <= 26000000 ? 1 : 2);
11272         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11273         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11274                 999999) / 1000000) + 1;
11275
11276         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11277         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11278             0xfff8, timeout >> 2);
11279         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11280             0xff9f,timeout << 5);
11281         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11282
11283         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11284         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11285         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11286
11287         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11288             (timeoutref + 1)) - 1;
11289         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11290             0xf0, count >> 8);
11291         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11292
11293         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11294         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11295         while (tmp[1] >= freqref) {
11296                 tmp[0]++;
11297                 tmp[1] -= freqref;
11298         }
11299         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11300         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11301         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11302         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11303         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11304
11305         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11306         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11307         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11308         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11309
11310         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11311         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11312
11313         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11314                 scale = 1;
11315                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11316         } else {
11317                 scale = 0;
11318                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11319         }
11320         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11321         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11322
11323         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11324             (scale + 1);
11325         if (tmp[5] > 150)
11326                 tmp[5] = 0;
11327
11328         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11329         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11330
11331         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11332         if (freqxtal > 26000000)
11333                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11334         else
11335                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11336
11337         if (val[0] == 45)
11338                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11339         else
11340                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11341
11342         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11343         DELAY(1);
11344         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11345
11346         /* VCO Calibration */
11347         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11348         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11349         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11350         DELAY(1);
11351         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11352         DELAY(1);
11353         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11354         DELAY(1);
11355         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11356         DELAY(300);
11357         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11358
11359         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11360         return (0);
11361 }
11362
11363 static int
11364 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11365 {
11366         struct bwn_softc *sc = mac->mac_sc;
11367         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11368         const struct bwn_b206x_chan *bc = NULL;
11369         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11370         uint32_t tmp[9];
11371         int i;
11372
11373         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11374                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11375                         bc = &bwn_b2062_chantable[i];
11376                         break;
11377                 }
11378         }
11379
11380         if (bc == NULL)
11381                 return (EINVAL);
11382
11383         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11384         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11385         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11386         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11387         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11388         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11389         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11390         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11391         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11392         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11393
11394         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11395         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11396         bwn_phy_lp_b2062_reset_pllbias(mac);
11397         tmp[0] = freqxtal / 1000;
11398         tmp[1] = plp->plp_div * 1000;
11399         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11400         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11401                 tmp[2] *= 2;
11402         tmp[3] = 48 * tmp[0];
11403         tmp[5] = tmp[2] / tmp[3];
11404         tmp[6] = tmp[2] % tmp[3];
11405         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11406         tmp[4] = tmp[6] * 0x100;
11407         tmp[5] = tmp[4] / tmp[3];
11408         tmp[6] = tmp[4] % tmp[3];
11409         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11410         tmp[4] = tmp[6] * 0x100;
11411         tmp[5] = tmp[4] / tmp[3];
11412         tmp[6] = tmp[4] % tmp[3];
11413         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11414         tmp[4] = tmp[6] * 0x100;
11415         tmp[5] = tmp[4] / tmp[3];
11416         tmp[6] = tmp[4] % tmp[3];
11417         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11418             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11419         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11420         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11421         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11422         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11423
11424         bwn_phy_lp_b2062_vco_calib(mac);
11425         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11426                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11427                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11428                 bwn_phy_lp_b2062_reset_pllbias(mac);
11429                 bwn_phy_lp_b2062_vco_calib(mac);
11430                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11431                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11432                         return (EIO);
11433                 }
11434         }
11435         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11436         return (0);
11437 }
11438
11439 static void
11440 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11441 {
11442         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11443         uint16_t tmp = (channel == 14);
11444
11445         if (mac->mac_phy.rev < 2) {
11446                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11447                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11448                         bwn_phy_lp_set_rccap(mac);
11449                 return;
11450         }
11451
11452         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11453 }
11454
11455 static void
11456 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11457 {
11458         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11459         struct bwn_softc *sc = mac->mac_sc;
11460         struct ifnet *ifp = sc->sc_ifp;
11461         struct ieee80211com *ic = ifp->if_l2com;
11462         uint16_t iso, tmp[3];
11463
11464         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11465
11466         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11467                 iso = plp->plp_txisoband_m;
11468         else if (freq <= 5320)
11469                 iso = plp->plp_txisoband_l;
11470         else if (freq <= 5700)
11471                 iso = plp->plp_txisoband_m;
11472         else
11473                 iso = plp->plp_txisoband_h;
11474
11475         tmp[0] = ((iso - 26) / 12) << 12;
11476         tmp[1] = tmp[0] + 0x1000;
11477         tmp[2] = tmp[0] + 0x2000;
11478
11479         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11480         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11481 }
11482
11483 static void
11484 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11485 {
11486         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11487         int i;
11488         static const uint16_t addr[] = {
11489                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11490                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11491                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11492                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11493                 BWN_PHY_OFDM(0xcf),
11494         };
11495         static const uint16_t val[] = {
11496                 0xde5e, 0xe832, 0xe331, 0x4d26,
11497                 0x0026, 0x1420, 0x0020, 0xfe08,
11498                 0x0008,
11499         };
11500
11501         for (i = 0; i < N(addr); i++) {
11502                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11503                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11504         }
11505 }
11506
11507 static void
11508 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11509 {
11510         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11511         struct bwn_softc *sc = mac->mac_sc;
11512         uint16_t ctl;
11513
11514         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11515         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11516         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11517                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11518                 break;
11519         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11520                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11521                 break;
11522         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11523                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11524                 break;
11525         default:
11526                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11527                 device_printf(sc->sc_dev, "unknown command mode\n");
11528                 break;
11529         }
11530 }
11531
11532 static void
11533 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11534 {
11535         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11536         uint16_t ctl;
11537         uint8_t old;
11538
11539         bwn_phy_lp_get_txpctlmode(mac);
11540         old = plp->plp_txpctlmode;
11541         if (old == mode)
11542                 return;
11543         plp->plp_txpctlmode = mode;
11544
11545         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11546                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11547                     plp->plp_tssiidx);
11548                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11549                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11550
11551                 /* disable TX GAIN override */
11552                 if (mac->mac_phy.rev < 2)
11553                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11554                 else {
11555                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11556                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11557                 }
11558                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11559
11560                 plp->plp_txpwridx = -1;
11561         }
11562         if (mac->mac_phy.rev >= 2) {
11563                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11564                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11565                 else
11566                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11567         }
11568
11569         /* writes TX Power Control mode */
11570         switch (plp->plp_txpctlmode) {
11571         case BWN_PHYLP_TXPCTL_OFF:
11572                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11573                 break;
11574         case BWN_PHYLP_TXPCTL_ON_HW:
11575                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11576                 break;
11577         case BWN_PHYLP_TXPCTL_ON_SW:
11578                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11579                 break;
11580         default:
11581                 ctl = 0;
11582                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11583         }
11584         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11585             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11586 }
11587
11588 static void
11589 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11590 {
11591         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11592         struct bwn_softc *sc = mac->mac_sc;
11593         const unsigned int size = 256;
11594         struct bwn_txgain tg;
11595         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11596         uint16_t tssinpt, tssiidx, value[2];
11597         uint8_t mode;
11598         int8_t txpwridx;
11599
11600         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11601             M_NOWAIT | M_ZERO);
11602         if (tabs == NULL) {
11603                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11604                 return;
11605         }
11606
11607         bwn_phy_lp_get_txpctlmode(mac);
11608         mode = plp->plp_txpctlmode;
11609         txpwridx = plp->plp_txpwridx;
11610         tssinpt = plp->plp_tssinpt;
11611         tssiidx = plp->plp_tssiidx;
11612
11613         bwn_tab_read_multi(mac,
11614             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11615             BWN_TAB_4(7, 0x140), size, tabs);
11616
11617         bwn_phy_lp_tblinit(mac);
11618         bwn_phy_lp_bbinit(mac);
11619         bwn_phy_lp_txpctl_init(mac);
11620         bwn_phy_lp_rf_onoff(mac, 1);
11621         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11622
11623         bwn_tab_write_multi(mac,
11624             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11625             BWN_TAB_4(7, 0x140), size, tabs);
11626
11627         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11628         plp->plp_tssinpt = tssinpt;
11629         plp->plp_tssiidx = tssiidx;
11630         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11631         if (txpwridx != -1) {
11632                 /* set TX power by index */
11633                 plp->plp_txpwridx = txpwridx;
11634                 bwn_phy_lp_get_txpctlmode(mac);
11635                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11636                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11637                 if (mac->mac_phy.rev >= 2) {
11638                         rxcomp = bwn_tab_read(mac,
11639                             BWN_TAB_4(7, txpwridx + 320));
11640                         txgain = bwn_tab_read(mac,
11641                             BWN_TAB_4(7, txpwridx + 192));
11642                         tg.tg_pad = (txgain >> 16) & 0xff;
11643                         tg.tg_gm = txgain & 0xff;
11644                         tg.tg_pga = (txgain >> 8) & 0xff;
11645                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11646                         bwn_phy_lp_set_txgain(mac, &tg);
11647                 } else {
11648                         rxcomp = bwn_tab_read(mac,
11649                             BWN_TAB_4(10, txpwridx + 320));
11650                         txgain = bwn_tab_read(mac,
11651                             BWN_TAB_4(10, txpwridx + 192));
11652                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11653                             0xf800, (txgain >> 4) & 0x7fff);
11654                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11655                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11656                 }
11657                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11658
11659                 /* set TX IQCC */
11660                 value[0] = (rxcomp >> 10) & 0x3ff;
11661                 value[1] = rxcomp & 0x3ff;
11662                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11663
11664                 coeff = bwn_tab_read(mac,
11665                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11666                     BWN_TAB_4(10, txpwridx + 448));
11667                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11668                 if (mac->mac_phy.rev >= 2) {
11669                         rfpwr = bwn_tab_read(mac,
11670                             BWN_TAB_4(7, txpwridx + 576));
11671                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11672                             rfpwr & 0xffff);
11673                 }
11674                 bwn_phy_lp_set_txgain_override(mac);
11675         }
11676         if (plp->plp_rccap)
11677                 bwn_phy_lp_set_rccap(mac);
11678         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11679         bwn_phy_lp_set_txpctlmode(mac, mode);
11680         free(tabs, M_DEVBUF);
11681 }
11682
11683 static void
11684 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11685 {
11686         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11687         int i;
11688         static const uint16_t addr[] = {
11689                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11690                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11691                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11692                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11693                 BWN_PHY_OFDM(0xcf),
11694         };
11695
11696         for (i = 0; i < N(addr); i++)
11697                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11698 }
11699
11700 static void
11701 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11702 {
11703         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11704
11705         if (mac->mac_phy.rev < 2) {
11706                 bwn_phy_lp_tblinit_r01(mac);
11707                 bwn_phy_lp_tblinit_txgain(mac);
11708                 bwn_phy_lp_set_gaintbl(mac, freq);
11709                 return;
11710         }
11711
11712         bwn_phy_lp_tblinit_r2(mac);
11713         bwn_phy_lp_tblinit_txgain(mac);
11714 }
11715
11716 struct bwn_wpair {
11717         uint16_t                reg;
11718         uint16_t                value;
11719 };
11720
11721 struct bwn_smpair {
11722         uint16_t                offset;
11723         uint16_t                mask;
11724         uint16_t                set;
11725 };
11726
11727 static void
11728 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11729 {
11730         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11731         struct bwn_softc *sc = mac->mac_sc;
11732         struct ifnet *ifp = sc->sc_ifp;
11733         struct ieee80211com *ic = ifp->if_l2com;
11734         static const struct bwn_wpair v1[] = {
11735                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11736                 { BWN_PHY_AFE_CTL, 0x8800 },
11737                 { BWN_PHY_AFE_CTL_OVR, 0 },
11738                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11739                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11740                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11741                 { BWN_PHY_OFDM(0xf9), 0 },
11742                 { BWN_PHY_TR_LOOKUP_1, 0 }
11743         };
11744         static const struct bwn_smpair v2[] = {
11745                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11746                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11747                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11748                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11749                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11750         };
11751         static const struct bwn_smpair v3[] = {
11752                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11753                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11754                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11755                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11756                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11757                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11758                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11759                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11760                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11761                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11762
11763         };
11764         int i;
11765
11766         for (i = 0; i < N(v1); i++)
11767                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11768         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11769         for (i = 0; i < N(v2); i++)
11770                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11771
11772         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11773         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11774         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11775         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11776                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11777                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11778         } else {
11779                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11780         }
11781         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11782         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11783         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11784         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11785         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11786         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11787         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11788         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11789         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11790         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11791         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11792         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11793             (siba_get_chiprev(sc->sc_dev) == 0)) {
11794                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11795                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11796         } else {
11797                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11798                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11799         }
11800         for (i = 0; i < N(v3); i++)
11801                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11802         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11803             (siba_get_chiprev(sc->sc_dev) == 0)) {
11804                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11805                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11806         }
11807
11808         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11809                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11810                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11811                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11812                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11813                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11814                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11815         } else
11816                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11817
11818         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11819         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11820         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11821         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11822         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11823         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11824         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11825             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11826             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11827
11828         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11829             (siba_get_chiprev(sc->sc_dev) == 0)) {
11830                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11831                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11832                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11833         }
11834
11835         bwn_phy_lp_digflt_save(mac);
11836 }
11837
11838 static void
11839 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11840 {
11841         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11842         struct bwn_softc *sc = mac->mac_sc;
11843         struct ifnet *ifp = sc->sc_ifp;
11844         struct ieee80211com *ic = ifp->if_l2com;
11845         static const struct bwn_smpair v1[] = {
11846                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11847                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11848                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11849                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11850                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11851                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11852                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11853         };
11854         static const struct bwn_smpair v2[] = {
11855                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11856                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11857                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11858                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11859                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11860                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11861                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11862                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11863                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11864                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11865                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11866                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11867                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11868                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11869                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11870                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11871         };
11872         static const struct bwn_smpair v3[] = {
11873                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11874                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11875                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11876                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11877                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11878                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11879                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11880                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11881         };
11882         static const struct bwn_smpair v4[] = {
11883                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11884                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11885                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11886                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11887                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11888                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11889                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11890                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11891         };
11892         static const struct bwn_smpair v5[] = {
11893                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11894                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11895                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11896                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11897                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11898                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11899                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11900                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11901         };
11902         int i;
11903         uint16_t tmp, tmp2;
11904
11905         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11906         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11907         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11908         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11909         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11910         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11911         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11912         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11913         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11914         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11915         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11916         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11917         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11918         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11919         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11920         for (i = 0; i < N(v1); i++)
11921                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11922         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11923             0xff00, plp->plp_rxpwroffset);
11924         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11925             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11926            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11927                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11928                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11929                 if (mac->mac_phy.rev == 0)
11930                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11931                             0xffcf, 0x0010);
11932                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11933         } else {
11934                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11935                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11936                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11937         }
11938         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11939         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11940         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11941                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11942         else
11943                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11944         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11945         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11946             0xfff9, (plp->plp_bxarch << 1));
11947         if (mac->mac_phy.rev == 1 &&
11948             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11949                 for (i = 0; i < N(v2); i++)
11950                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11951                             v2[i].set);
11952         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11953             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11954             ((mac->mac_phy.rev == 0) &&
11955              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11956                 for (i = 0; i < N(v3); i++)
11957                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11958                             v3[i].set);
11959         } else if (mac->mac_phy.rev == 1 ||
11960                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11961                 for (i = 0; i < N(v4); i++)
11962                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11963                             v4[i].set);
11964         } else {
11965                 for (i = 0; i < N(v5); i++)
11966                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11967                             v5[i].set);
11968         }
11969         if (mac->mac_phy.rev == 1 &&
11970             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11971                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11972                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11973                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11974                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11975         }
11976         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11977             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11978             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11979                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11980                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11981                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11982                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11983         }
11984         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11985                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11986                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11987                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11988                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11989                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11990                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11991                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11992                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11993         } else {
11994                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11995                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11996         }
11997         if (mac->mac_phy.rev == 1) {
11998                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11999                 tmp2 = (tmp & 0x03e0) >> 5;
12000                 tmp2 |= tmp2 << 5;
12001                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12002                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12003                 tmp2 = (tmp & 0x1f00) >> 8;
12004                 tmp2 |= tmp2 << 5;
12005                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12006                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12007                 tmp2 = tmp & 0x00ff;
12008                 tmp2 |= tmp << 8;
12009                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12010         }
12011 }
12012
12013 struct bwn_b2062_freq {
12014         uint16_t                freq;
12015         uint8_t                 value[6];
12016 };
12017
12018 static void
12019 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12020 {
12021 #define CALC_CTL7(freq, div)                                            \
12022         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12023 #define CALC_CTL18(freq, div)                                           \
12024         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12025 #define CALC_CTL19(freq, div)                                           \
12026         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12027         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12028         struct bwn_softc *sc = mac->mac_sc;
12029         struct ifnet *ifp = sc->sc_ifp;
12030         struct ieee80211com *ic = ifp->if_l2com;
12031         static const struct bwn_b2062_freq freqdata_tab[] = {
12032                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12033                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12034                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12035                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12036                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12037                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12038         };
12039         static const struct bwn_wpair v1[] = {
12040                 { BWN_B2062_N_TXCTL3, 0 },
12041                 { BWN_B2062_N_TXCTL4, 0 },
12042                 { BWN_B2062_N_TXCTL5, 0 },
12043                 { BWN_B2062_N_TXCTL6, 0 },
12044                 { BWN_B2062_N_PDNCTL0, 0x40 },
12045                 { BWN_B2062_N_PDNCTL0, 0 },
12046                 { BWN_B2062_N_CALIB_TS, 0x10 },
12047                 { BWN_B2062_N_CALIB_TS, 0 }
12048         };
12049         const struct bwn_b2062_freq *f = NULL;
12050         uint32_t xtalfreq, ref;
12051         unsigned int i;
12052
12053         bwn_phy_lp_b2062_tblinit(mac);
12054
12055         for (i = 0; i < N(v1); i++)
12056                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12057         if (mac->mac_phy.rev > 0)
12058                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12059                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12060         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12061                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12062         else
12063                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12064
12065         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12066             ("%s:%d: fail", __func__, __LINE__));
12067         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12068         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12069
12070         if (xtalfreq <= 30000000) {
12071                 plp->plp_div = 1;
12072                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12073         } else {
12074                 plp->plp_div = 2;
12075                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12076         }
12077
12078         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12079             CALC_CTL7(xtalfreq, plp->plp_div));
12080         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12081             CALC_CTL18(xtalfreq, plp->plp_div));
12082         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12083             CALC_CTL19(xtalfreq, plp->plp_div));
12084
12085         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12086         ref &= 0xffff;
12087         for (i = 0; i < N(freqdata_tab); i++) {
12088                 if (ref < freqdata_tab[i].freq) {
12089                         f = &freqdata_tab[i];
12090                         break;
12091                 }
12092         }
12093         if (f == NULL)
12094                 f = &freqdata_tab[N(freqdata_tab) - 1];
12095         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12096             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12097         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12098             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12099         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12100         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12101 #undef CALC_CTL7
12102 #undef CALC_CTL18
12103 #undef CALC_CTL19
12104 }
12105
12106 static void
12107 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12108 {
12109
12110         bwn_phy_lp_b2063_tblinit(mac);
12111         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12112         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12113         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12114         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12115         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12116         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12117         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12118         if (mac->mac_phy.rev == 2) {
12119                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12120                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12121                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12122         } else {
12123                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12124                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12125         }
12126 }
12127
12128 static void
12129 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12130 {
12131         struct bwn_softc *sc = mac->mac_sc;
12132         static const struct bwn_wpair v1[] = {
12133                 { BWN_B2063_RX_BB_SP8, 0x0 },
12134                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12135                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12136                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12137                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12138                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12139                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12140                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12141         };
12142         static const struct bwn_wpair v2[] = {
12143                 { BWN_B2063_TX_BB_SP3, 0x0 },
12144                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12145                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12146                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12147                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12148         };
12149         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12150         int i;
12151         uint8_t tmp;
12152
12153         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12154
12155         for (i = 0; i < 2; i++)
12156                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12157         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12158         for (i = 2; i < N(v1); i++)
12159                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12160         for (i = 0; i < 10000; i++) {
12161                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12162                         break;
12163                 DELAY(1000);
12164         }
12165
12166         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12167                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12168
12169         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12170
12171         for (i = 0; i < N(v2); i++)
12172                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12173         if (freqxtal == 24000000) {
12174                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12175                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12176         } else {
12177                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12178                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12179         }
12180         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12181         for (i = 0; i < 10000; i++) {
12182                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12183                         break;
12184                 DELAY(1000);
12185         }
12186         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12187                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12188         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12189 }
12190
12191 static void
12192 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12193 {
12194         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12195         struct bwn_softc *sc = mac->mac_sc;
12196         struct bwn_phy_lp_iq_est ie;
12197         struct bwn_txgain tx_gains;
12198         static const uint32_t pwrtbl[21] = {
12199                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12200                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12201                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12202                 0x0004c, 0x0002c, 0x0001a,
12203         };
12204         uint32_t npwr, ipwr, sqpwr, tmp;
12205         int loopback, i, j, sum, error;
12206         uint16_t save[7];
12207         uint8_t txo, bbmult, txpctlmode;
12208
12209         error = bwn_phy_lp_switch_channel(mac, 7);
12210         if (error)
12211                 device_printf(sc->sc_dev,
12212                     "failed to change channel to 7 (%d)\n", error);
12213         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12214         bbmult = bwn_phy_lp_get_bbmult(mac);
12215         if (txo)
12216                 tx_gains = bwn_phy_lp_get_txgain(mac);
12217
12218         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12219         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12220         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12221         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12222         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12223         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12224         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12225
12226         bwn_phy_lp_get_txpctlmode(mac);
12227         txpctlmode = plp->plp_txpctlmode;
12228         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12229
12230         /* disable CRS */
12231         bwn_phy_lp_set_deaf(mac, 1);
12232         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12233         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12234         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12235         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12236         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12237         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12238         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12239         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12240         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12241         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12242         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12243         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12244         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12245         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12246         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12247         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12248         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12249         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12250         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12251         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12252         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12253         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12254         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12255         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12256
12257         loopback = bwn_phy_lp_loopback(mac);
12258         if (loopback == -1)
12259                 goto done;
12260         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12261         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12262         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12263         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12264         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12265
12266         tmp = 0;
12267         memset(&ie, 0, sizeof(ie));
12268         for (i = 128; i <= 159; i++) {
12269                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12270                 sum = 0;
12271                 for (j = 5; j <= 25; j++) {
12272                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12273                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12274                                 goto done;
12275                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12276                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12277                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12278                             12);
12279                         sum += ((ipwr - npwr) * (ipwr - npwr));
12280                         if ((i == 128) || (sum < tmp)) {
12281                                 plp->plp_rccap = i;
12282                                 tmp = sum;
12283                         }
12284                 }
12285         }
12286         bwn_phy_lp_ddfs_turnoff(mac);
12287 done:
12288         /* restore CRS */
12289         bwn_phy_lp_clear_deaf(mac, 1);
12290         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12291         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12292
12293         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12294         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12295         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12296         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12297         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12298         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12299         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12300
12301         bwn_phy_lp_set_bbmult(mac, bbmult);
12302         if (txo)
12303                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12304         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12305         if (plp->plp_rccap)
12306                 bwn_phy_lp_set_rccap(mac);
12307 }
12308
12309 static void
12310 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12311 {
12312         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12313         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12314
12315         if (mac->mac_phy.rev == 1)
12316                 rc_cap = MIN(rc_cap + 5, 15);
12317
12318         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12319             MAX(plp->plp_rccap - 4, 0x80));
12320         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12321         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12322             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12323 }
12324
12325 static uint32_t
12326 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12327 {
12328         uint32_t i, q, r;
12329
12330         if (div == 0)
12331                 return (0);
12332
12333         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12334                 q <<= 1;
12335                 if (r << 1 >= div) {
12336                         q++;
12337                         r = (r << 1) - div;
12338                 }
12339         }
12340         if (r << 1 >= div)
12341                 q++;
12342         return (q);
12343 }
12344
12345 static void
12346 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12347 {
12348         struct bwn_softc *sc = mac->mac_sc;
12349
12350         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12351         DELAY(20);
12352         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12353                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12354                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12355         } else {
12356                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12357         }
12358         DELAY(5);
12359 }
12360
12361 static void
12362 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12363 {
12364
12365         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12366         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12367         DELAY(200);
12368 }
12369
12370 static void
12371 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12372 {
12373 #define FLAG_A  0x01
12374 #define FLAG_G  0x02
12375         struct bwn_softc *sc = mac->mac_sc;
12376         struct ifnet *ifp = sc->sc_ifp;
12377         struct ieee80211com *ic = ifp->if_l2com;
12378         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12379                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12380                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12381                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12382                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12383                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12384                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12385                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12386                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12387                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12388                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12389                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12390                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12391                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12392                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12393                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12399                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12426         };
12427         const struct bwn_b206x_rfinit_entry *br;
12428         unsigned int i;
12429
12430         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12431                 br = &bwn_b2062_init_tab[i];
12432                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12433                         if (br->br_flags & FLAG_G)
12434                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12435                 } else {
12436                         if (br->br_flags & FLAG_A)
12437                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12438                 }
12439         }
12440 #undef FLAG_A
12441 #undef FLAG_B
12442 }
12443
12444 static void
12445 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12446 {
12447 #define FLAG_A  0x01
12448 #define FLAG_G  0x02
12449         struct bwn_softc *sc = mac->mac_sc;
12450         struct ifnet *ifp = sc->sc_ifp;
12451         struct ieee80211com *ic = ifp->if_l2com;
12452         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12453                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12454                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12455                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12456                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12457                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12458                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12459                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12460                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12461                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12462                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12464                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12465                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12466                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12467                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12468                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12469                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12470                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12471                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12472                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12473                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12474                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12475                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12476                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12477                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12478                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12479                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12482                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12483                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12485                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12486                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12487                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12488                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12489                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12493                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12494                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12495         };
12496         const struct bwn_b206x_rfinit_entry *br;
12497         unsigned int i;
12498
12499         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12500                 br = &bwn_b2063_init_tab[i];
12501                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12502                         if (br->br_flags & FLAG_G)
12503                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12504                 } else {
12505                         if (br->br_flags & FLAG_A)
12506                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12507                 }
12508         }
12509 #undef FLAG_A
12510 #undef FLAG_B
12511 }
12512
12513 static void
12514 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12515     int count, void *_data)
12516 {
12517         unsigned int i;
12518         uint32_t offset, type;
12519         uint8_t *data = _data;
12520
12521         type = BWN_TAB_GETTYPE(typenoffset);
12522         offset = BWN_TAB_GETOFFSET(typenoffset);
12523         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12524
12525         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12526
12527         for (i = 0; i < count; i++) {
12528                 switch (type) {
12529                 case BWN_TAB_8BIT:
12530                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12531                         data++;
12532                         break;
12533                 case BWN_TAB_16BIT:
12534                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12535                             BWN_PHY_TABLEDATALO);
12536                         data += 2;
12537                         break;
12538                 case BWN_TAB_32BIT:
12539                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12540                             BWN_PHY_TABLEDATAHI);
12541                         *((uint32_t *)data) <<= 16;
12542                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12543                             BWN_PHY_TABLEDATALO);
12544                         data += 4;
12545                         break;
12546                 default:
12547                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12548                 }
12549         }
12550 }
12551
12552 static void
12553 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12554     int count, const void *_data)
12555 {
12556         uint32_t offset, type, value;
12557         const uint8_t *data = _data;
12558         unsigned int i;
12559
12560         type = BWN_TAB_GETTYPE(typenoffset);
12561         offset = BWN_TAB_GETOFFSET(typenoffset);
12562         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12563
12564         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12565
12566         for (i = 0; i < count; i++) {
12567                 switch (type) {
12568                 case BWN_TAB_8BIT:
12569                         value = *data;
12570                         data++;
12571                         KASSERT(!(value & ~0xff),
12572                             ("%s:%d: fail", __func__, __LINE__));
12573                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12574                         break;
12575                 case BWN_TAB_16BIT:
12576                         value = *((const uint16_t *)data);
12577                         data += 2;
12578                         KASSERT(!(value & ~0xffff),
12579                             ("%s:%d: fail", __func__, __LINE__));
12580                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12581                         break;
12582                 case BWN_TAB_32BIT:
12583                         value = *((const uint32_t *)data);
12584                         data += 4;
12585                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12586                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12587                         break;
12588                 default:
12589                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12590                 }
12591         }
12592 }
12593
12594 static struct bwn_txgain
12595 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12596 {
12597         struct bwn_txgain tg;
12598         uint16_t tmp;
12599
12600         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12601         if (mac->mac_phy.rev < 2) {
12602                 tmp = BWN_PHY_READ(mac,
12603                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12604                 tg.tg_gm = tmp & 0x0007;
12605                 tg.tg_pga = (tmp & 0x0078) >> 3;
12606                 tg.tg_pad = (tmp & 0x780) >> 7;
12607                 return (tg);
12608         }
12609
12610         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12611         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12612         tg.tg_gm = tmp & 0xff;
12613         tg.tg_pga = (tmp >> 8) & 0xff;
12614         return (tg);
12615 }
12616
12617 static uint8_t
12618 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12619 {
12620
12621         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12622 }
12623
12624 static void
12625 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12626 {
12627         uint16_t pa;
12628
12629         if (mac->mac_phy.rev < 2) {
12630                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12631                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12632                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12633                 bwn_phy_lp_set_txgain_override(mac);
12634                 return;
12635         }
12636
12637         pa = bwn_phy_lp_get_pa_gain(mac);
12638         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12639             (tg->tg_pga << 8) | tg->tg_gm);
12640         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12641             tg->tg_pad | (pa << 6));
12642         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12643         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12644             tg->tg_pad | (pa << 8));
12645         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12646         bwn_phy_lp_set_txgain_override(mac);
12647 }
12648
12649 static void
12650 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12651 {
12652
12653         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12654 }
12655
12656 static void
12657 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12658 {
12659         uint16_t trsw = (tx << 1) | rx;
12660
12661         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12662         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12663 }
12664
12665 static void
12666 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12667 {
12668         struct bwn_softc *sc = mac->mac_sc;
12669         struct ifnet *ifp = sc->sc_ifp;
12670         struct ieee80211com *ic = ifp->if_l2com;
12671         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12672
12673         if (mac->mac_phy.rev < 2) {
12674                 trsw = gain & 0x1;
12675                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12676                 ext_lna = (gain & 2) >> 1;
12677
12678                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12679                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12680                     0xfbff, ext_lna << 10);
12681                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12682                     0xf7ff, ext_lna << 11);
12683                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12684         } else {
12685                 low_gain = gain & 0xffff;
12686                 high_gain = (gain >> 16) & 0xf;
12687                 ext_lna = (gain >> 21) & 0x1;
12688                 trsw = ~(gain >> 20) & 0x1;
12689
12690                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12691                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12692                     0xfdff, ext_lna << 9);
12693                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12694                     0xfbff, ext_lna << 10);
12695                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12696                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12697                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12698                         tmp = (gain >> 2) & 0x3;
12699                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12700                             0xe7ff, tmp<<11);
12701                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12702                             tmp << 3);
12703                 }
12704         }
12705
12706         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12707         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12708         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12709         if (mac->mac_phy.rev >= 2) {
12710                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12711                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12712                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12713                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12714                 }
12715                 return;
12716         }
12717         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12718 }
12719
12720 static void
12721 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12722 {
12723         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12724
12725         if (user)
12726                 plp->plp_crsusr_off = 1;
12727         else
12728                 plp->plp_crssys_off = 1;
12729
12730         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12731 }
12732
12733 static void
12734 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12735 {
12736         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12737         struct bwn_softc *sc = mac->mac_sc;
12738         struct ifnet *ifp = sc->sc_ifp;
12739         struct ieee80211com *ic = ifp->if_l2com;
12740
12741         if (user)
12742                 plp->plp_crsusr_off = 0;
12743         else
12744                 plp->plp_crssys_off = 0;
12745
12746         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12747                 return;
12748
12749         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12750                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12751         else
12752                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12753 }
12754
12755 static unsigned int
12756 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12757 {
12758         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12759         static uint8_t sqrt_table[256] = {
12760                 10, 14, 17, 20, 22, 24, 26, 28,
12761                 30, 31, 33, 34, 36, 37, 38, 40,
12762                 41, 42, 43, 44, 45, 46, 47, 48,
12763                 50, 50, 51, 52, 53, 54, 55, 56,
12764                 57, 58, 59, 60, 60, 61, 62, 63,
12765                 64, 64, 65, 66, 67, 67, 68, 69,
12766                 70, 70, 71, 72, 72, 73, 74, 74,
12767                 75, 76, 76, 77, 78, 78, 79, 80,
12768                 80, 81, 81, 82, 83, 83, 84, 84,
12769                 85, 86, 86, 87, 87, 88, 88, 89,
12770                 90, 90, 91, 91, 92, 92, 93, 93,
12771                 94, 94, 95, 95, 96, 96, 97, 97,
12772                 98, 98, 99, 100, 100, 100, 101, 101,
12773                 102, 102, 103, 103, 104, 104, 105, 105,
12774                 106, 106, 107, 107, 108, 108, 109, 109,
12775                 110, 110, 110, 111, 111, 112, 112, 113,
12776                 113, 114, 114, 114, 115, 115, 116, 116,
12777                 117, 117, 117, 118, 118, 119, 119, 120,
12778                 120, 120, 121, 121, 122, 122, 122, 123,
12779                 123, 124, 124, 124, 125, 125, 126, 126,
12780                 126, 127, 127, 128, 128, 128, 129, 129,
12781                 130, 130, 130, 131, 131, 131, 132, 132,
12782                 133, 133, 133, 134, 134, 134, 135, 135,
12783                 136, 136, 136, 137, 137, 137, 138, 138,
12784                 138, 139, 139, 140, 140, 140, 141, 141,
12785                 141, 142, 142, 142, 143, 143, 143, 144,
12786                 144, 144, 145, 145, 145, 146, 146, 146,
12787                 147, 147, 147, 148, 148, 148, 149, 149,
12788                 150, 150, 150, 150, 151, 151, 151, 152,
12789                 152, 152, 153, 153, 153, 154, 154, 154,
12790                 155, 155, 155, 156, 156, 156, 157, 157,
12791                 157, 158, 158, 158, 159, 159, 159, 160
12792         };
12793
12794         if (x == 0)
12795                 return (0);
12796         if (x >= 256) {
12797                 unsigned int tmp;
12798
12799                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12800                         /* do nothing */ ;
12801                 return (tmp);
12802         }
12803         return (sqrt_table[x - 1] / 10);
12804 }
12805
12806 static int
12807 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12808 {
12809 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12810         int _t;                                                         \
12811         _t = _x - 20;                                                   \
12812         if (_t >= 0) {                                                  \
12813                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12814         } else {                                                        \
12815                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12816         }                                                               \
12817 } while (0)
12818 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12819         int _t;                                                         \
12820         _t = _x - 11;                                                   \
12821         if (_t >= 0)                                                    \
12822                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12823         else                                                            \
12824                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12825 } while (0)
12826         struct bwn_phy_lp_iq_est ie;
12827         uint16_t v0, v1;
12828         int tmp[2], ret;
12829
12830         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12831         v0 = v1 >> 8;
12832         v1 |= 0xff;
12833
12834         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12835         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12836
12837         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12838         if (ret == 0)
12839                 goto done;
12840
12841         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12842                 ret = 0;
12843                 goto done;
12844         }
12845
12846         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12847         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12848
12849         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12850         v0 = tmp[0] >> 3;
12851         v1 = tmp[1] >> 4;
12852 done:
12853         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12854         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12855         return ret;
12856 #undef CALC_COEFF
12857 #undef CALC_COEFF2
12858 }
12859
12860 static void
12861 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12862 {
12863         static const uint16_t noisescale[] = {
12864                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12865                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12866                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12867                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12868                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12869         };
12870         static const uint16_t crsgainnft[] = {
12871                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12872                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12873                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12874                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12875                 0x013d,
12876         };
12877         static const uint16_t filterctl[] = {
12878                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12879                 0xff53, 0x0127,
12880         };
12881         static const uint32_t psctl[] = {
12882                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12883                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12884                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12885                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12886                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12887                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12888                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12889                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12890         };
12891         static const uint16_t ofdmcckgain_r0[] = {
12892                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12893                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12894                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12895                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12896                 0x755d,
12897         };
12898         static const uint16_t ofdmcckgain_r1[] = {
12899                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12900                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12901                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12902                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12903                 0x755d,
12904         };
12905         static const uint16_t gaindelta[] = {
12906                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12907                 0x0000,
12908         };
12909         static const uint32_t txpwrctl[] = {
12910                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12911                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12912                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12913                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12914                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12915                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12916                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12917                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12918                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12919                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12920                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12921                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12922                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12923                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12924                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12925                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12926                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12949                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12950                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12951                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12952                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12953                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12954                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12955                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12956                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12957                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12958                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12959                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12960                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12961                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12962                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12963                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12964                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12965                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12966                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12967                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12968                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12969                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12970                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12971                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12972                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12973                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12974                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12975                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12976                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12977                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12978                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12979                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12980                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12981                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12982                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12983                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12984                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12985                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12986                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12987                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12988                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12989                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12990                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12991                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12992                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12993                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12994                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12995                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12996                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12997                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12998                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12999                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13000                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13001                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13002                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13003                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13004                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13005                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13006                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13007                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13008                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13009                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13010                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13011                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13012                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13013                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13014                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13015                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13016                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13017                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13018                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13019                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13020                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13021                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13022                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13023                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13024                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13025                 0x00000702,
13026         };
13027
13028         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13029
13030         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13031             bwn_tab_sigsq_tbl);
13032         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13033         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13034         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13035         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13036         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13037             bwn_tab_pllfrac_tbl);
13038         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13039             bwn_tabl_iqlocal_tbl);
13040         if (mac->mac_phy.rev == 0) {
13041                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13042                     ofdmcckgain_r0);
13043                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13044                     ofdmcckgain_r0);
13045         } else {
13046                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13047                     ofdmcckgain_r1);
13048                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13049                     ofdmcckgain_r1);
13050         }
13051         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13052         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13053 }
13054
13055 static void
13056 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13057 {
13058         struct bwn_softc *sc = mac->mac_sc;
13059         int i;
13060         static const uint16_t noisescale[] = {
13061                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13062                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13063                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13068         };
13069         static const uint32_t filterctl[] = {
13070                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13071                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13072         };
13073         static const uint32_t psctl[] = {
13074                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13075                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13076                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13077                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13078         };
13079         static const uint32_t gainidx[] = {
13080                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13081                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13082                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13083                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13084                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13085                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13086                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13087                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13088                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13089                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13090                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13091                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13092                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13093                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13094                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13095                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13096                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13097                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13098                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13099                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13100                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13101                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13102                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13103                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13104                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13105                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13106                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13107                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13108                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13109                 0x0000001a, 0x64ca55ad, 0x0000001a
13110         };
13111         static const uint16_t auxgainidx[] = {
13112                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13113                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13114                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13115                 0x0004, 0x0016
13116         };
13117         static const uint16_t swctl[] = {
13118                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13119                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13120                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13121                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13122                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13123                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13124                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13125                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13126         };
13127         static const uint8_t hf[] = {
13128                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13129                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13130         };
13131         static const uint32_t gainval[] = {
13132                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13133                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13134                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13135                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13136                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13137                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13138                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13139                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13141                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13142                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13143                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13144                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13145                 0x000000f1, 0x00000000, 0x00000000
13146         };
13147         static const uint16_t gain[] = {
13148                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13149                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13150                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13151                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13152                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13153                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13154                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13155                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13156                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13157                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13158                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13159                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13160         };
13161         static const uint32_t papdeps[] = {
13162                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13163                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13164                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13165                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13166                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13167                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13168                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13169                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13170                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13171                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13172                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13173                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13174                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13175         };
13176         static const uint32_t papdmult[] = {
13177                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13178                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13179                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13180                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13181                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13182                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13183                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13184                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13185                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13186                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13187                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13188                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13189                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13190         };
13191         static const uint32_t gainidx_a0[] = {
13192                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13193                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13194                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13195                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13196                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13197                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13198                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13199                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13200                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13201                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13202                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13203                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13204                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13205         };
13206         static const uint16_t auxgainidx_a0[] = {
13207                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13208                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13209                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13210                 0x0002, 0x0014
13211         };
13212         static const uint32_t gainval_a0[] = {
13213                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13214                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13215                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13216                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13217                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13218                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13219                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13220                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13221                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13222                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13223                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13224                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13225                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13226                 0x000000f7, 0x00000000, 0x00000000
13227         };
13228         static const uint16_t gain_a0[] = {
13229                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13230                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13231                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13232                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13233                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13234                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13235                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13236                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13237                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13238                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13239                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13240                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13241         };
13242
13243         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13244
13245         for (i = 0; i < 704; i++)
13246                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13247
13248         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13249             bwn_tab_sigsq_tbl);
13250         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13251         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13252         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13253         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13254         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13255         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13256         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13257         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13258         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13259         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13260             bwn_tab_pllfrac_tbl);
13261         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13262             bwn_tabl_iqlocal_tbl);
13263         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13264         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13265
13266         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13267             (siba_get_chiprev(sc->sc_dev) == 0)) {
13268                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13269                     gainidx_a0);
13270                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13271                     auxgainidx_a0);
13272                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13273                     gainval_a0);
13274                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13275         }
13276 }
13277
13278 static void
13279 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13280 {
13281         struct bwn_softc *sc = mac->mac_sc;
13282         struct ifnet *ifp = sc->sc_ifp;
13283         struct ieee80211com *ic = ifp->if_l2com;
13284         static struct bwn_txgain_entry txgain_r2[] = {
13285                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13286                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13287                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13288                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13289                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13290                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13291                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13292                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13293                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13294                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13295                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13296                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13297                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13298                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13299                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13300                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13301                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13302                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13303                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13304                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13305                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13306                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13307                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13308                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13309                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13310                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13311                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13312                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13313                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13314                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13315                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13316                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13317                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13318                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13319                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13320                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13321                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13322                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13323                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13324                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13325                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13326                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13327                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13328                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13329                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13330                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13331                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13332                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13333                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13334                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13335                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13336                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13337                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13338                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13339                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13340                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13341                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13342                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13343                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13344                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13345                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13346                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13347                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13348                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13349         };
13350         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13351                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13352                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13353                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13354                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13355                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13356                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13357                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13358                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13359                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13360                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13361                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13362                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13363                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13364                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13365                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13366                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13367                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13368                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13369                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13370                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13371                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13372                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13373                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13374                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13375                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13376                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13377                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13378                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13379                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13380                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13381                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13382                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13383                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13384                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13385                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13386                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13387                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13388                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13389                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13390                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13391                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13392                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13393                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13394                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13395                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13396                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13397                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13398                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13399                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13400                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13401                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13402                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13403                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13404                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13405                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13406                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13407                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13408                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13409                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13410                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13411                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13412                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13413                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13414                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13415         };
13416         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13417                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13418                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13419                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13420                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13421                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13422                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13423                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13424                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13425                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13426                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13427                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13428                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13429                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13430                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13431                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13432                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13433                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13434                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13435                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13436                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13437                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13438                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13439                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13440                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13441                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13442                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13443                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13444                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13445                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13446                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13447                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13448                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13449                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13450                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13451                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13452                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13453                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13454                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13455                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13456                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13457                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13458                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13459                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13460                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13461                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13462                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13463                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13464                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13465                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13466                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13467                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13468                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13469                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13470                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13471                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13472                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13473                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13474                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13475                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13476                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13477                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13478                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13479                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13480                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13481         };
13482         static struct bwn_txgain_entry txgain_r0[] = {
13483                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13484                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13485                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13486                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13487                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13488                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13489                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13490                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13491                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13492                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13493                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13494                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13495                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13496                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13497                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13498                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13499                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13500                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13501                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13502                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13503                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13504                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13505                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13506                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13507                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13508                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13509                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13510                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13511                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13512                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13513                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13514                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13515                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13516                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13517                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13518                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13519                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13520                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13521                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13522                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13523                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13524                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13525                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13526                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13527                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13528                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13529                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13530                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13531                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13532                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13533                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13534                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13535                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13536                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13537                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13538                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13539                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13540                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13541                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13542                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13543                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13544                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13545                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13546                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13547         };
13548         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13549                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13550                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13551                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13552                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13553                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13554                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13555                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13556                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13557                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13558                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13559                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13560                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13561                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13562                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13563                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13564                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13565                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13566                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13567                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13568                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13569                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13570                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13571                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13572                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13573                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13574                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13575                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13576                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13577                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13578                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13579                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13580                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13581                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13582                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13583                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13584                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13585                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13586                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13587                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13588                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13589                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13590                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13591                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13592                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13593                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13594                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13595                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13596                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13597                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13598                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13599                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13600                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13601                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13602                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13603                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13604                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13605                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13606                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13607                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13608                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13609                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13610                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13611                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13612                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13613         };
13614         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13615                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13616                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13617                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13618                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13619                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13620                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13621                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13622                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13623                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13624                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13625                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13626                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13627                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13628                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13629                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13630                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13631                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13632                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13633                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13634                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13635                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13636                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13637                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13638                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13639                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13640                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13641                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13642                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13643                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13644                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13645                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13646                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13647                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13648                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13649                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13650                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13651                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13652                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13653                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13654                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13655                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13656                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13657                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13658                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13659                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13660                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13661                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13662                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13663                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13664                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13665                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13666                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13667                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13668                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13669                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13670                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13671                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13672                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13673                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13674                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13675                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13676                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13677                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13678                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13679         };
13680         static struct bwn_txgain_entry txgain_r1[] = {
13681                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13682                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13683                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13684                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13685                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13686                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13687                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13688                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13689                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13690                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13691                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13692                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13693                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13694                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13695                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13696                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13697                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13698                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13699                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13700                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13701                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13702                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13703                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13704                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13705                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13706                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13707                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13708                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13709                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13710                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13711                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13712                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13713                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13714                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13715                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13716                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13717                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13718                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13719                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13720                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13721                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13722                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13723                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13724                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13725                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13726                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13727                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13728                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13729                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13730                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13731                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13732                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13733                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13734                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13735                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13736                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13737                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13738                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13739                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13740                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13741                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13742                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13743                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13744                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13745                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13746                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13747                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13748                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13749                 { 7, 11, 6, 0, 71 }
13750         };
13751         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13752                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13753                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13754                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13755                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13756                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13757                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13758                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13759                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13760                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13761                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13762                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13763                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13764                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13765                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13766                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13767                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13768                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13769                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13770                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13771                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13772                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13773                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13774                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13775                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13776                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13777                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13778                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13779                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13780                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13781                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13782                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13783                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13784                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13785                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13786                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13787                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13788                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13789                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13790                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13791                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13792                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13793                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13794                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13795                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13796                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13797                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13798                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13799                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13800                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13801                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13802                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13803                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13804                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13805                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13806                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13807                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13808                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13809                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13810                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13811                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13812                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13813                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13814                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13815                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13816         };
13817         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13818                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13819                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13820                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13821                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13822                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13823                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13824                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13825                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13826                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13827                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13828                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13829                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13830                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13831                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13832                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13833                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13834                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13835                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13836                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13837                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13838                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13839                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13840                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13841                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13842                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13843                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13844                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13845                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13846                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13847                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13848                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13849                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13850                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13851                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13852                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13853                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13854                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13855                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13856                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13857                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13858                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13859                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13860                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13861                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13862                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13863                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13864                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13865                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13866                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13867                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13868                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13869                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13870                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13871                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13872                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13873                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13874                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13875                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13876                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13877                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13878                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13879                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13880                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13881                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13882         };
13883
13884         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13885                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13886                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13887                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13888                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13889                             txgain_2ghz_r2);
13890                 else
13891                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13892                             txgain_5ghz_r2);
13893                 return;
13894         }
13895
13896         if (mac->mac_phy.rev == 0) {
13897                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13898                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13899                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13900                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13901                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13902                             txgain_2ghz_r0);
13903                 else
13904                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13905                             txgain_5ghz_r0);
13906                 return;
13907         }
13908
13909         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13910             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13911                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13912         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13913                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13914         else
13915                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13916 }
13917
13918 static void
13919 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13920 {
13921         uint32_t offset, type;
13922
13923         type = BWN_TAB_GETTYPE(typeoffset);
13924         offset = BWN_TAB_GETOFFSET(typeoffset);
13925         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13926
13927         switch (type) {
13928         case BWN_TAB_8BIT:
13929                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13930                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13931                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13932                 break;
13933         case BWN_TAB_16BIT:
13934                 KASSERT(!(value & ~0xffff),
13935                     ("%s:%d: fail", __func__, __LINE__));
13936                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13937                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13938                 break;
13939         case BWN_TAB_32BIT:
13940                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13941                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13942                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13943                 break;
13944         default:
13945                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13946         }
13947 }
13948
13949 static int
13950 bwn_phy_lp_loopback(struct bwn_mac *mac)
13951 {
13952         struct bwn_phy_lp_iq_est ie;
13953         int i, index = -1;
13954         uint32_t tmp;
13955
13956         memset(&ie, 0, sizeof(ie));
13957
13958         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13959         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13960         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13961         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13962         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13963         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13964         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13965         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13966         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13967         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13968         for (i = 0; i < 32; i++) {
13969                 bwn_phy_lp_set_rxgain_idx(mac, i);
13970                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13971                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13972                         continue;
13973                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13974                 if ((tmp > 4000) && (tmp < 10000)) {
13975                         index = i;
13976                         break;
13977                 }
13978         }
13979         bwn_phy_lp_ddfs_turnoff(mac);
13980         return (index);
13981 }
13982
13983 static void
13984 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13985 {
13986
13987         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13988 }
13989
13990 static void
13991 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13992     int incr1, int incr2, int scale_idx)
13993 {
13994
13995         bwn_phy_lp_ddfs_turnoff(mac);
13996         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13997         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13998         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13999         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14000         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14001         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14002         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14003         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14004         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14005         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14006 }
14007
14008 static uint8_t
14009 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14010     struct bwn_phy_lp_iq_est *ie)
14011 {
14012         int i;
14013
14014         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14015         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14016         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14017         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14018         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14019
14020         for (i = 0; i < 500; i++) {
14021                 if (!(BWN_PHY_READ(mac,
14022                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14023                         break;
14024                 DELAY(1000);
14025         }
14026         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14027                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14028                 return 0;
14029         }
14030
14031         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14032         ie->ie_iqprod <<= 16;
14033         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14034         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14035         ie->ie_ipwr <<= 16;
14036         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14037         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14038         ie->ie_qpwr <<= 16;
14039         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14040
14041         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14042         return 1;
14043 }
14044
14045 static uint32_t
14046 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14047 {
14048         uint32_t offset, type, value;
14049
14050         type = BWN_TAB_GETTYPE(typeoffset);
14051         offset = BWN_TAB_GETOFFSET(typeoffset);
14052         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14053
14054         switch (type) {
14055         case BWN_TAB_8BIT:
14056                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14057                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14058                 break;
14059         case BWN_TAB_16BIT:
14060                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14061                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14062                 break;
14063         case BWN_TAB_32BIT:
14064                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14065                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14066                 value <<= 16;
14067                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14068                 break;
14069         default:
14070                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14071                 value = 0;
14072         }
14073
14074         return (value);
14075 }
14076
14077 static void
14078 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14079 {
14080
14081         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14082         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14083 }
14084
14085 static void
14086 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14087 {
14088         uint16_t ctl;
14089
14090         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14091         ctl |= dac << 7;
14092         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14093 }
14094
14095 static void
14096 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14097 {
14098
14099         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14100         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14101 }
14102
14103 static void
14104 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14105 {
14106
14107         if (mac->mac_phy.rev < 2)
14108                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14109         else {
14110                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14111                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14112         }
14113         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14114 }
14115
14116 static uint16_t
14117 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14118 {
14119
14120         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14121 }
14122
14123 static uint8_t
14124 bwn_nbits(int32_t val)
14125 {
14126         uint32_t tmp;
14127         uint8_t nbits = 0;
14128
14129         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14130                 nbits++;
14131         return (nbits);
14132 }
14133
14134 static void
14135 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14136     struct bwn_txgain_entry *table)
14137 {
14138         int i;
14139
14140         for (i = offset; i < count; i++)
14141                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14142 }
14143
14144 static void
14145 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14146     struct bwn_txgain_entry data)
14147 {
14148
14149         if (mac->mac_phy.rev >= 2)
14150                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14151         else
14152                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14153 }
14154
14155 static void
14156 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14157     struct bwn_txgain_entry te)
14158 {
14159         struct bwn_softc *sc = mac->mac_sc;
14160         struct ifnet *ifp = sc->sc_ifp;
14161         struct ieee80211com *ic = ifp->if_l2com;
14162         uint32_t tmp;
14163
14164         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14165
14166         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14167         if (mac->mac_phy.rev >= 3) {
14168                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14169                     (0x10 << 24) : (0x70 << 24));
14170         } else {
14171                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14172                     (0x14 << 24) : (0x7f << 24));
14173         }
14174         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14175         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14176             te.te_bbmult << 20 | te.te_dac << 28);
14177 }
14178
14179 static void
14180 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14181     struct bwn_txgain_entry te)
14182 {
14183
14184         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14185
14186         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14187             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14188             te.te_dac);
14189         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14190 }
14191
14192 static void
14193 bwn_sysctl_node(struct bwn_softc *sc)
14194 {
14195         device_t dev = sc->sc_dev;
14196         struct bwn_mac *mac;
14197         struct bwn_stats *stats;
14198
14199         /* XXX assume that count of MAC is only 1. */
14200
14201         if ((mac = sc->sc_curmac) == NULL)
14202                 return;
14203         stats = &mac->mac_stats;
14204
14205         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14206             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14207             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14208         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14209             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14210             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14211         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14212             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14213             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14214
14215 #ifdef BWN_DEBUG
14216         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14217             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14218             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14219 #endif
14220 }
14221
14222 static device_method_t bwn_methods[] = {
14223         /* Device interface */
14224         DEVMETHOD(device_probe,         bwn_probe),
14225         DEVMETHOD(device_attach,        bwn_attach),
14226         DEVMETHOD(device_detach,        bwn_detach),
14227         DEVMETHOD(device_suspend,       bwn_suspend),
14228         DEVMETHOD(device_resume,        bwn_resume),
14229         DEVMETHOD_END
14230 };
14231 static driver_t bwn_driver = {
14232         "bwn",
14233         bwn_methods,
14234         sizeof(struct bwn_softc)
14235 };
14236 static devclass_t bwn_devclass;
14237 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14238 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14239 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14240 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14241 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);