]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwn/if_bwn.c
Update llvm/clang to r241361.
[FreeBSD/FreeBSD.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_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/siba/siba_ids.h>
65 #include <dev/siba/sibareg.h>
66 #include <dev/siba/sibavar.h>
67
68 #include <net80211/ieee80211_var.h>
69 #include <net80211/ieee80211_radiotap.h>
70 #include <net80211/ieee80211_regdomain.h>
71 #include <net80211/ieee80211_phy.h>
72 #include <net80211/ieee80211_ratectl.h>
73
74 #include <dev/bwn/if_bwnreg.h>
75 #include <dev/bwn/if_bwnvar.h>
76
77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
78     "Broadcom driver parameters");
79
80 /*
81  * Tunable & sysctl variables.
82  */
83
84 #ifdef BWN_DEBUG
85 static  int bwn_debug = 0;
86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
87     "Broadcom debugging printfs");
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 ieee80211com *);
185 static void     bwn_update_promisc(struct ieee80211com *);
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         ic->ic_softc = sc;
1062         ic->ic_name = device_get_nameunit(sc->sc_dev);
1063         /* XXX not right but it's not used anywhere important */
1064         ic->ic_phytype = IEEE80211_T_OFDM;
1065         ic->ic_opmode = IEEE80211_M_STA;
1066         ic->ic_caps =
1067                   IEEE80211_C_STA               /* station mode supported */
1068                 | IEEE80211_C_MONITOR           /* monitor mode */
1069                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1070                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1071                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1072                 | IEEE80211_C_WME               /* WME/WMM supported */
1073                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1074                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1075                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1076                 ;
1077
1078         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1079
1080         /* call MI attach routine. */
1081         ieee80211_ifattach(ic,
1082             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1083             siba_sprom_get_mac_80211a(sc->sc_dev) :
1084             siba_sprom_get_mac_80211bg(sc->sc_dev));
1085
1086         ic->ic_headroom = sizeof(struct bwn_txhdr);
1087
1088         /* override default methods */
1089         ic->ic_raw_xmit = bwn_raw_xmit;
1090         ic->ic_updateslot = bwn_updateslot;
1091         ic->ic_update_promisc = bwn_update_promisc;
1092         ic->ic_wme.wme_update = bwn_wme_update;
1093
1094         ic->ic_scan_start = bwn_scan_start;
1095         ic->ic_scan_end = bwn_scan_end;
1096         ic->ic_set_channel = bwn_set_channel;
1097
1098         ic->ic_vap_create = bwn_vap_create;
1099         ic->ic_vap_delete = bwn_vap_delete;
1100
1101         ieee80211_radiotap_attach(ic,
1102             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1103             BWN_TX_RADIOTAP_PRESENT,
1104             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1105             BWN_RX_RADIOTAP_PRESENT);
1106
1107         bwn_sysctl_node(sc);
1108
1109         if (bootverbose)
1110                 ieee80211_announce(ic);
1111         return (0);
1112 }
1113
1114 static void
1115 bwn_phy_detach(struct bwn_mac *mac)
1116 {
1117
1118         if (mac->mac_phy.detach != NULL)
1119                 mac->mac_phy.detach(mac);
1120 }
1121
1122 static int
1123 bwn_detach(device_t dev)
1124 {
1125         struct bwn_softc *sc = device_get_softc(dev);
1126         struct bwn_mac *mac = sc->sc_curmac;
1127         struct ifnet *ifp = sc->sc_ifp;
1128         struct ieee80211com *ic = ifp->if_l2com;
1129         int i;
1130
1131         sc->sc_flags |= BWN_FLAG_INVALID;
1132
1133         if (device_is_attached(sc->sc_dev)) {
1134                 bwn_stop(sc, 1);
1135                 bwn_dma_free(mac);
1136                 callout_drain(&sc->sc_led_blink_ch);
1137                 callout_drain(&sc->sc_rfswitch_ch);
1138                 callout_drain(&sc->sc_task_ch);
1139                 callout_drain(&sc->sc_watchdog_ch);
1140                 bwn_phy_detach(mac);
1141                 if (ifp != NULL) {
1142                         ieee80211_draintask(ic, &mac->mac_hwreset);
1143                         ieee80211_draintask(ic, &mac->mac_txpower);
1144                         ieee80211_ifdetach(ic);
1145                         if_free(ifp);
1146                 }
1147         }
1148         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1149         taskqueue_free(sc->sc_tq);
1150
1151         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1152                 if (mac->mac_intrhand[i] != NULL) {
1153                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1154                             mac->mac_intrhand[i]);
1155                         mac->mac_intrhand[i] = NULL;
1156                 }
1157         }
1158         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1159         if (mac->mac_msi != 0)
1160                 pci_release_msi(dev);
1161
1162         BWN_LOCK_DESTROY(sc);
1163         return (0);
1164 }
1165
1166 static int
1167 bwn_attach_pre(struct bwn_softc *sc)
1168 {
1169         struct ifnet *ifp;
1170         int error = 0;
1171
1172         BWN_LOCK_INIT(sc);
1173         TAILQ_INIT(&sc->sc_maclist);
1174         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1175         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1176         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1177
1178         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1179                 taskqueue_thread_enqueue, &sc->sc_tq);
1180         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1181                 "%s taskq", device_get_nameunit(sc->sc_dev));
1182
1183         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1184         if (ifp == NULL) {
1185                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1186                 error = ENOSPC;
1187                 goto fail;
1188         }
1189
1190         /* set these up early for if_printf use */
1191         if_initname(ifp, device_get_name(sc->sc_dev),
1192             device_get_unit(sc->sc_dev));
1193
1194         ifp->if_softc = sc;
1195         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1196         ifp->if_init = bwn_init;
1197         ifp->if_ioctl = bwn_ioctl;
1198         ifp->if_start = bwn_start;
1199         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1200         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1201         IFQ_SET_READY(&ifp->if_snd);
1202
1203         return (0);
1204
1205 fail:   BWN_LOCK_DESTROY(sc);
1206         return (error);
1207 }
1208
1209 static void
1210 bwn_sprom_bugfixes(device_t dev)
1211 {
1212 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1213         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1214          (siba_get_pci_device(dev) == _device) &&                       \
1215          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1216          (siba_get_pci_subdevice(dev) == _subdevice))
1217
1218         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1219             siba_get_pci_subdevice(dev) == 0x4e &&
1220             siba_get_pci_revid(dev) > 0x40)
1221                 siba_sprom_set_bf_lo(dev,
1222                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1223         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1224             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1225                 siba_sprom_set_bf_lo(dev,
1226                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1227         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1228                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1229                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1230                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1231                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1232                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1233                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1234                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1235                         siba_sprom_set_bf_lo(dev,
1236                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1237         }
1238 #undef  BWN_ISDEV
1239 }
1240
1241 static int
1242 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1243 {
1244 #define IS_RUNNING(ifp) \
1245         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1246         struct bwn_softc *sc = ifp->if_softc;
1247         struct ieee80211com *ic = ifp->if_l2com;
1248         struct ifreq *ifr = (struct ifreq *)data;
1249         int error = 0, startall;
1250
1251         switch (cmd) {
1252         case SIOCSIFFLAGS:
1253                 startall = 0;
1254                 if (IS_RUNNING(ifp)) {
1255                         bwn_update_promisc(ic);
1256                 } else if (ifp->if_flags & IFF_UP) {
1257                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1258                                 bwn_init(sc);
1259                                 startall = 1;
1260                         }
1261                 } else
1262                         bwn_stop(sc, 1);
1263                 if (startall)
1264                         ieee80211_start_all(ic);
1265                 break;
1266         case SIOCGIFMEDIA:
1267                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1268                 break;
1269         case SIOCGIFADDR:
1270                 error = ether_ioctl(ifp, cmd, data);
1271                 break;
1272         default:
1273                 error = EINVAL;
1274                 break;
1275         }
1276         return (error);
1277 }
1278
1279 static void
1280 bwn_start(struct ifnet *ifp)
1281 {
1282         struct bwn_softc *sc = ifp->if_softc;
1283
1284         BWN_LOCK(sc);
1285         bwn_start_locked(ifp);
1286         BWN_UNLOCK(sc);
1287 }
1288
1289 static void
1290 bwn_start_locked(struct ifnet *ifp)
1291 {
1292         struct bwn_softc *sc = ifp->if_softc;
1293         struct bwn_mac *mac = sc->sc_curmac;
1294         struct ieee80211_frame *wh;
1295         struct ieee80211_node *ni;
1296         struct ieee80211_key *k;
1297         struct mbuf *m;
1298
1299         BWN_ASSERT_LOCKED(sc);
1300
1301         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1302             mac->mac_status < BWN_MAC_STATUS_STARTED)
1303                 return;
1304
1305         for (;;) {
1306                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1307                 if (m == NULL)
1308                         break;
1309
1310                 if (bwn_tx_isfull(sc, m))
1311                         break;
1312                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1313                 if (ni == NULL) {
1314                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1315                         m_freem(m);
1316                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1317                         continue;
1318                 }
1319                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1320                 wh = mtod(m, struct ieee80211_frame *);
1321                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1322                         k = ieee80211_crypto_encap(ni, m);
1323                         if (k == NULL) {
1324                                 ieee80211_free_node(ni);
1325                                 m_freem(m);
1326                                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1327                                 continue;
1328                         }
1329                 }
1330                 wh = NULL;      /* Catch any invalid use */
1331
1332                 if (bwn_tx_start(sc, ni, m) != 0) {
1333                         if (ni != NULL)
1334                                 ieee80211_free_node(ni);
1335                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1336                         continue;
1337                 }
1338
1339                 sc->sc_watchdog_timer = 5;
1340         }
1341 }
1342
1343 static int
1344 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1345 {
1346         struct bwn_dma_ring *dr;
1347         struct bwn_mac *mac = sc->sc_curmac;
1348         struct bwn_pio_txqueue *tq;
1349         struct ifnet *ifp = sc->sc_ifp;
1350         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1351
1352         BWN_ASSERT_LOCKED(sc);
1353
1354         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1355                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1356                 if (dr->dr_stop == 1 ||
1357                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1358                         dr->dr_stop = 1;
1359                         goto full;
1360                 }
1361         } else {
1362                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1363                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1364                     pktlen > (tq->tq_size - tq->tq_used)) {
1365                         tq->tq_stop = 1;
1366                         goto full;
1367                 }
1368         }
1369         return (0);
1370 full:
1371         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1372         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1373         return (1);
1374 }
1375
1376 static int
1377 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1378 {
1379         struct bwn_mac *mac = sc->sc_curmac;
1380         int error;
1381
1382         BWN_ASSERT_LOCKED(sc);
1383
1384         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1385                 m_freem(m);
1386                 return (ENXIO);
1387         }
1388
1389         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1390             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1391         if (error) {
1392                 m_freem(m);
1393                 return (error);
1394         }
1395         return (0);
1396 }
1397
1398 static int
1399 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1400 {
1401         struct bwn_pio_txpkt *tp;
1402         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1403         struct bwn_softc *sc = mac->mac_sc;
1404         struct bwn_txhdr txhdr;
1405         struct mbuf *m_new;
1406         uint32_t ctl32;
1407         int error;
1408         uint16_t ctl16;
1409
1410         BWN_ASSERT_LOCKED(sc);
1411
1412         /* XXX TODO send packets after DTIM */
1413
1414         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1415         tp = TAILQ_FIRST(&tq->tq_pktlist);
1416         tp->tp_ni = ni;
1417         tp->tp_m = m;
1418
1419         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1420         if (error) {
1421                 device_printf(sc->sc_dev, "tx fail\n");
1422                 return (error);
1423         }
1424
1425         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1426         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1427         tq->tq_free--;
1428
1429         if (siba_get_revid(sc->sc_dev) >= 8) {
1430                 /*
1431                  * XXX please removes m_defrag(9)
1432                  */
1433                 m_new = m_defrag(m, M_NOWAIT);
1434                 if (m_new == NULL) {
1435                         device_printf(sc->sc_dev,
1436                             "%s: can't defrag TX buffer\n",
1437                             __func__);
1438                         return (ENOBUFS);
1439                 }
1440                 if (m_new->m_next != NULL)
1441                         device_printf(sc->sc_dev,
1442                             "TODO: fragmented packets for PIO\n");
1443                 tp->tp_m = m_new;
1444
1445                 /* send HEADER */
1446                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1447                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1448                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1449                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1450                 /* send BODY */
1451                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1452                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1453                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1454                     ctl32 | BWN_PIO8_TXCTL_EOF);
1455         } else {
1456                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1457                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1458                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1459                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1460                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1461                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1462                     ctl16 | BWN_PIO_TXCTL_EOF);
1463         }
1464
1465         return (0);
1466 }
1467
1468 static struct bwn_pio_txqueue *
1469 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1470 {
1471
1472         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1473                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1474
1475         switch (prio) {
1476         case 0:
1477                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1478         case 1:
1479                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1480         case 2:
1481                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1482         case 3:
1483                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1484         }
1485         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1486         return (NULL);
1487 }
1488
1489 static int
1490 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1491 {
1492 #define BWN_GET_TXHDRCACHE(slot)                                        \
1493         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1494         struct bwn_dma *dma = &mac->mac_method.dma;
1495         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1496         struct bwn_dmadesc_generic *desc;
1497         struct bwn_dmadesc_meta *mt;
1498         struct bwn_softc *sc = mac->mac_sc;
1499         struct ifnet *ifp = sc->sc_ifp;
1500         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1501         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1502
1503         BWN_ASSERT_LOCKED(sc);
1504         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1505
1506         /* XXX send after DTIM */
1507
1508         slot = bwn_dma_getslot(dr);
1509         dr->getdesc(dr, slot, &desc, &mt);
1510         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1511             ("%s:%d: fail", __func__, __LINE__));
1512
1513         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1514             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1515             BWN_DMA_COOKIE(dr, slot));
1516         if (error)
1517                 goto fail;
1518         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1519             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1520             &mt->mt_paddr, BUS_DMA_NOWAIT);
1521         if (error) {
1522                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1523                     __func__, error);
1524                 goto fail;
1525         }
1526         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1527             BUS_DMASYNC_PREWRITE);
1528         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1529         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1530             BUS_DMASYNC_PREWRITE);
1531
1532         slot = bwn_dma_getslot(dr);
1533         dr->getdesc(dr, slot, &desc, &mt);
1534         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1535             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1536         mt->mt_m = m;
1537         mt->mt_ni = ni;
1538
1539         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1540             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1541         if (error && error != EFBIG) {
1542                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1543                     __func__, error);
1544                 goto fail;
1545         }
1546         if (error) {    /* error == EFBIG */
1547                 struct mbuf *m_new;
1548
1549                 m_new = m_defrag(m, M_NOWAIT);
1550                 if (m_new == NULL) {
1551                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1552                             __func__);
1553                         error = ENOBUFS;
1554                         goto fail;
1555                 } else {
1556                         m = m_new;
1557                 }
1558
1559                 mt->mt_m = m;
1560                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1561                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1562                 if (error) {
1563                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1564                             __func__, error);
1565                         goto fail;
1566                 }
1567         }
1568         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1569         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1570         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1571             BUS_DMASYNC_PREWRITE);
1572
1573         /* XXX send after DTIM */
1574
1575         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1576         return (0);
1577 fail:
1578         dr->dr_curslot = backup[0];
1579         dr->dr_usedslot = backup[1];
1580         return (error);
1581 #undef BWN_GET_TXHDRCACHE
1582 }
1583
1584 static void
1585 bwn_watchdog(void *arg)
1586 {
1587         struct bwn_softc *sc = arg;
1588         struct ifnet *ifp = sc->sc_ifp;
1589
1590         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1591                 if_printf(ifp, "device timeout\n");
1592                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1593         }
1594         callout_schedule(&sc->sc_watchdog_ch, hz);
1595 }
1596
1597 static int
1598 bwn_attach_core(struct bwn_mac *mac)
1599 {
1600         struct bwn_softc *sc = mac->mac_sc;
1601         int error, have_bg = 0, have_a = 0;
1602         uint32_t high;
1603
1604         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1605             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1606
1607         siba_powerup(sc->sc_dev, 0);
1608
1609         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1610         bwn_reset_core(mac,
1611             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1612         error = bwn_phy_getinfo(mac, high);
1613         if (error)
1614                 goto fail;
1615
1616         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1617         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1618         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1619             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1620             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1621                 have_a = have_bg = 0;
1622                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1623                         have_a = 1;
1624                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1625                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1626                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1627                         have_bg = 1;
1628                 else
1629                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1630                             mac->mac_phy.type));
1631         }
1632         /* XXX turns off PHY A because it's not supported */
1633         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1634             mac->mac_phy.type != BWN_PHYTYPE_N) {
1635                 have_a = 0;
1636                 have_bg = 1;
1637         }
1638
1639         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1640                 mac->mac_phy.attach = bwn_phy_g_attach;
1641                 mac->mac_phy.detach = bwn_phy_g_detach;
1642                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1643                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1644                 mac->mac_phy.init = bwn_phy_g_init;
1645                 mac->mac_phy.exit = bwn_phy_g_exit;
1646                 mac->mac_phy.phy_read = bwn_phy_g_read;
1647                 mac->mac_phy.phy_write = bwn_phy_g_write;
1648                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1649                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1650                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1651                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1652                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1653                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1654                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1655                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1656                 mac->mac_phy.set_im = bwn_phy_g_im;
1657                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1658                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1659                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1660                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1661         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1662                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1663                 mac->mac_phy.init = bwn_phy_lp_init;
1664                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1665                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1666                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1667                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1668                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1669                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1670                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1671                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1672                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1673                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1674                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1675         } else {
1676                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1677                     mac->mac_phy.type);
1678                 error = ENXIO;
1679                 goto fail;
1680         }
1681
1682         mac->mac_phy.gmode = have_bg;
1683         if (mac->mac_phy.attach != NULL) {
1684                 error = mac->mac_phy.attach(mac);
1685                 if (error) {
1686                         device_printf(sc->sc_dev, "failed\n");
1687                         goto fail;
1688                 }
1689         }
1690
1691         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1692
1693         error = bwn_chiptest(mac);
1694         if (error)
1695                 goto fail;
1696         error = bwn_setup_channels(mac, have_bg, have_a);
1697         if (error) {
1698                 device_printf(sc->sc_dev, "failed to setup channels\n");
1699                 goto fail;
1700         }
1701
1702         if (sc->sc_curmac == NULL)
1703                 sc->sc_curmac = mac;
1704
1705         error = bwn_dma_attach(mac);
1706         if (error != 0) {
1707                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1708                 goto fail;
1709         }
1710
1711         mac->mac_phy.switch_analog(mac, 0);
1712
1713         siba_dev_down(sc->sc_dev, 0);
1714 fail:
1715         siba_powerdown(sc->sc_dev);
1716         return (error);
1717 }
1718
1719 static void
1720 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1721 {
1722         struct bwn_softc *sc = mac->mac_sc;
1723         uint32_t low, ctl;
1724
1725         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1726
1727         siba_dev_up(sc->sc_dev, flags);
1728         DELAY(2000);
1729
1730         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1731             ~BWN_TGSLOW_PHYRESET;
1732         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1733         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1734         DELAY(1000);
1735         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1736         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1737         DELAY(1000);
1738
1739         if (mac->mac_phy.switch_analog != NULL)
1740                 mac->mac_phy.switch_analog(mac, 1);
1741
1742         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1743         if (flags & BWN_TGSLOW_SUPPORT_G)
1744                 ctl |= BWN_MACCTL_GMODE;
1745         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1746 }
1747
1748 static int
1749 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1750 {
1751         struct bwn_phy *phy = &mac->mac_phy;
1752         struct bwn_softc *sc = mac->mac_sc;
1753         uint32_t tmp;
1754
1755         /* PHY */
1756         tmp = BWN_READ_2(mac, BWN_PHYVER);
1757         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1758         phy->rf_on = 1;
1759         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1760         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1761         phy->rev = (tmp & BWN_PHYVER_VERSION);
1762         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1763             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1764                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1765             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1766             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1767             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1768                 goto unsupphy;
1769
1770         /* RADIO */
1771         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1772                 if (siba_get_chiprev(sc->sc_dev) == 0)
1773                         tmp = 0x3205017f;
1774                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1775                         tmp = 0x4205017f;
1776                 else
1777                         tmp = 0x5205017f;
1778         } else {
1779                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1780                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1781                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1782                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1783         }
1784         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1785         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1786         phy->rf_manuf = (tmp & 0x00000fff);
1787         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1788                 goto unsupradio;
1789         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1790              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1791             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1792             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1793             (phy->type == BWN_PHYTYPE_N &&
1794              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1795             (phy->type == BWN_PHYTYPE_LP &&
1796              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1797                 goto unsupradio;
1798
1799         return (0);
1800 unsupphy:
1801         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1802             "analog %#x)\n",
1803             phy->type, phy->rev, phy->analog);
1804         return (ENXIO);
1805 unsupradio:
1806         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1807             "rev %#x)\n",
1808             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1809         return (ENXIO);
1810 }
1811
1812 static int
1813 bwn_chiptest(struct bwn_mac *mac)
1814 {
1815 #define TESTVAL0        0x55aaaa55
1816 #define TESTVAL1        0xaa5555aa
1817         struct bwn_softc *sc = mac->mac_sc;
1818         uint32_t v, backup;
1819
1820         BWN_LOCK(sc);
1821
1822         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1823
1824         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1825         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1826                 goto error;
1827         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1828         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1829                 goto error;
1830
1831         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1832
1833         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1834             (siba_get_revid(sc->sc_dev) <= 10)) {
1835                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1836                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1837                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1838                         goto error;
1839                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1840                         goto error;
1841         }
1842         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1843
1844         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1845         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1846                 goto error;
1847
1848         BWN_UNLOCK(sc);
1849         return (0);
1850 error:
1851         BWN_UNLOCK(sc);
1852         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1853         return (ENODEV);
1854 }
1855
1856 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1857 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1858
1859 static int
1860 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1861 {
1862         struct bwn_softc *sc = mac->mac_sc;
1863         struct ifnet *ifp = sc->sc_ifp;
1864         struct ieee80211com *ic = ifp->if_l2com;
1865
1866         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1867         ic->ic_nchans = 0;
1868
1869         if (have_bg)
1870                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1871                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1872         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1873                 if (have_a)
1874                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1875                             &ic->ic_nchans, &bwn_chantable_n,
1876                             IEEE80211_CHAN_HTA);
1877         } else {
1878                 if (have_a)
1879                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1880                             &ic->ic_nchans, &bwn_chantable_a,
1881                             IEEE80211_CHAN_A);
1882         }
1883
1884         mac->mac_phy.supports_2ghz = have_bg;
1885         mac->mac_phy.supports_5ghz = have_a;
1886
1887         return (ic->ic_nchans == 0 ? ENXIO : 0);
1888 }
1889
1890 static uint32_t
1891 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1892 {
1893         uint32_t ret;
1894
1895         BWN_ASSERT_LOCKED(mac->mac_sc);
1896
1897         if (way == BWN_SHARED) {
1898                 KASSERT((offset & 0x0001) == 0,
1899                     ("%s:%d warn", __func__, __LINE__));
1900                 if (offset & 0x0003) {
1901                         bwn_shm_ctlword(mac, way, offset >> 2);
1902                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1903                         ret <<= 16;
1904                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1905                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1906                         goto out;
1907                 }
1908                 offset >>= 2;
1909         }
1910         bwn_shm_ctlword(mac, way, offset);
1911         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1912 out:
1913         return (ret);
1914 }
1915
1916 static uint16_t
1917 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1918 {
1919         uint16_t ret;
1920
1921         BWN_ASSERT_LOCKED(mac->mac_sc);
1922
1923         if (way == BWN_SHARED) {
1924                 KASSERT((offset & 0x0001) == 0,
1925                     ("%s:%d warn", __func__, __LINE__));
1926                 if (offset & 0x0003) {
1927                         bwn_shm_ctlword(mac, way, offset >> 2);
1928                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1929                         goto out;
1930                 }
1931                 offset >>= 2;
1932         }
1933         bwn_shm_ctlword(mac, way, offset);
1934         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1935 out:
1936
1937         return (ret);
1938 }
1939
1940 static void
1941 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1942     uint16_t offset)
1943 {
1944         uint32_t control;
1945
1946         control = way;
1947         control <<= 16;
1948         control |= offset;
1949         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1950 }
1951
1952 static void
1953 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1954     uint32_t value)
1955 {
1956         BWN_ASSERT_LOCKED(mac->mac_sc);
1957
1958         if (way == BWN_SHARED) {
1959                 KASSERT((offset & 0x0001) == 0,
1960                     ("%s:%d warn", __func__, __LINE__));
1961                 if (offset & 0x0003) {
1962                         bwn_shm_ctlword(mac, way, offset >> 2);
1963                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1964                                     (value >> 16) & 0xffff);
1965                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1966                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1967                         return;
1968                 }
1969                 offset >>= 2;
1970         }
1971         bwn_shm_ctlword(mac, way, offset);
1972         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1973 }
1974
1975 static void
1976 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1977     uint16_t value)
1978 {
1979         BWN_ASSERT_LOCKED(mac->mac_sc);
1980
1981         if (way == BWN_SHARED) {
1982                 KASSERT((offset & 0x0001) == 0,
1983                     ("%s:%d warn", __func__, __LINE__));
1984                 if (offset & 0x0003) {
1985                         bwn_shm_ctlword(mac, way, offset >> 2);
1986                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1987                         return;
1988                 }
1989                 offset >>= 2;
1990         }
1991         bwn_shm_ctlword(mac, way, offset);
1992         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1993 }
1994
1995 static void
1996 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1997     int txpow)
1998 {
1999
2000         c->ic_freq = freq;
2001         c->ic_flags = flags;
2002         c->ic_ieee = ieee;
2003         c->ic_minpower = 0;
2004         c->ic_maxpower = 2 * txpow;
2005         c->ic_maxregpower = txpow;
2006 }
2007
2008 static void
2009 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2010     const struct bwn_channelinfo *ci, int flags)
2011 {
2012         struct ieee80211_channel *c;
2013         int i;
2014
2015         c = &chans[*nchans];
2016
2017         for (i = 0; i < ci->nchannels; i++) {
2018                 const struct bwn_channel *hc;
2019
2020                 hc = &ci->channels[i];
2021                 if (*nchans >= maxchans)
2022                         break;
2023                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2024                 c++, (*nchans)++;
2025                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2026                         /* g channel have a separate b-only entry */
2027                         if (*nchans >= maxchans)
2028                                 break;
2029                         c[0] = c[-1];
2030                         c[-1].ic_flags = IEEE80211_CHAN_B;
2031                         c++, (*nchans)++;
2032                 }
2033                 if (flags == IEEE80211_CHAN_HTG) {
2034                         /* HT g channel have a separate g-only entry */
2035                         if (*nchans >= maxchans)
2036                                 break;
2037                         c[-1].ic_flags = IEEE80211_CHAN_G;
2038                         c[0] = c[-1];
2039                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2040                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2041                         c++, (*nchans)++;
2042                 }
2043                 if (flags == IEEE80211_CHAN_HTA) {
2044                         /* HT a channel have a separate a-only entry */
2045                         if (*nchans >= maxchans)
2046                                 break;
2047                         c[-1].ic_flags = IEEE80211_CHAN_A;
2048                         c[0] = c[-1];
2049                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2050                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2051                         c++, (*nchans)++;
2052                 }
2053         }
2054 }
2055
2056 static int
2057 bwn_phy_g_attach(struct bwn_mac *mac)
2058 {
2059         struct bwn_softc *sc = mac->mac_sc;
2060         struct bwn_phy *phy = &mac->mac_phy;
2061         struct bwn_phy_g *pg = &phy->phy_g;
2062         unsigned int i;
2063         int16_t pab0, pab1, pab2;
2064         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2065         int8_t bg;
2066
2067         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2068         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2069         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2070         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2071
2072         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2073                 device_printf(sc->sc_dev, "not supported anymore\n");
2074
2075         pg->pg_flags = 0;
2076         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2077             pab2 == -1) {
2078                 pg->pg_idletssi = 52;
2079                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2080                 return (0);
2081         }
2082
2083         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2084         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2085         if (pg->pg_tssi2dbm == NULL) {
2086                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2087                 return (ENOMEM);
2088         }
2089         for (i = 0; i < 64; i++) {
2090                 int32_t m1, m2, f, q, delta;
2091                 int8_t j = 0;
2092
2093                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2094                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2095                 f = 256;
2096
2097                 do {
2098                         if (j > 15) {
2099                                 device_printf(sc->sc_dev,
2100                                     "failed to generate tssi2dBm\n");
2101                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2102                                 return (ENOMEM);
2103                         }
2104                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2105                             f, 2048);
2106                         delta = abs(q - f);
2107                         f = q;
2108                         j++;
2109                 } while (delta >= 2);
2110
2111                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2112                     128);
2113         }
2114
2115         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2116         return (0);
2117 }
2118
2119 static void
2120 bwn_phy_g_detach(struct bwn_mac *mac)
2121 {
2122         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2123
2124         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2125                 free(pg->pg_tssi2dbm, M_DEVBUF);
2126                 pg->pg_tssi2dbm = NULL;
2127         }
2128         pg->pg_flags = 0;
2129 }
2130
2131 static void
2132 bwn_phy_g_init_pre(struct bwn_mac *mac)
2133 {
2134         struct bwn_phy *phy = &mac->mac_phy;
2135         struct bwn_phy_g *pg = &phy->phy_g;
2136         void *tssi2dbm;
2137         int idletssi;
2138         unsigned int i;
2139
2140         tssi2dbm = pg->pg_tssi2dbm;
2141         idletssi = pg->pg_idletssi;
2142
2143         memset(pg, 0, sizeof(*pg));
2144
2145         pg->pg_tssi2dbm = tssi2dbm;
2146         pg->pg_idletssi = idletssi;
2147
2148         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2149
2150         for (i = 0; i < N(pg->pg_nrssi); i++)
2151                 pg->pg_nrssi[i] = -1000;
2152         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2153                 pg->pg_nrssi_lt[i] = i;
2154         pg->pg_lofcal = 0xffff;
2155         pg->pg_initval = 0xffff;
2156         pg->pg_immode = BWN_IMMODE_NONE;
2157         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2158         pg->pg_avgtssi = 0xff;
2159
2160         pg->pg_loctl.tx_bias = 0xff;
2161         TAILQ_INIT(&pg->pg_loctl.calib_list);
2162 }
2163
2164 static int
2165 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2166 {
2167         struct bwn_phy *phy = &mac->mac_phy;
2168         struct bwn_phy_g *pg = &phy->phy_g;
2169         struct bwn_softc *sc = mac->mac_sc;
2170         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2171         static const struct bwn_rfatt rfatt0[] = {
2172                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2173                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2174                 { 3, 1 }, { 4, 1 }
2175         };
2176         static const struct bwn_rfatt rfatt1[] = {
2177                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2178                 { 14, 1 }
2179         };
2180         static const struct bwn_rfatt rfatt2[] = {
2181                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2182                 { 9, 1 }
2183         };
2184         static const struct bwn_bbatt bbatt_0[] = {
2185                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2186         };
2187
2188         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2189
2190         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2191                 pg->pg_bbatt.att = 0;
2192         else
2193                 pg->pg_bbatt.att = 2;
2194
2195         /* prepare Radio Attenuation */
2196         pg->pg_rfatt.padmix = 0;
2197
2198         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2199             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2200                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2201                         pg->pg_rfatt.att = 2;
2202                         goto done;
2203                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2204                         pg->pg_rfatt.att = 3;
2205                         goto done;
2206                 }
2207         }
2208
2209         if (phy->type == BWN_PHYTYPE_A) {
2210                 pg->pg_rfatt.att = 0x60;
2211                 goto done;
2212         }
2213
2214         switch (phy->rf_ver) {
2215         case 0x2050:
2216                 switch (phy->rf_rev) {
2217                 case 0:
2218                         pg->pg_rfatt.att = 5;
2219                         goto done;
2220                 case 1:
2221                         if (phy->type == BWN_PHYTYPE_G) {
2222                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2223                                     SIBA_BOARDVENDOR_BCM &&
2224                                     siba_get_pci_subdevice(sc->sc_dev) ==
2225                                     SIBA_BOARD_BCM4309G &&
2226                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2227                                         pg->pg_rfatt.att = 3;
2228                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2229                                     SIBA_BOARDVENDOR_BCM &&
2230                                     siba_get_pci_subdevice(sc->sc_dev) ==
2231                                     SIBA_BOARD_BU4306)
2232                                         pg->pg_rfatt.att = 3;
2233                                 else
2234                                         pg->pg_rfatt.att = 1;
2235                         } else {
2236                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2237                                     SIBA_BOARDVENDOR_BCM &&
2238                                     siba_get_pci_subdevice(sc->sc_dev) ==
2239                                     SIBA_BOARD_BCM4309G &&
2240                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2241                                         pg->pg_rfatt.att = 7;
2242                                 else
2243                                         pg->pg_rfatt.att = 6;
2244                         }
2245                         goto done;
2246                 case 2:
2247                         if (phy->type == BWN_PHYTYPE_G) {
2248                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2249                                     SIBA_BOARDVENDOR_BCM &&
2250                                     siba_get_pci_subdevice(sc->sc_dev) ==
2251                                     SIBA_BOARD_BCM4309G &&
2252                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2253                                         pg->pg_rfatt.att = 3;
2254                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2255                                     SIBA_BOARDVENDOR_BCM &&
2256                                     siba_get_pci_subdevice(sc->sc_dev) ==
2257                                     SIBA_BOARD_BU4306)
2258                                         pg->pg_rfatt.att = 5;
2259                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2260                                         pg->pg_rfatt.att = 4;
2261                                 else
2262                                         pg->pg_rfatt.att = 3;
2263                         } else
2264                                 pg->pg_rfatt.att = 6;
2265                         goto done;
2266                 case 3:
2267                         pg->pg_rfatt.att = 5;
2268                         goto done;
2269                 case 4:
2270                 case 5:
2271                         pg->pg_rfatt.att = 1;
2272                         goto done;
2273                 case 6:
2274                 case 7:
2275                         pg->pg_rfatt.att = 5;
2276                         goto done;
2277                 case 8:
2278                         pg->pg_rfatt.att = 0xa;
2279                         pg->pg_rfatt.padmix = 1;
2280                         goto done;
2281                 case 9:
2282                 default:
2283                         pg->pg_rfatt.att = 5;
2284                         goto done;
2285                 }
2286                 break;
2287         case 0x2053:
2288                 switch (phy->rf_rev) {
2289                 case 1:
2290                         pg->pg_rfatt.att = 6;
2291                         goto done;
2292                 }
2293                 break;
2294         }
2295         pg->pg_rfatt.att = 5;
2296 done:
2297         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2298
2299         if (!bwn_has_hwpctl(mac)) {
2300                 lo->rfatt.array = rfatt0;
2301                 lo->rfatt.len = N(rfatt0);
2302                 lo->rfatt.min = 0;
2303                 lo->rfatt.max = 9;
2304                 goto genbbatt;
2305         }
2306         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2307                 lo->rfatt.array = rfatt1;
2308                 lo->rfatt.len = N(rfatt1);
2309                 lo->rfatt.min = 0;
2310                 lo->rfatt.max = 14;
2311                 goto genbbatt;
2312         }
2313         lo->rfatt.array = rfatt2;
2314         lo->rfatt.len = N(rfatt2);
2315         lo->rfatt.min = 0;
2316         lo->rfatt.max = 9;
2317 genbbatt:
2318         lo->bbatt.array = bbatt_0;
2319         lo->bbatt.len = N(bbatt_0);
2320         lo->bbatt.min = 0;
2321         lo->bbatt.max = 8;
2322
2323         BWN_READ_4(mac, BWN_MACCTL);
2324         if (phy->rev == 1) {
2325                 phy->gmode = 0;
2326                 bwn_reset_core(mac, 0);
2327                 bwn_phy_g_init_sub(mac);
2328                 phy->gmode = 1;
2329                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2330         }
2331         return (0);
2332 }
2333
2334 static uint16_t
2335 bwn_phy_g_txctl(struct bwn_mac *mac)
2336 {
2337         struct bwn_phy *phy = &mac->mac_phy;
2338
2339         if (phy->rf_ver != 0x2050)
2340                 return (0);
2341         if (phy->rf_rev == 1)
2342                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2343         if (phy->rf_rev < 6)
2344                 return (BWN_TXCTL_PA2DB);
2345         if (phy->rf_rev == 8)
2346                 return (BWN_TXCTL_TXMIX);
2347         return (0);
2348 }
2349
2350 static int
2351 bwn_phy_g_init(struct bwn_mac *mac)
2352 {
2353
2354         bwn_phy_g_init_sub(mac);
2355         return (0);
2356 }
2357
2358 static void
2359 bwn_phy_g_exit(struct bwn_mac *mac)
2360 {
2361         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2362         struct bwn_lo_calib *cal, *tmp;
2363
2364         if (lo == NULL)
2365                 return;
2366         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2367                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2368                 free(cal, M_DEVBUF);
2369         }
2370 }
2371
2372 static uint16_t
2373 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2374 {
2375
2376         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2377         return (BWN_READ_2(mac, BWN_PHYDATA));
2378 }
2379
2380 static void
2381 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2382 {
2383
2384         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2385         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2386 }
2387
2388 static uint16_t
2389 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2390 {
2391
2392         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2393         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2394         return (BWN_READ_2(mac, BWN_RFDATALO));
2395 }
2396
2397 static void
2398 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2399 {
2400
2401         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2402         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2403         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2404 }
2405
2406 static int
2407 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2408 {
2409
2410         return (mac->mac_phy.rev >= 6);
2411 }
2412
2413 static void
2414 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2415 {
2416         struct bwn_phy *phy = &mac->mac_phy;
2417         struct bwn_phy_g *pg = &phy->phy_g;
2418         unsigned int channel;
2419         uint16_t rfover, rfoverval;
2420
2421         if (on) {
2422                 if (phy->rf_on)
2423                         return;
2424
2425                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2426                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2427                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2428                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2429                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2430                             pg->pg_radioctx_over);
2431                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2432                             pg->pg_radioctx_overval);
2433                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2434                 }
2435                 channel = phy->chan;
2436                 bwn_phy_g_switch_chan(mac, 6, 1);
2437                 bwn_phy_g_switch_chan(mac, channel, 0);
2438                 return;
2439         }
2440
2441         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2442         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2443         pg->pg_radioctx_over = rfover;
2444         pg->pg_radioctx_overval = rfoverval;
2445         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2446         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2447         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2448 }
2449
2450 static int
2451 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2452 {
2453
2454         if ((newchan < 1) || (newchan > 14))
2455                 return (EINVAL);
2456         bwn_phy_g_switch_chan(mac, newchan, 0);
2457
2458         return (0);
2459 }
2460
2461 static uint32_t
2462 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2463 {
2464
2465         return (1);
2466 }
2467
2468 static void
2469 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2470 {
2471         struct bwn_phy *phy = &mac->mac_phy;
2472         uint64_t hf;
2473         int autodiv = 0;
2474         uint16_t tmp;
2475
2476         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2477                 autodiv = 1;
2478
2479         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2480         bwn_hf_write(mac, hf);
2481
2482         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2483             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2484             ((autodiv ? BWN_ANTAUTO1 : antenna)
2485                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2486
2487         if (autodiv) {
2488                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2489                 if (antenna == BWN_ANTAUTO1)
2490                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2491                 else
2492                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2493                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2494         }
2495         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2496         if (autodiv)
2497                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2498         else
2499                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2500         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2501         if (phy->rev >= 2) {
2502                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2503                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2504                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2505                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2506                     0x15);
2507                 if (phy->rev == 2)
2508                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2509                 else
2510                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2511                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2512                             8);
2513         }
2514         if (phy->rev >= 6)
2515                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2516
2517         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2518         bwn_hf_write(mac, hf);
2519 }
2520
2521 static int
2522 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2523 {
2524         struct bwn_phy *phy = &mac->mac_phy;
2525         struct bwn_phy_g *pg = &phy->phy_g;
2526
2527         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2528         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2529
2530         if (phy->rev == 0 || !phy->gmode)
2531                 return (ENODEV);
2532
2533         pg->pg_aci_wlan_automatic = 0;
2534         return (0);
2535 }
2536
2537 static int
2538 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2539 {
2540         struct bwn_phy *phy = &mac->mac_phy;
2541         struct bwn_phy_g *pg = &phy->phy_g;
2542         struct bwn_softc *sc = mac->mac_sc;
2543         unsigned int tssi;
2544         int cck, ofdm;
2545         int power;
2546         int rfatt, bbatt;
2547         unsigned int max;
2548
2549         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2550
2551         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2552         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2553         if (cck < 0 && ofdm < 0) {
2554                 if (ignore_tssi == 0)
2555                         return (BWN_TXPWR_RES_DONE);
2556                 cck = 0;
2557                 ofdm = 0;
2558         }
2559         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2560         if (pg->pg_avgtssi != 0xff)
2561                 tssi = (tssi + pg->pg_avgtssi) / 2;
2562         pg->pg_avgtssi = tssi;
2563         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2564
2565         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2566         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2567                 max -= 3;
2568         if (max >= 120) {
2569                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2570                 max = 80;
2571                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2572         }
2573
2574         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2575             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2576              tssi, 0x00), 0x3f)]);
2577         if (power == 0)
2578                 return (BWN_TXPWR_RES_DONE);
2579
2580         rfatt = -((power + 7) / 8);
2581         bbatt = (-(power / 2)) - (4 * rfatt);
2582         if ((rfatt == 0) && (bbatt == 0))
2583                 return (BWN_TXPWR_RES_DONE);
2584         pg->pg_bbatt_delta = bbatt;
2585         pg->pg_rfatt_delta = rfatt;
2586         return (BWN_TXPWR_RES_NEED_ADJUST);
2587 }
2588
2589 static void
2590 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2591 {
2592         struct bwn_phy *phy = &mac->mac_phy;
2593         struct bwn_phy_g *pg = &phy->phy_g;
2594         struct bwn_softc *sc = mac->mac_sc;
2595         int rfatt, bbatt;
2596         uint8_t txctl;
2597
2598         bwn_mac_suspend(mac);
2599
2600         BWN_ASSERT_LOCKED(sc);
2601
2602         bbatt = pg->pg_bbatt.att;
2603         bbatt += pg->pg_bbatt_delta;
2604         rfatt = pg->pg_rfatt.att;
2605         rfatt += pg->pg_rfatt_delta;
2606
2607         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2608         txctl = pg->pg_txctl;
2609         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2610                 if (rfatt <= 1) {
2611                         if (txctl == 0) {
2612                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2613                                 rfatt += 2;
2614                                 bbatt += 2;
2615                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2616                             BWN_BFL_PACTRL) {
2617                                 bbatt += 4 * (rfatt - 2);
2618                                 rfatt = 2;
2619                         }
2620                 } else if (rfatt > 4 && txctl) {
2621                         txctl = 0;
2622                         if (bbatt < 3) {
2623                                 rfatt -= 3;
2624                                 bbatt += 2;
2625                         } else {
2626                                 rfatt -= 2;
2627                                 bbatt -= 2;
2628                         }
2629                 }
2630         }
2631         pg->pg_txctl = txctl;
2632         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2633         pg->pg_rfatt.att = rfatt;
2634         pg->pg_bbatt.att = bbatt;
2635
2636         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2637
2638         bwn_phy_lock(mac);
2639         bwn_rf_lock(mac);
2640         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2641             pg->pg_txctl);
2642         bwn_rf_unlock(mac);
2643         bwn_phy_unlock(mac);
2644
2645         bwn_mac_enable(mac);
2646 }
2647
2648 static void
2649 bwn_phy_g_task_15s(struct bwn_mac *mac)
2650 {
2651         struct bwn_phy *phy = &mac->mac_phy;
2652         struct bwn_phy_g *pg = &phy->phy_g;
2653         struct bwn_softc *sc = mac->mac_sc;
2654         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2655         unsigned long expire, now;
2656         struct bwn_lo_calib *cal, *tmp;
2657         uint8_t expired = 0;
2658
2659         bwn_mac_suspend(mac);
2660
2661         if (lo == NULL)
2662                 goto fail;
2663
2664         BWN_GETTIME(now);
2665         if (bwn_has_hwpctl(mac)) {
2666                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2667                 if (time_before(lo->pwr_vec_read_time, expire)) {
2668                         bwn_lo_get_powervector(mac);
2669                         bwn_phy_g_dc_lookup_init(mac, 0);
2670                 }
2671                 goto fail;
2672         }
2673
2674         expire = now - BWN_LO_CALIB_EXPIRE;
2675         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2676                 if (!time_before(cal->calib_time, expire))
2677                         continue;
2678                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2679                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2680                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2681                         expired = 1;
2682                 }
2683
2684                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2685                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2686                     cal->ctl.i, cal->ctl.q);
2687
2688                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2689                 free(cal, M_DEVBUF);
2690         }
2691         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2692                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2693                     &pg->pg_rfatt);
2694                 if (cal == NULL) {
2695                         device_printf(sc->sc_dev,
2696                             "failed to recalibrate LO\n");
2697                         goto fail;
2698                 }
2699                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2700                 bwn_lo_write(mac, &cal->ctl);
2701         }
2702
2703 fail:
2704         bwn_mac_enable(mac);
2705 }
2706
2707 static void
2708 bwn_phy_g_task_60s(struct bwn_mac *mac)
2709 {
2710         struct bwn_phy *phy = &mac->mac_phy;
2711         struct bwn_softc *sc = mac->mac_sc;
2712         uint8_t old = phy->chan;
2713
2714         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2715                 return;
2716
2717         bwn_mac_suspend(mac);
2718         bwn_nrssi_slope_11g(mac);
2719         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2720                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2721                 bwn_switch_channel(mac, old);
2722         }
2723         bwn_mac_enable(mac);
2724 }
2725
2726 static void
2727 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2728 {
2729
2730         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2731 }
2732
2733 static int
2734 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2735         const struct ieee80211_bpf_params *params)
2736 {
2737         struct ieee80211com *ic = ni->ni_ic;
2738         struct ifnet *ifp = ic->ic_ifp;
2739         struct bwn_softc *sc = ifp->if_softc;
2740         struct bwn_mac *mac = sc->sc_curmac;
2741
2742         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2743             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2744                 ieee80211_free_node(ni);
2745                 m_freem(m);
2746                 return (ENETDOWN);
2747         }
2748
2749         BWN_LOCK(sc);
2750         if (bwn_tx_isfull(sc, m)) {
2751                 ieee80211_free_node(ni);
2752                 m_freem(m);
2753                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2754                 BWN_UNLOCK(sc);
2755                 return (ENOBUFS);
2756         }
2757
2758         if (bwn_tx_start(sc, ni, m) != 0) {
2759                 if (ni != NULL)
2760                         ieee80211_free_node(ni);
2761                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2762         }
2763         sc->sc_watchdog_timer = 5;
2764         BWN_UNLOCK(sc);
2765         return (0);
2766 }
2767
2768 /*
2769  * Callback from the 802.11 layer to update the slot time
2770  * based on the current setting.  We use it to notify the
2771  * firmware of ERP changes and the f/w takes care of things
2772  * like slot time and preamble.
2773  */
2774 static void
2775 bwn_updateslot(struct ieee80211com *ic)
2776 {
2777         struct bwn_softc *sc = ic->ic_softc;
2778         struct bwn_mac *mac;
2779
2780         BWN_LOCK(sc);
2781         if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
2782                 mac = (struct bwn_mac *)sc->sc_curmac;
2783                 bwn_set_slot_time(mac,
2784                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2785         }
2786         BWN_UNLOCK(sc);
2787 }
2788
2789 /*
2790  * Callback from the 802.11 layer after a promiscuous mode change.
2791  * Note this interface does not check the operating mode as this
2792  * is an internal callback and we are expected to honor the current
2793  * state (e.g. this is used for setting the interface in promiscuous
2794  * mode when operating in hostap mode to do ACS).
2795  */
2796 static void
2797 bwn_update_promisc(struct ieee80211com *ic)
2798 {
2799         struct bwn_softc *sc = ic->ic_softc;
2800         struct bwn_mac *mac = sc->sc_curmac;
2801
2802         BWN_LOCK(sc);
2803         mac = sc->sc_curmac;
2804         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2805                 if (ic->ic_ifp->if_flags & IFF_PROMISC)
2806                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2807                 else
2808                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2809                 bwn_set_opmode(mac);
2810         }
2811         BWN_UNLOCK(sc);
2812 }
2813
2814 /*
2815  * Callback from the 802.11 layer to update WME parameters.
2816  */
2817 static int
2818 bwn_wme_update(struct ieee80211com *ic)
2819 {
2820         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2821         struct bwn_mac *mac = sc->sc_curmac;
2822         struct wmeParams *wmep;
2823         int i;
2824
2825         BWN_LOCK(sc);
2826         mac = sc->sc_curmac;
2827         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2828                 bwn_mac_suspend(mac);
2829                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2830                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2831                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2832                 }
2833                 bwn_mac_enable(mac);
2834         }
2835         BWN_UNLOCK(sc);
2836         return (0);
2837 }
2838
2839 static void
2840 bwn_scan_start(struct ieee80211com *ic)
2841 {
2842         struct ifnet *ifp = ic->ic_ifp;
2843         struct bwn_softc *sc = ifp->if_softc;
2844         struct bwn_mac *mac;
2845
2846         BWN_LOCK(sc);
2847         mac = sc->sc_curmac;
2848         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2849                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2850                 bwn_set_opmode(mac);
2851                 /* disable CFP update during scan */
2852                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2853         }
2854         BWN_UNLOCK(sc);
2855 }
2856
2857 static void
2858 bwn_scan_end(struct ieee80211com *ic)
2859 {
2860         struct ifnet *ifp = ic->ic_ifp;
2861         struct bwn_softc *sc = ifp->if_softc;
2862         struct bwn_mac *mac;
2863
2864         BWN_LOCK(sc);
2865         mac = sc->sc_curmac;
2866         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2867                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2868                 bwn_set_opmode(mac);
2869                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2870         }
2871         BWN_UNLOCK(sc);
2872 }
2873
2874 static void
2875 bwn_set_channel(struct ieee80211com *ic)
2876 {
2877         struct ifnet *ifp = ic->ic_ifp;
2878         struct bwn_softc *sc = ifp->if_softc;
2879         struct bwn_mac *mac = sc->sc_curmac;
2880         struct bwn_phy *phy = &mac->mac_phy;
2881         int chan, error;
2882
2883         BWN_LOCK(sc);
2884
2885         error = bwn_switch_band(sc, ic->ic_curchan);
2886         if (error)
2887                 goto fail;
2888         bwn_mac_suspend(mac);
2889         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2890         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2891         if (chan != phy->chan)
2892                 bwn_switch_channel(mac, chan);
2893
2894         /* TX power level */
2895         if (ic->ic_curchan->ic_maxpower != 0 &&
2896             ic->ic_curchan->ic_maxpower != phy->txpower) {
2897                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2898                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2899                     BWN_TXPWR_IGNORE_TSSI);
2900         }
2901
2902         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2903         if (phy->set_antenna)
2904                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2905
2906         if (sc->sc_rf_enabled != phy->rf_on) {
2907                 if (sc->sc_rf_enabled) {
2908                         bwn_rf_turnon(mac);
2909                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2910                                 device_printf(sc->sc_dev,
2911                                     "please turn on the RF switch\n");
2912                 } else
2913                         bwn_rf_turnoff(mac);
2914         }
2915
2916         bwn_mac_enable(mac);
2917
2918 fail:
2919         /*
2920          * Setup radio tap channel freq and flags
2921          */
2922         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2923                 htole16(ic->ic_curchan->ic_freq);
2924         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2925                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2926
2927         BWN_UNLOCK(sc);
2928 }
2929
2930 static struct ieee80211vap *
2931 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2932     enum ieee80211_opmode opmode, int flags,
2933     const uint8_t bssid[IEEE80211_ADDR_LEN],
2934     const uint8_t mac0[IEEE80211_ADDR_LEN])
2935 {
2936         struct ifnet *ifp = ic->ic_ifp;
2937         struct bwn_softc *sc = ifp->if_softc;
2938         struct ieee80211vap *vap;
2939         struct bwn_vap *bvp;
2940         uint8_t mac[IEEE80211_ADDR_LEN];
2941
2942         IEEE80211_ADDR_COPY(mac, mac0);
2943         switch (opmode) {
2944         case IEEE80211_M_HOSTAP:
2945         case IEEE80211_M_MBSS:
2946         case IEEE80211_M_STA:
2947         case IEEE80211_M_WDS:
2948         case IEEE80211_M_MONITOR:
2949         case IEEE80211_M_IBSS:
2950         case IEEE80211_M_AHDEMO:
2951                 break;
2952         default:
2953                 return (NULL);
2954         }
2955
2956         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2957
2958         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2959             M_80211_VAP, M_NOWAIT | M_ZERO);
2960         if (bvp == NULL) {
2961                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2962                 return (NULL);
2963         }
2964         vap = &bvp->bv_vap;
2965         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2966         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2967         /* override with driver methods */
2968         bvp->bv_newstate = vap->iv_newstate;
2969         vap->iv_newstate = bwn_newstate;
2970
2971         /* override max aid so sta's cannot assoc when we're out of sta id's */
2972         vap->iv_max_aid = BWN_STAID_MAX;
2973
2974         ieee80211_ratectl_init(vap);
2975
2976         /* complete setup */
2977         ieee80211_vap_attach(vap, ieee80211_media_change,
2978             ieee80211_media_status);
2979         return (vap);
2980 }
2981
2982 static void
2983 bwn_vap_delete(struct ieee80211vap *vap)
2984 {
2985         struct bwn_vap *bvp = BWN_VAP(vap);
2986
2987         ieee80211_ratectl_deinit(vap);
2988         ieee80211_vap_detach(vap);
2989         free(bvp, M_80211_VAP);
2990 }
2991
2992 static void
2993 bwn_init(void *arg)
2994 {
2995         struct bwn_softc *sc = arg;
2996         struct ifnet *ifp = sc->sc_ifp;
2997         struct ieee80211com *ic = ifp->if_l2com;
2998         int error = 0;
2999
3000         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3001                 __func__, ifp->if_flags);
3002
3003         BWN_LOCK(sc);
3004         error = bwn_init_locked(sc);
3005         BWN_UNLOCK(sc);
3006
3007         if (error == 0)
3008                 ieee80211_start_all(ic);        /* start all vap's */
3009 }
3010
3011 static int
3012 bwn_init_locked(struct bwn_softc *sc)
3013 {
3014         struct bwn_mac *mac;
3015         struct ifnet *ifp = sc->sc_ifp;
3016         int error;
3017
3018         BWN_ASSERT_LOCKED(sc);
3019
3020         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3021         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3022         sc->sc_filters = 0;
3023         bwn_wme_clear(sc);
3024         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3025         sc->sc_rf_enabled = 1;
3026
3027         mac = sc->sc_curmac;
3028         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3029                 error = bwn_core_init(mac);
3030                 if (error != 0)
3031                         return (error);
3032         }
3033         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3034                 bwn_core_start(mac);
3035
3036         bwn_set_opmode(mac);
3037         bwn_set_pretbtt(mac);
3038         bwn_spu_setdelay(mac, 0);
3039         bwn_set_macaddr(mac);
3040
3041         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3042         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3043         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3044
3045         return (0);
3046 }
3047
3048 static void
3049 bwn_stop(struct bwn_softc *sc, int statechg)
3050 {
3051
3052         BWN_LOCK(sc);
3053         bwn_stop_locked(sc, statechg);
3054         BWN_UNLOCK(sc);
3055 }
3056
3057 static void
3058 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3059 {
3060         struct bwn_mac *mac = sc->sc_curmac;
3061         struct ifnet *ifp = sc->sc_ifp;
3062
3063         BWN_ASSERT_LOCKED(sc);
3064
3065         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3066                 /* XXX FIXME opmode not based on VAP */
3067                 bwn_set_opmode(mac);
3068                 bwn_set_macaddr(mac);
3069         }
3070
3071         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3072                 bwn_core_stop(mac);
3073
3074         callout_stop(&sc->sc_led_blink_ch);
3075         sc->sc_led_blinking = 0;
3076
3077         bwn_core_exit(mac);
3078         sc->sc_rf_enabled = 0;
3079
3080         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3081 }
3082
3083 static void
3084 bwn_wme_clear(struct bwn_softc *sc)
3085 {
3086 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3087         struct wmeParams *p;
3088         unsigned int i;
3089
3090         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3091             ("%s:%d: fail", __func__, __LINE__));
3092
3093         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3094                 p = &(sc->sc_wmeParams[i]);
3095
3096                 switch (bwn_wme_shm_offsets[i]) {
3097                 case BWN_WME_VOICE:
3098                         p->wmep_txopLimit = 0;
3099                         p->wmep_aifsn = 2;
3100                         /* XXX FIXME: log2(cwmin) */
3101                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3102                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3103                         break;
3104                 case BWN_WME_VIDEO:
3105                         p->wmep_txopLimit = 0;
3106                         p->wmep_aifsn = 2;
3107                         /* XXX FIXME: log2(cwmin) */
3108                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3109                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3110                         break;
3111                 case BWN_WME_BESTEFFORT:
3112                         p->wmep_txopLimit = 0;
3113                         p->wmep_aifsn = 3;
3114                         /* XXX FIXME: log2(cwmin) */
3115                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3116                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3117                         break;
3118                 case BWN_WME_BACKGROUND:
3119                         p->wmep_txopLimit = 0;
3120                         p->wmep_aifsn = 7;
3121                         /* XXX FIXME: log2(cwmin) */
3122                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3123                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3124                         break;
3125                 default:
3126                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3127                 }
3128         }
3129 }
3130
3131 static int
3132 bwn_core_init(struct bwn_mac *mac)
3133 {
3134         struct bwn_softc *sc = mac->mac_sc;
3135         uint64_t hf;
3136         int error;
3137
3138         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3139             ("%s:%d: fail", __func__, __LINE__));
3140
3141         siba_powerup(sc->sc_dev, 0);
3142         if (!siba_dev_isup(sc->sc_dev))
3143                 bwn_reset_core(mac,
3144                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3145
3146         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3147         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3148         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3149         BWN_GETTIME(mac->mac_phy.nexttime);
3150         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3151         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3152         mac->mac_stats.link_noise = -95;
3153         mac->mac_reason_intr = 0;
3154         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3155         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3156 #ifdef BWN_DEBUG
3157         if (sc->sc_debug & BWN_DEBUG_XMIT)
3158                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3159 #endif
3160         mac->mac_suspended = 1;
3161         mac->mac_task_state = 0;
3162         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3163
3164         mac->mac_phy.init_pre(mac);
3165
3166         siba_pcicore_intr(sc->sc_dev);
3167
3168         siba_fix_imcfglobug(sc->sc_dev);
3169         bwn_bt_disable(mac);
3170         if (mac->mac_phy.prepare_hw) {
3171                 error = mac->mac_phy.prepare_hw(mac);
3172                 if (error)
3173                         goto fail0;
3174         }
3175         error = bwn_chip_init(mac);
3176         if (error)
3177                 goto fail0;
3178         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3179             siba_get_revid(sc->sc_dev));
3180         hf = bwn_hf_read(mac);
3181         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3182                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3183                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3184                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3185                 if (mac->mac_phy.rev == 1)
3186                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3187         }
3188         if (mac->mac_phy.rf_ver == 0x2050) {
3189                 if (mac->mac_phy.rf_rev < 6)
3190                         hf |= BWN_HF_FORCE_VCO_RECALC;
3191                 if (mac->mac_phy.rf_rev == 6)
3192                         hf |= BWN_HF_4318_TSSI;
3193         }
3194         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3195                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3196         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3197             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3198                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3199         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3200         bwn_hf_write(mac, hf);
3201
3202         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3203         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3204         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3205         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3206
3207         bwn_rate_init(mac);
3208         bwn_set_phytxctl(mac);
3209
3210         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3211             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3212         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3213
3214         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3215                 bwn_pio_init(mac);
3216         else
3217                 bwn_dma_init(mac);
3218         bwn_wme_init(mac);
3219         bwn_spu_setdelay(mac, 1);
3220         bwn_bt_enable(mac);
3221
3222         siba_powerup(sc->sc_dev,
3223             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3224         bwn_set_macaddr(mac);
3225         bwn_crypt_init(mac);
3226
3227         /* XXX LED initializatin */
3228
3229         mac->mac_status = BWN_MAC_STATUS_INITED;
3230
3231         return (error);
3232
3233 fail0:
3234         siba_powerdown(sc->sc_dev);
3235         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3236             ("%s:%d: fail", __func__, __LINE__));
3237         return (error);
3238 }
3239
3240 static void
3241 bwn_core_start(struct bwn_mac *mac)
3242 {
3243         struct bwn_softc *sc = mac->mac_sc;
3244         uint32_t tmp;
3245
3246         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3247             ("%s:%d: fail", __func__, __LINE__));
3248
3249         if (siba_get_revid(sc->sc_dev) < 5)
3250                 return;
3251
3252         while (1) {
3253                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3254                 if (!(tmp & 0x00000001))
3255                         break;
3256                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3257         }
3258
3259         bwn_mac_enable(mac);
3260         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3261         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3262
3263         mac->mac_status = BWN_MAC_STATUS_STARTED;
3264 }
3265
3266 static void
3267 bwn_core_exit(struct bwn_mac *mac)
3268 {
3269         struct bwn_softc *sc = mac->mac_sc;
3270         uint32_t macctl;
3271
3272         BWN_ASSERT_LOCKED(mac->mac_sc);
3273
3274         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3275             ("%s:%d: fail", __func__, __LINE__));
3276
3277         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3278                 return;
3279         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3280
3281         macctl = BWN_READ_4(mac, BWN_MACCTL);
3282         macctl &= ~BWN_MACCTL_MCODE_RUN;
3283         macctl |= BWN_MACCTL_MCODE_JMP0;
3284         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3285
3286         bwn_dma_stop(mac);
3287         bwn_pio_stop(mac);
3288         bwn_chip_exit(mac);
3289         mac->mac_phy.switch_analog(mac, 0);
3290         siba_dev_down(sc->sc_dev, 0);
3291         siba_powerdown(sc->sc_dev);
3292 }
3293
3294 static void
3295 bwn_bt_disable(struct bwn_mac *mac)
3296 {
3297         struct bwn_softc *sc = mac->mac_sc;
3298
3299         (void)sc;
3300         /* XXX do nothing yet */
3301 }
3302
3303 static int
3304 bwn_chip_init(struct bwn_mac *mac)
3305 {
3306         struct bwn_softc *sc = mac->mac_sc;
3307         struct bwn_phy *phy = &mac->mac_phy;
3308         uint32_t macctl;
3309         int error;
3310
3311         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3312         if (phy->gmode)
3313                 macctl |= BWN_MACCTL_GMODE;
3314         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3315
3316         error = bwn_fw_fillinfo(mac);
3317         if (error)
3318                 return (error);
3319         error = bwn_fw_loaducode(mac);
3320         if (error)
3321                 return (error);
3322
3323         error = bwn_gpio_init(mac);
3324         if (error)
3325                 return (error);
3326
3327         error = bwn_fw_loadinitvals(mac);
3328         if (error) {
3329                 siba_gpio_set(sc->sc_dev, 0);
3330                 return (error);
3331         }
3332         phy->switch_analog(mac, 1);
3333         error = bwn_phy_init(mac);
3334         if (error) {
3335                 siba_gpio_set(sc->sc_dev, 0);
3336                 return (error);
3337         }
3338         if (phy->set_im)
3339                 phy->set_im(mac, BWN_IMMODE_NONE);
3340         if (phy->set_antenna)
3341                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3342         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3343
3344         if (phy->type == BWN_PHYTYPE_B)
3345                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3346         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3347         if (siba_get_revid(sc->sc_dev) < 5)
3348                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3349
3350         BWN_WRITE_4(mac, BWN_MACCTL,
3351             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3352         BWN_WRITE_4(mac, BWN_MACCTL,
3353             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3354         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3355
3356         bwn_set_opmode(mac);
3357         if (siba_get_revid(sc->sc_dev) < 3) {
3358                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3359                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3360                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3361                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3362         } else {
3363                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3364                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3365         }
3366         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3367         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3368         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3369         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3370         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3371         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3372         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3373         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3374             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3375         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3376         return (error);
3377 }
3378
3379 /* read hostflags */
3380 static uint64_t
3381 bwn_hf_read(struct bwn_mac *mac)
3382 {
3383         uint64_t ret;
3384
3385         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3386         ret <<= 16;
3387         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3388         ret <<= 16;
3389         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3390         return (ret);
3391 }
3392
3393 static void
3394 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3395 {
3396
3397         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3398             (value & 0x00000000ffffull));
3399         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3400             (value & 0x0000ffff0000ull) >> 16);
3401         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3402             (value & 0xffff00000000ULL) >> 32);
3403 }
3404
3405 static void
3406 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3407 {
3408
3409         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3410         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3411 }
3412
3413 static void
3414 bwn_rate_init(struct bwn_mac *mac)
3415 {
3416
3417         switch (mac->mac_phy.type) {
3418         case BWN_PHYTYPE_A:
3419         case BWN_PHYTYPE_G:
3420         case BWN_PHYTYPE_LP:
3421         case BWN_PHYTYPE_N:
3422                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3423                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3424                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3425                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3426                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3427                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3428                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3429                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3430                         break;
3431                 /* FALLTHROUGH */
3432         case BWN_PHYTYPE_B:
3433                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3434                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3435                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3436                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3437                 break;
3438         default:
3439                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3440         }
3441 }
3442
3443 static void
3444 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3445 {
3446         uint16_t offset;
3447
3448         if (ofdm) {
3449                 offset = 0x480;
3450                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3451         } else {
3452                 offset = 0x4c0;
3453                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3454         }
3455         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3456             bwn_shm_read_2(mac, BWN_SHARED, offset));
3457 }
3458
3459 static uint8_t
3460 bwn_plcp_getcck(const uint8_t bitrate)
3461 {
3462
3463         switch (bitrate) {
3464         case BWN_CCK_RATE_1MB:
3465                 return (0x0a);
3466         case BWN_CCK_RATE_2MB:
3467                 return (0x14);
3468         case BWN_CCK_RATE_5MB:
3469                 return (0x37);
3470         case BWN_CCK_RATE_11MB:
3471                 return (0x6e);
3472         }
3473         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3474         return (0);
3475 }
3476
3477 static uint8_t
3478 bwn_plcp_getofdm(const uint8_t bitrate)
3479 {
3480
3481         switch (bitrate) {
3482         case BWN_OFDM_RATE_6MB:
3483                 return (0xb);
3484         case BWN_OFDM_RATE_9MB:
3485                 return (0xf);
3486         case BWN_OFDM_RATE_12MB:
3487                 return (0xa);
3488         case BWN_OFDM_RATE_18MB:
3489                 return (0xe);
3490         case BWN_OFDM_RATE_24MB:
3491                 return (0x9);
3492         case BWN_OFDM_RATE_36MB:
3493                 return (0xd);
3494         case BWN_OFDM_RATE_48MB:
3495                 return (0x8);
3496         case BWN_OFDM_RATE_54MB:
3497                 return (0xc);
3498         }
3499         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3500         return (0);
3501 }
3502
3503 static void
3504 bwn_set_phytxctl(struct bwn_mac *mac)
3505 {
3506         uint16_t ctl;
3507
3508         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3509             BWN_TX_PHY_TXPWR);
3510         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3511         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3512         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3513 }
3514
3515 static void
3516 bwn_pio_init(struct bwn_mac *mac)
3517 {
3518         struct bwn_pio *pio = &mac->mac_method.pio;
3519
3520         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3521             & ~BWN_MACCTL_BIGENDIAN);
3522         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3523
3524         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3525         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3526         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3527         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3528         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3529         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3530 }
3531
3532 static void
3533 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3534     int index)
3535 {
3536         struct bwn_pio_txpkt *tp;
3537         struct bwn_softc *sc = mac->mac_sc;
3538         unsigned int i;
3539
3540         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3541         tq->tq_index = index;
3542
3543         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3544         if (siba_get_revid(sc->sc_dev) >= 8)
3545                 tq->tq_size = 1920;
3546         else {
3547                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3548                 tq->tq_size -= 80;
3549         }
3550
3551         TAILQ_INIT(&tq->tq_pktlist);
3552         for (i = 0; i < N(tq->tq_pkts); i++) {
3553                 tp = &(tq->tq_pkts[i]);
3554                 tp->tp_index = i;
3555                 tp->tp_queue = tq;
3556                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3557         }
3558 }
3559
3560 static uint16_t
3561 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3562 {
3563         struct bwn_softc *sc = mac->mac_sc;
3564         static const uint16_t bases[] = {
3565                 BWN_PIO_BASE0,
3566                 BWN_PIO_BASE1,
3567                 BWN_PIO_BASE2,
3568                 BWN_PIO_BASE3,
3569                 BWN_PIO_BASE4,
3570                 BWN_PIO_BASE5,
3571                 BWN_PIO_BASE6,
3572                 BWN_PIO_BASE7,
3573         };
3574         static const uint16_t bases_rev11[] = {
3575                 BWN_PIO11_BASE0,
3576                 BWN_PIO11_BASE1,
3577                 BWN_PIO11_BASE2,
3578                 BWN_PIO11_BASE3,
3579                 BWN_PIO11_BASE4,
3580                 BWN_PIO11_BASE5,
3581         };
3582
3583         if (siba_get_revid(sc->sc_dev) >= 11) {
3584                 if (index >= N(bases_rev11))
3585                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3586                 return (bases_rev11[index]);
3587         }
3588         if (index >= N(bases))
3589                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3590         return (bases[index]);
3591 }
3592
3593 static void
3594 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3595     int index)
3596 {
3597         struct bwn_softc *sc = mac->mac_sc;
3598
3599         prq->prq_mac = mac;
3600         prq->prq_rev = siba_get_revid(sc->sc_dev);
3601         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3602         bwn_dma_rxdirectfifo(mac, index, 1);
3603 }
3604
3605 static void
3606 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3607 {
3608         if (tq == NULL)
3609                 return;
3610         bwn_pio_cancel_tx_packets(tq);
3611 }
3612
3613 static void
3614 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3615 {
3616
3617         bwn_destroy_pioqueue_tx(pio);
3618 }
3619
3620 static uint16_t
3621 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3622     uint16_t offset)
3623 {
3624
3625         return (BWN_READ_2(mac, tq->tq_base + offset));
3626 }
3627
3628 static void
3629 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3630 {
3631         uint32_t ctl;
3632         int type;
3633         uint16_t base;
3634
3635         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3636         base = bwn_dma_base(type, idx);
3637         if (type == BWN_DMA_64BIT) {
3638                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3639                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3640                 if (enable)
3641                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3642                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3643         } else {
3644                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3645                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3646                 if (enable)
3647                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3648                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3649         }
3650 }
3651
3652 static uint64_t
3653 bwn_dma_mask(struct bwn_mac *mac)
3654 {
3655         uint32_t tmp;
3656         uint16_t base;
3657
3658         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3659         if (tmp & SIBA_TGSHIGH_DMA64)
3660                 return (BWN_DMA_BIT_MASK(64));
3661         base = bwn_dma_base(0, 0);
3662         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3663         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3664         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3665                 return (BWN_DMA_BIT_MASK(32));
3666
3667         return (BWN_DMA_BIT_MASK(30));
3668 }
3669
3670 static int
3671 bwn_dma_mask2type(uint64_t dmamask)
3672 {
3673
3674         if (dmamask == BWN_DMA_BIT_MASK(30))
3675                 return (BWN_DMA_30BIT);
3676         if (dmamask == BWN_DMA_BIT_MASK(32))
3677                 return (BWN_DMA_32BIT);
3678         if (dmamask == BWN_DMA_BIT_MASK(64))
3679                 return (BWN_DMA_64BIT);
3680         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3681         return (BWN_DMA_30BIT);
3682 }
3683
3684 static void
3685 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3686 {
3687         struct bwn_pio_txpkt *tp;
3688         unsigned int i;
3689
3690         for (i = 0; i < N(tq->tq_pkts); i++) {
3691                 tp = &(tq->tq_pkts[i]);
3692                 if (tp->tp_m) {
3693                         m_freem(tp->tp_m);
3694                         tp->tp_m = NULL;
3695                 }
3696         }
3697 }
3698
3699 static uint16_t
3700 bwn_dma_base(int type, int controller_idx)
3701 {
3702         static const uint16_t map64[] = {
3703                 BWN_DMA64_BASE0,
3704                 BWN_DMA64_BASE1,
3705                 BWN_DMA64_BASE2,
3706                 BWN_DMA64_BASE3,
3707                 BWN_DMA64_BASE4,
3708                 BWN_DMA64_BASE5,
3709         };
3710         static const uint16_t map32[] = {
3711                 BWN_DMA32_BASE0,
3712                 BWN_DMA32_BASE1,
3713                 BWN_DMA32_BASE2,
3714                 BWN_DMA32_BASE3,
3715                 BWN_DMA32_BASE4,
3716                 BWN_DMA32_BASE5,
3717         };
3718
3719         if (type == BWN_DMA_64BIT) {
3720                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3721                     ("%s:%d: fail", __func__, __LINE__));
3722                 return (map64[controller_idx]);
3723         }
3724         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3725             ("%s:%d: fail", __func__, __LINE__));
3726         return (map32[controller_idx]);
3727 }
3728
3729 static void
3730 bwn_dma_init(struct bwn_mac *mac)
3731 {
3732         struct bwn_dma *dma = &mac->mac_method.dma;
3733
3734         /* setup TX DMA channels. */
3735         bwn_dma_setup(dma->wme[WME_AC_BK]);
3736         bwn_dma_setup(dma->wme[WME_AC_BE]);
3737         bwn_dma_setup(dma->wme[WME_AC_VI]);
3738         bwn_dma_setup(dma->wme[WME_AC_VO]);
3739         bwn_dma_setup(dma->mcast);
3740         /* setup RX DMA channel. */
3741         bwn_dma_setup(dma->rx);
3742 }
3743
3744 static struct bwn_dma_ring *
3745 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3746     int for_tx, int type)
3747 {
3748         struct bwn_dma *dma = &mac->mac_method.dma;
3749         struct bwn_dma_ring *dr;
3750         struct bwn_dmadesc_generic *desc;
3751         struct bwn_dmadesc_meta *mt;
3752         struct bwn_softc *sc = mac->mac_sc;
3753         int error, i;
3754
3755         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3756         if (dr == NULL)
3757                 goto out;
3758         dr->dr_numslots = BWN_RXRING_SLOTS;
3759         if (for_tx)
3760                 dr->dr_numslots = BWN_TXRING_SLOTS;
3761
3762         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3763             M_DEVBUF, M_NOWAIT | M_ZERO);
3764         if (dr->dr_meta == NULL)
3765                 goto fail0;
3766
3767         dr->dr_type = type;
3768         dr->dr_mac = mac;
3769         dr->dr_base = bwn_dma_base(type, controller_index);
3770         dr->dr_index = controller_index;
3771         if (type == BWN_DMA_64BIT) {
3772                 dr->getdesc = bwn_dma_64_getdesc;
3773                 dr->setdesc = bwn_dma_64_setdesc;
3774                 dr->start_transfer = bwn_dma_64_start_transfer;
3775                 dr->suspend = bwn_dma_64_suspend;
3776                 dr->resume = bwn_dma_64_resume;
3777                 dr->get_curslot = bwn_dma_64_get_curslot;
3778                 dr->set_curslot = bwn_dma_64_set_curslot;
3779         } else {
3780                 dr->getdesc = bwn_dma_32_getdesc;
3781                 dr->setdesc = bwn_dma_32_setdesc;
3782                 dr->start_transfer = bwn_dma_32_start_transfer;
3783                 dr->suspend = bwn_dma_32_suspend;
3784                 dr->resume = bwn_dma_32_resume;
3785                 dr->get_curslot = bwn_dma_32_get_curslot;
3786                 dr->set_curslot = bwn_dma_32_set_curslot;
3787         }
3788         if (for_tx) {
3789                 dr->dr_tx = 1;
3790                 dr->dr_curslot = -1;
3791         } else {
3792                 if (dr->dr_index == 0) {
3793                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3794                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3795                 } else
3796                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3797         }
3798
3799         error = bwn_dma_allocringmemory(dr);
3800         if (error)
3801                 goto fail2;
3802
3803         if (for_tx) {
3804                 /*
3805                  * Assumption: BWN_TXRING_SLOTS can be divided by
3806                  * BWN_TX_SLOTS_PER_FRAME
3807                  */
3808                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3809                     ("%s:%d: fail", __func__, __LINE__));
3810
3811                 dr->dr_txhdr_cache =
3812                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3813                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3814                 KASSERT(dr->dr_txhdr_cache != NULL,
3815                     ("%s:%d: fail", __func__, __LINE__));
3816
3817                 /*
3818                  * Create TX ring DMA stuffs
3819                  */
3820                 error = bus_dma_tag_create(dma->parent_dtag,
3821                                     BWN_ALIGN, 0,
3822                                     BUS_SPACE_MAXADDR,
3823                                     BUS_SPACE_MAXADDR,
3824                                     NULL, NULL,
3825                                     BWN_HDRSIZE(mac),
3826                                     1,
3827                                     BUS_SPACE_MAXSIZE_32BIT,
3828                                     0,
3829                                     NULL, NULL,
3830                                     &dr->dr_txring_dtag);
3831                 if (error) {
3832                         device_printf(sc->sc_dev,
3833                             "can't create TX ring DMA tag: TODO frees\n");
3834                         goto fail1;
3835                 }
3836
3837                 for (i = 0; i < dr->dr_numslots; i += 2) {
3838                         dr->getdesc(dr, i, &desc, &mt);
3839
3840                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3841                         mt->mt_m = NULL;
3842                         mt->mt_ni = NULL;
3843                         mt->mt_islast = 0;
3844                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3845                             &mt->mt_dmap);
3846                         if (error) {
3847                                 device_printf(sc->sc_dev,
3848                                      "can't create RX buf DMA map\n");
3849                                 goto fail1;
3850                         }
3851
3852                         dr->getdesc(dr, i + 1, &desc, &mt);
3853
3854                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3855                         mt->mt_m = NULL;
3856                         mt->mt_ni = NULL;
3857                         mt->mt_islast = 1;
3858                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3859                             &mt->mt_dmap);
3860                         if (error) {
3861                                 device_printf(sc->sc_dev,
3862                                      "can't create RX buf DMA map\n");
3863                                 goto fail1;
3864                         }
3865                 }
3866         } else {
3867                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3868                     &dr->dr_spare_dmap);
3869                 if (error) {
3870                         device_printf(sc->sc_dev,
3871                             "can't create RX buf DMA map\n");
3872                         goto out;               /* XXX wrong! */
3873                 }
3874
3875                 for (i = 0; i < dr->dr_numslots; i++) {
3876                         dr->getdesc(dr, i, &desc, &mt);
3877
3878                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3879                             &mt->mt_dmap);
3880                         if (error) {
3881                                 device_printf(sc->sc_dev,
3882                                     "can't create RX buf DMA map\n");
3883                                 goto out;       /* XXX wrong! */
3884                         }
3885                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3886                         if (error) {
3887                                 device_printf(sc->sc_dev,
3888                                     "failed to allocate RX buf\n");
3889                                 goto out;       /* XXX wrong! */
3890                         }
3891                 }
3892
3893                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3894                     BUS_DMASYNC_PREWRITE);
3895
3896                 dr->dr_usedslot = dr->dr_numslots;
3897         }
3898
3899       out:
3900         return (dr);
3901
3902 fail2:
3903         free(dr->dr_txhdr_cache, M_DEVBUF);
3904 fail1:
3905         free(dr->dr_meta, M_DEVBUF);
3906 fail0:
3907         free(dr, M_DEVBUF);
3908         return (NULL);
3909 }
3910
3911 static void
3912 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3913 {
3914
3915         if (dr == NULL)
3916                 return;
3917
3918         bwn_dma_free_descbufs(*dr);
3919         bwn_dma_free_ringmemory(*dr);
3920
3921         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3922         free((*dr)->dr_meta, M_DEVBUF);
3923         free(*dr, M_DEVBUF);
3924
3925         *dr = NULL;
3926 }
3927
3928 static void
3929 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3930     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3931 {
3932         struct bwn_dmadesc32 *desc;
3933
3934         *meta = &(dr->dr_meta[slot]);
3935         desc = dr->dr_ring_descbase;
3936         desc = &(desc[slot]);
3937
3938         *gdesc = (struct bwn_dmadesc_generic *)desc;
3939 }
3940
3941 static void
3942 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3943     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3944     int start, int end, int irq)
3945 {
3946         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3947         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3948         uint32_t addr, addrext, ctl;
3949         int slot;
3950
3951         slot = (int)(&(desc->dma.dma32) - descbase);
3952         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3953             ("%s:%d: fail", __func__, __LINE__));
3954
3955         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3956         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3957         addr |= siba_dma_translation(sc->sc_dev);
3958         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3959         if (slot == dr->dr_numslots - 1)
3960                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3961         if (start)
3962                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3963         if (end)
3964                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3965         if (irq)
3966                 ctl |= BWN_DMA32_DCTL_IRQ;
3967         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3968             & BWN_DMA32_DCTL_ADDREXT_MASK;
3969
3970         desc->dma.dma32.control = htole32(ctl);
3971         desc->dma.dma32.address = htole32(addr);
3972 }
3973
3974 static void
3975 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3976 {
3977
3978         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3979             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3980 }
3981
3982 static void
3983 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3984 {
3985
3986         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3987             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3988 }
3989
3990 static void
3991 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3992 {
3993
3994         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3995             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3996 }
3997
3998 static int
3999 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4000 {
4001         uint32_t val;
4002
4003         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4004         val &= BWN_DMA32_RXDPTR;
4005
4006         return (val / sizeof(struct bwn_dmadesc32));
4007 }
4008
4009 static void
4010 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4011 {
4012
4013         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4014             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4015 }
4016
4017 static void
4018 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4019     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4020 {
4021         struct bwn_dmadesc64 *desc;
4022
4023         *meta = &(dr->dr_meta[slot]);
4024         desc = dr->dr_ring_descbase;
4025         desc = &(desc[slot]);
4026
4027         *gdesc = (struct bwn_dmadesc_generic *)desc;
4028 }
4029
4030 static void
4031 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4032     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4033     int start, int end, int irq)
4034 {
4035         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4036         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4037         int slot;
4038         uint32_t ctl0 = 0, ctl1 = 0;
4039         uint32_t addrlo, addrhi;
4040         uint32_t addrext;
4041
4042         slot = (int)(&(desc->dma.dma64) - descbase);
4043         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4044             ("%s:%d: fail", __func__, __LINE__));
4045
4046         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4047         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4048         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4049             30;
4050         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4051         if (slot == dr->dr_numslots - 1)
4052                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4053         if (start)
4054                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4055         if (end)
4056                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4057         if (irq)
4058                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4059         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4060         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4061             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4062
4063         desc->dma.dma64.control0 = htole32(ctl0);
4064         desc->dma.dma64.control1 = htole32(ctl1);
4065         desc->dma.dma64.address_low = htole32(addrlo);
4066         desc->dma.dma64.address_high = htole32(addrhi);
4067 }
4068
4069 static void
4070 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4071 {
4072
4073         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4074             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4075 }
4076
4077 static void
4078 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4079 {
4080
4081         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4082             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4083 }
4084
4085 static void
4086 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4087 {
4088
4089         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4090             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4091 }
4092
4093 static int
4094 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4095 {
4096         uint32_t val;
4097
4098         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4099         val &= BWN_DMA64_RXSTATDPTR;
4100
4101         return (val / sizeof(struct bwn_dmadesc64));
4102 }
4103
4104 static void
4105 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4106 {
4107
4108         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4109             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4110 }
4111
4112 static int
4113 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4114 {
4115         struct bwn_mac *mac = dr->dr_mac;
4116         struct bwn_dma *dma = &mac->mac_method.dma;
4117         struct bwn_softc *sc = mac->mac_sc;
4118         int error;
4119
4120         error = bus_dma_tag_create(dma->parent_dtag,
4121                             BWN_ALIGN, 0,
4122                             BUS_SPACE_MAXADDR,
4123                             BUS_SPACE_MAXADDR,
4124                             NULL, NULL,
4125                             BWN_DMA_RINGMEMSIZE,
4126                             1,
4127                             BUS_SPACE_MAXSIZE_32BIT,
4128                             0,
4129                             NULL, NULL,
4130                             &dr->dr_ring_dtag);
4131         if (error) {
4132                 device_printf(sc->sc_dev,
4133                     "can't create TX ring DMA tag: TODO frees\n");
4134                 return (-1);
4135         }
4136
4137         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4138             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4139             &dr->dr_ring_dmap);
4140         if (error) {
4141                 device_printf(sc->sc_dev,
4142                     "can't allocate DMA mem: TODO frees\n");
4143                 return (-1);
4144         }
4145         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4146             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4147             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4148         if (error) {
4149                 device_printf(sc->sc_dev,
4150                     "can't load DMA mem: TODO free\n");
4151                 return (-1);
4152         }
4153
4154         return (0);
4155 }
4156
4157 static void
4158 bwn_dma_setup(struct bwn_dma_ring *dr)
4159 {
4160         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4161         uint64_t ring64;
4162         uint32_t addrext, ring32, value;
4163         uint32_t trans = siba_dma_translation(sc->sc_dev);
4164
4165         if (dr->dr_tx) {
4166                 dr->dr_curslot = -1;
4167
4168                 if (dr->dr_type == BWN_DMA_64BIT) {
4169                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4170                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4171                             >> 30;
4172                         value = BWN_DMA64_TXENABLE;
4173                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4174                             & BWN_DMA64_TXADDREXT_MASK;
4175                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4176                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4177                             (ring64 & 0xffffffff));
4178                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4179                             ((ring64 >> 32) &
4180                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4181                 } else {
4182                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4183                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4184                         value = BWN_DMA32_TXENABLE;
4185                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4186                             & BWN_DMA32_TXADDREXT_MASK;
4187                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4188                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4189                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4190                 }
4191                 return;
4192         }
4193
4194         /*
4195          * set for RX
4196          */
4197         dr->dr_usedslot = dr->dr_numslots;
4198
4199         if (dr->dr_type == BWN_DMA_64BIT) {
4200                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4201                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4202                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4203                 value |= BWN_DMA64_RXENABLE;
4204                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4205                     & BWN_DMA64_RXADDREXT_MASK;
4206                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4207                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4208                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4209                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4210                     | (trans << 1));
4211                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4212                     sizeof(struct bwn_dmadesc64));
4213         } else {
4214                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4215                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4216                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4217                 value |= BWN_DMA32_RXENABLE;
4218                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4219                     & BWN_DMA32_RXADDREXT_MASK;
4220                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4221                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4222                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4223                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4224                     sizeof(struct bwn_dmadesc32));
4225         }
4226 }
4227
4228 static void
4229 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4230 {
4231
4232         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4233         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4234             dr->dr_ring_dmap);
4235 }
4236
4237 static void
4238 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4239 {
4240
4241         if (dr->dr_tx) {
4242                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4243                 if (dr->dr_type == BWN_DMA_64BIT) {
4244                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4245                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4246                 } else
4247                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4248         } else {
4249                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4250                 if (dr->dr_type == BWN_DMA_64BIT) {
4251                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4252                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4253                 } else
4254                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4255         }
4256 }
4257
4258 static void
4259 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4260 {
4261         struct bwn_dmadesc_generic *desc;
4262         struct bwn_dmadesc_meta *meta;
4263         struct bwn_mac *mac = dr->dr_mac;
4264         struct bwn_dma *dma = &mac->mac_method.dma;
4265         struct bwn_softc *sc = mac->mac_sc;
4266         int i;
4267
4268         if (!dr->dr_usedslot)
4269                 return;
4270         for (i = 0; i < dr->dr_numslots; i++) {
4271                 dr->getdesc(dr, i, &desc, &meta);
4272
4273                 if (meta->mt_m == NULL) {
4274                         if (!dr->dr_tx)
4275                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4276                                     __func__);
4277                         continue;
4278                 }
4279                 if (dr->dr_tx) {
4280                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4281                                 bus_dmamap_unload(dr->dr_txring_dtag,
4282                                     meta->mt_dmap);
4283                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4284                                 bus_dmamap_unload(dma->txbuf_dtag,
4285                                     meta->mt_dmap);
4286                 } else
4287                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4288                 bwn_dma_free_descbuf(dr, meta);
4289         }
4290 }
4291
4292 static int
4293 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4294     int type)
4295 {
4296         struct bwn_softc *sc = mac->mac_sc;
4297         uint32_t value;
4298         int i;
4299         uint16_t offset;
4300
4301         for (i = 0; i < 10; i++) {
4302                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4303                     BWN_DMA32_TXSTATUS;
4304                 value = BWN_READ_4(mac, base + offset);
4305                 if (type == BWN_DMA_64BIT) {
4306                         value &= BWN_DMA64_TXSTAT;
4307                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4308                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4309                             value == BWN_DMA64_TXSTAT_STOPPED)
4310                                 break;
4311                 } else {
4312                         value &= BWN_DMA32_TXSTATE;
4313                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4314                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4315                             value == BWN_DMA32_TXSTAT_STOPPED)
4316                                 break;
4317                 }
4318                 DELAY(1000);
4319         }
4320         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4321         BWN_WRITE_4(mac, base + offset, 0);
4322         for (i = 0; i < 10; i++) {
4323                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4324                                                    BWN_DMA32_TXSTATUS;
4325                 value = BWN_READ_4(mac, base + offset);
4326                 if (type == BWN_DMA_64BIT) {
4327                         value &= BWN_DMA64_TXSTAT;
4328                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4329                                 i = -1;
4330                                 break;
4331                         }
4332                 } else {
4333                         value &= BWN_DMA32_TXSTATE;
4334                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4335                                 i = -1;
4336                                 break;
4337                         }
4338                 }
4339                 DELAY(1000);
4340         }
4341         if (i != -1) {
4342                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4343                 return (ENODEV);
4344         }
4345         DELAY(1000);
4346
4347         return (0);
4348 }
4349
4350 static int
4351 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4352     int type)
4353 {
4354         struct bwn_softc *sc = mac->mac_sc;
4355         uint32_t value;
4356         int i;
4357         uint16_t offset;
4358
4359         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4360         BWN_WRITE_4(mac, base + offset, 0);
4361         for (i = 0; i < 10; i++) {
4362                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4363                     BWN_DMA32_RXSTATUS;
4364                 value = BWN_READ_4(mac, base + offset);
4365                 if (type == BWN_DMA_64BIT) {
4366                         value &= BWN_DMA64_RXSTAT;
4367                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4368                                 i = -1;
4369                                 break;
4370                         }
4371                 } else {
4372                         value &= BWN_DMA32_RXSTATE;
4373                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4374                                 i = -1;
4375                                 break;
4376                         }
4377                 }
4378                 DELAY(1000);
4379         }
4380         if (i != -1) {
4381                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4382                 return (ENODEV);
4383         }
4384
4385         return (0);
4386 }
4387
4388 static void
4389 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4390     struct bwn_dmadesc_meta *meta)
4391 {
4392
4393         if (meta->mt_m != NULL) {
4394                 m_freem(meta->mt_m);
4395                 meta->mt_m = NULL;
4396         }
4397         if (meta->mt_ni != NULL) {
4398                 ieee80211_free_node(meta->mt_ni);
4399                 meta->mt_ni = NULL;
4400         }
4401 }
4402
4403 static void
4404 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4405 {
4406         struct bwn_rxhdr4 *rxhdr;
4407         unsigned char *frame;
4408
4409         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4410         rxhdr->frame_len = 0;
4411
4412         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4413             sizeof(struct bwn_plcp6) + 2,
4414             ("%s:%d: fail", __func__, __LINE__));
4415         frame = mtod(m, char *) + dr->dr_frameoffset;
4416         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4417 }
4418
4419 static uint8_t
4420 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4421 {
4422         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4423
4424         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4425             == 0xff);
4426 }
4427
4428 static void
4429 bwn_wme_init(struct bwn_mac *mac)
4430 {
4431
4432         bwn_wme_load(mac);
4433
4434         /* enable WME support. */
4435         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4436         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4437             BWN_IFSCTL_USE_EDCF);
4438 }
4439
4440 static void
4441 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4442 {
4443         struct bwn_softc *sc = mac->mac_sc;
4444         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4445         uint16_t delay; /* microsec */
4446
4447         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4448         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4449                 delay = 500;
4450         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4451                 delay = max(delay, (uint16_t)2400);
4452
4453         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4454 }
4455
4456 static void
4457 bwn_bt_enable(struct bwn_mac *mac)
4458 {
4459         struct bwn_softc *sc = mac->mac_sc;
4460         uint64_t hf;
4461
4462         if (bwn_bluetooth == 0)
4463                 return;
4464         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4465                 return;
4466         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4467                 return;
4468
4469         hf = bwn_hf_read(mac);
4470         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4471                 hf |= BWN_HF_BT_COEXISTALT;
4472         else
4473                 hf |= BWN_HF_BT_COEXIST;
4474         bwn_hf_write(mac, hf);
4475 }
4476
4477 static void
4478 bwn_set_macaddr(struct bwn_mac *mac)
4479 {
4480
4481         bwn_mac_write_bssid(mac);
4482         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4483 }
4484
4485 static void
4486 bwn_clear_keys(struct bwn_mac *mac)
4487 {
4488         int i;
4489
4490         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4491                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4492                     ("%s:%d: fail", __func__, __LINE__));
4493
4494                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4495                     NULL, BWN_SEC_KEYSIZE, NULL);
4496                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4497                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4498                             NULL, BWN_SEC_KEYSIZE, NULL);
4499                 }
4500                 mac->mac_key[i].keyconf = NULL;
4501         }
4502 }
4503
4504 static void
4505 bwn_crypt_init(struct bwn_mac *mac)
4506 {
4507         struct bwn_softc *sc = mac->mac_sc;
4508
4509         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4510         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4511             ("%s:%d: fail", __func__, __LINE__));
4512         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4513         mac->mac_ktp *= 2;
4514         if (siba_get_revid(sc->sc_dev) >= 5)
4515                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4516         bwn_clear_keys(mac);
4517 }
4518
4519 static void
4520 bwn_chip_exit(struct bwn_mac *mac)
4521 {
4522         struct bwn_softc *sc = mac->mac_sc;
4523
4524         bwn_phy_exit(mac);
4525         siba_gpio_set(sc->sc_dev, 0);
4526 }
4527
4528 static int
4529 bwn_fw_fillinfo(struct bwn_mac *mac)
4530 {
4531         int error;
4532
4533         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4534         if (error == 0)
4535                 return (0);
4536         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4537         if (error == 0)
4538                 return (0);
4539         return (error);
4540 }
4541
4542 static int
4543 bwn_gpio_init(struct bwn_mac *mac)
4544 {
4545         struct bwn_softc *sc = mac->mac_sc;
4546         uint32_t mask = 0x1f, set = 0xf, value;
4547
4548         BWN_WRITE_4(mac, BWN_MACCTL,
4549             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4550         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4551             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4552
4553         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4554                 mask |= 0x0060;
4555                 set |= 0x0060;
4556         }
4557         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4558                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4559                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4560                 mask |= 0x0200;
4561                 set |= 0x0200;
4562         }
4563         if (siba_get_revid(sc->sc_dev) >= 2)
4564                 mask |= 0x0010;
4565
4566         value = siba_gpio_get(sc->sc_dev);
4567         if (value == -1)
4568                 return (0);
4569         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4570
4571         return (0);
4572 }
4573
4574 static int
4575 bwn_fw_loadinitvals(struct bwn_mac *mac)
4576 {
4577 #define GETFWOFFSET(fwp, offset)                                \
4578         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4579         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4580         const struct bwn_fwhdr *hdr;
4581         struct bwn_fw *fw = &mac->mac_fw;
4582         int error;
4583
4584         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4585         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4586             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4587         if (error)
4588                 return (error);
4589         if (fw->initvals_band.fw) {
4590                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4591                 error = bwn_fwinitvals_write(mac,
4592                     GETFWOFFSET(fw->initvals_band, hdr_len),
4593                     be32toh(hdr->size),
4594                     fw->initvals_band.fw->datasize - hdr_len);
4595         }
4596         return (error);
4597 #undef GETFWOFFSET
4598 }
4599
4600 static int
4601 bwn_phy_init(struct bwn_mac *mac)
4602 {
4603         struct bwn_softc *sc = mac->mac_sc;
4604         int error;
4605
4606         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4607         mac->mac_phy.rf_onoff(mac, 1);
4608         error = mac->mac_phy.init(mac);
4609         if (error) {
4610                 device_printf(sc->sc_dev, "PHY init failed\n");
4611                 goto fail0;
4612         }
4613         error = bwn_switch_channel(mac,
4614             mac->mac_phy.get_default_chan(mac));
4615         if (error) {
4616                 device_printf(sc->sc_dev,
4617                     "failed to switch default channel\n");
4618                 goto fail1;
4619         }
4620         return (0);
4621 fail1:
4622         if (mac->mac_phy.exit)
4623                 mac->mac_phy.exit(mac);
4624 fail0:
4625         mac->mac_phy.rf_onoff(mac, 0);
4626
4627         return (error);
4628 }
4629
4630 static void
4631 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4632 {
4633         uint16_t ant;
4634         uint16_t tmp;
4635
4636         ant = bwn_ant2phy(antenna);
4637
4638         /* For ACK/CTS */
4639         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4640         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4641         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4642         /* For Probe Resposes */
4643         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4644         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4645         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4646 }
4647
4648 static void
4649 bwn_set_opmode(struct bwn_mac *mac)
4650 {
4651         struct bwn_softc *sc = mac->mac_sc;
4652         struct ifnet *ifp = sc->sc_ifp;
4653         struct ieee80211com *ic = ifp->if_l2com;
4654         uint32_t ctl;
4655         uint16_t cfp_pretbtt;
4656
4657         ctl = BWN_READ_4(mac, BWN_MACCTL);
4658         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4659             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4660             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4661         ctl |= BWN_MACCTL_STA;
4662
4663         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4664             ic->ic_opmode == IEEE80211_M_MBSS)
4665                 ctl |= BWN_MACCTL_HOSTAP;
4666         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4667                 ctl &= ~BWN_MACCTL_STA;
4668         ctl |= sc->sc_filters;
4669
4670         if (siba_get_revid(sc->sc_dev) <= 4)
4671                 ctl |= BWN_MACCTL_PROMISC;
4672
4673         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4674
4675         cfp_pretbtt = 2;
4676         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4677                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4678                     siba_get_chiprev(sc->sc_dev) == 3)
4679                         cfp_pretbtt = 100;
4680                 else
4681                         cfp_pretbtt = 50;
4682         }
4683         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4684 }
4685
4686 static int
4687 bwn_dma_gettype(struct bwn_mac *mac)
4688 {
4689         uint32_t tmp;
4690         uint16_t base;
4691
4692         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4693         if (tmp & SIBA_TGSHIGH_DMA64)
4694                 return (BWN_DMA_64BIT);
4695         base = bwn_dma_base(0, 0);
4696         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4697         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4698         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4699                 return (BWN_DMA_32BIT);
4700
4701         return (BWN_DMA_30BIT);
4702 }
4703
4704 static void
4705 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4706 {
4707         if (!error) {
4708                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4709                 *((bus_addr_t *)arg) = seg->ds_addr;
4710         }
4711 }
4712
4713 static void
4714 bwn_phy_g_init_sub(struct bwn_mac *mac)
4715 {
4716         struct bwn_phy *phy = &mac->mac_phy;
4717         struct bwn_phy_g *pg = &phy->phy_g;
4718         struct bwn_softc *sc = mac->mac_sc;
4719         uint16_t i, tmp;
4720
4721         if (phy->rev == 1)
4722                 bwn_phy_init_b5(mac);
4723         else
4724                 bwn_phy_init_b6(mac);
4725
4726         if (phy->rev >= 2 || phy->gmode)
4727                 bwn_phy_init_a(mac);
4728
4729         if (phy->rev >= 2) {
4730                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4731                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4732         }
4733         if (phy->rev == 2) {
4734                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4735                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4736         }
4737         if (phy->rev > 5) {
4738                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4739                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4740         }
4741         if (phy->gmode || phy->rev >= 2) {
4742                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4743                 tmp &= BWN_PHYVER_VERSION;
4744                 if (tmp == 3 || tmp == 5) {
4745                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4746                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4747                 }
4748                 if (tmp == 5) {
4749                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4750                             0x1f00);
4751                 }
4752         }
4753         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4754                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4755         if (phy->rf_rev == 8) {
4756                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4757                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4758         }
4759         if (BWN_HAS_LOOPBACK(phy))
4760                 bwn_loopback_calcgain(mac);
4761
4762         if (phy->rf_rev != 8) {
4763                 if (pg->pg_initval == 0xffff)
4764                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4765                 else
4766                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4767         }
4768         bwn_lo_g_init(mac);
4769         if (BWN_HAS_TXMAG(phy)) {
4770                 BWN_RF_WRITE(mac, 0x52,
4771                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4772                     | pg->pg_loctl.tx_bias |
4773                     pg->pg_loctl.tx_magn);
4774         } else {
4775                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4776         }
4777         if (phy->rev >= 6) {
4778                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4779                     (pg->pg_loctl.tx_bias << 12));
4780         }
4781         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4782                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4783         else
4784                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4785         if (phy->rev < 2)
4786                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4787         else
4788                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4789         if (phy->gmode || phy->rev >= 2) {
4790                 bwn_lo_g_adjust(mac);
4791                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4792         }
4793
4794         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4795                 for (i = 0; i < 64; i++) {
4796                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4797                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4798                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4799                             -32), 31));
4800                 }
4801                 bwn_nrssi_threshold(mac);
4802         } else if (phy->gmode || phy->rev >= 2) {
4803                 if (pg->pg_nrssi[0] == -1000) {
4804                         KASSERT(pg->pg_nrssi[1] == -1000,
4805                             ("%s:%d: fail", __func__, __LINE__));
4806                         bwn_nrssi_slope_11g(mac);
4807                 } else
4808                         bwn_nrssi_threshold(mac);
4809         }
4810         if (phy->rf_rev == 8)
4811                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4812         bwn_phy_hwpctl_init(mac);
4813         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4814              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4815                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4816                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4817         }
4818 }
4819
4820 static uint8_t
4821 bwn_has_hwpctl(struct bwn_mac *mac)
4822 {
4823
4824         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4825                 return (0);
4826         return (mac->mac_phy.use_hwpctl(mac));
4827 }
4828
4829 static void
4830 bwn_phy_init_b5(struct bwn_mac *mac)
4831 {
4832         struct bwn_phy *phy = &mac->mac_phy;
4833         struct bwn_phy_g *pg = &phy->phy_g;
4834         struct bwn_softc *sc = mac->mac_sc;
4835         uint16_t offset, value;
4836         uint8_t old_channel;
4837
4838         if (phy->analog == 1)
4839                 BWN_RF_SET(mac, 0x007a, 0x0050);
4840         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4841             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4842                 value = 0x2120;
4843                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4844                         BWN_PHY_WRITE(mac, offset, value);
4845                         value += 0x202;
4846                 }
4847         }
4848         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4849         if (phy->rf_ver == 0x2050)
4850                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4851
4852         if (phy->gmode || phy->rev >= 2) {
4853                 if (phy->rf_ver == 0x2050) {
4854                         BWN_RF_SET(mac, 0x007a, 0x0020);
4855                         BWN_RF_SET(mac, 0x0051, 0x0004);
4856                 }
4857                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4858
4859                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4860                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4861
4862                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4863
4864                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4865                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4866                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4867         }
4868
4869         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4870                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4871
4872         if (phy->analog == 1) {
4873                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4874                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4875                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4876                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4877                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4878         } else
4879                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4880         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4881         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4882
4883         if (phy->analog == 1)
4884                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4885         else
4886                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4887
4888         if (phy->analog == 0)
4889                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4890
4891         old_channel = phy->chan;
4892         bwn_phy_g_switch_chan(mac, 7, 0);
4893
4894         if (phy->rf_ver != 0x2050) {
4895                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4896                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4897         }
4898
4899         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4900         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4901
4902         if (phy->rf_ver == 0x2050) {
4903                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4904                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4905         }
4906
4907         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4908         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4909         BWN_RF_SET(mac, 0x007a, 0x0007);
4910
4911         bwn_phy_g_switch_chan(mac, old_channel, 0);
4912         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4913         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4914         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4915
4916         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4917             pg->pg_txctl);
4918
4919         if (phy->rf_ver == 0x2050)
4920                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4921
4922         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4923 }
4924
4925 static void
4926 bwn_loopback_calcgain(struct bwn_mac *mac)
4927 {
4928         struct bwn_phy *phy = &mac->mac_phy;
4929         struct bwn_phy_g *pg = &phy->phy_g;
4930         struct bwn_softc *sc = mac->mac_sc;
4931         uint16_t backup_phy[16] = { 0 };
4932         uint16_t backup_radio[3];
4933         uint16_t backup_bband;
4934         uint16_t i, j, loop_i_max;
4935         uint16_t trsw_rx;
4936         uint16_t loop1_outer_done, loop1_inner_done;
4937
4938         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4939         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4940         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4941         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4942         if (phy->rev != 1) {
4943                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4944                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4945         }
4946         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4947         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4948         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4949         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4950         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4951         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4952         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4953         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4954         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4955         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4956         backup_bband = pg->pg_bbatt.att;
4957         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4958         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4959         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4960
4961         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4962         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4963         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4964         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4965         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4966         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4967         if (phy->rev != 1) {
4968                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4969                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4970                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4971                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4972         }
4973         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4974         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4975         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4976         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4977
4978         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4979         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4980         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4981
4982         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4983         if (phy->rev != 1) {
4984                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4985                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4986         }
4987         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4988
4989         if (phy->rf_rev == 8)
4990                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4991         else {
4992                 BWN_RF_WRITE(mac, 0x52, 0);
4993                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4994         }
4995         bwn_phy_g_set_bbatt(mac, 11);
4996
4997         if (phy->rev >= 3)
4998                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4999         else
5000                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5001         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5002
5003         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5004         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5005
5006         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5007         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5008
5009         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5010                 if (phy->rev >= 7) {
5011                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5012                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5013                 }
5014         }
5015         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5016
5017         j = 0;
5018         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5019         for (i = 0; i < loop_i_max; i++) {
5020                 for (j = 0; j < 16; j++) {
5021                         BWN_RF_WRITE(mac, 0x43, i);
5022                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5023                             (j << 8));
5024                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5025                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5026                         DELAY(20);
5027                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5028                                 goto done0;
5029                 }
5030         }
5031 done0:
5032         loop1_outer_done = i;
5033         loop1_inner_done = j;
5034         if (j >= 8) {
5035                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5036                 trsw_rx = 0x1b;
5037                 for (j = j - 8; j < 16; j++) {
5038                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5039                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5040                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5041                         DELAY(20);
5042                         trsw_rx -= 3;
5043                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5044                                 goto done1;
5045                 }
5046         } else
5047                 trsw_rx = 0x18;
5048 done1:
5049
5050         if (phy->rev != 1) {
5051                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5052                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5053         }
5054         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5055         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5056         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5057         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5058         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5059         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5060         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5061         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5062         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5063
5064         bwn_phy_g_set_bbatt(mac, backup_bband);
5065
5066         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5067         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5068         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5069
5070         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5071         DELAY(10);
5072         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5073         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5074         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5075         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5076
5077         pg->pg_max_lb_gain =
5078             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5079         pg->pg_trsw_rx_gain = trsw_rx * 2;
5080 }
5081
5082 static uint16_t
5083 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5084 {
5085         struct bwn_phy *phy = &mac->mac_phy;
5086         uint32_t tmp1 = 0, tmp2 = 0;
5087         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5088             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5089             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5090         static const uint8_t rcc_table[] = {
5091                 0x02, 0x03, 0x01, 0x0f,
5092                 0x06, 0x07, 0x05, 0x0f,
5093                 0x0a, 0x0b, 0x09, 0x0f,
5094                 0x0e, 0x0f, 0x0d, 0x0f,
5095         };
5096
5097         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5098             rfoverval = rfover = cck3 = 0;
5099         radio0 = BWN_RF_READ(mac, 0x43);
5100         radio1 = BWN_RF_READ(mac, 0x51);
5101         radio2 = BWN_RF_READ(mac, 0x52);
5102         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5103         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5104         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5105         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5106
5107         if (phy->type == BWN_PHYTYPE_B) {
5108                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5109                 reg0 = BWN_READ_2(mac, 0x3ec);
5110
5111                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5112                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5113         } else if (phy->gmode || phy->rev >= 2) {
5114                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5115                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5116                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5117                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5118                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5119                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5120
5121                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5122                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5123                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5124                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5125                 if (BWN_HAS_LOOPBACK(phy)) {
5126                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5127                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5128                         if (phy->rev >= 3)
5129                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5130                         else
5131                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5132                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5133                 }
5134
5135                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5136                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5137                         BWN_LPD(0, 1, 1)));
5138                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5139                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5140         }
5141         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5142
5143         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5144         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5145         reg1 = BWN_READ_2(mac, 0x3e6);
5146         reg2 = BWN_READ_2(mac, 0x3f4);
5147
5148         if (phy->analog == 0)
5149                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5150         else {
5151                 if (phy->analog >= 2)
5152                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5153                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5154                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5155         }
5156
5157         reg = BWN_RF_READ(mac, 0x60);
5158         index = (reg & 0x001e) >> 1;
5159         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5160
5161         if (phy->type == BWN_PHYTYPE_B)
5162                 BWN_RF_WRITE(mac, 0x78, 0x26);
5163         if (phy->gmode || phy->rev >= 2) {
5164                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5165                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5166                         BWN_LPD(0, 1, 1)));
5167         }
5168         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5169         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5170         if (phy->gmode || phy->rev >= 2) {
5171                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5172                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5173                         BWN_LPD(0, 0, 1)));
5174         }
5175         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5176         BWN_RF_SET(mac, 0x51, 0x0004);
5177         if (phy->rf_rev == 8)
5178                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5179         else {
5180                 BWN_RF_WRITE(mac, 0x52, 0);
5181                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5182         }
5183         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5184
5185         for (i = 0; i < 16; i++) {
5186                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5187                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5188                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5189                 if (phy->gmode || phy->rev >= 2) {
5190                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5191                             bwn_rf_2050_rfoverval(mac,
5192                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5193                 }
5194                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5195                 DELAY(10);
5196                 if (phy->gmode || phy->rev >= 2) {
5197                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5198                             bwn_rf_2050_rfoverval(mac,
5199                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5200                 }
5201                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5202                 DELAY(10);
5203                 if (phy->gmode || phy->rev >= 2) {
5204                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5205                             bwn_rf_2050_rfoverval(mac,
5206                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5207                 }
5208                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5209                 DELAY(20);
5210                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5211                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5212                 if (phy->gmode || phy->rev >= 2) {
5213                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5214                             bwn_rf_2050_rfoverval(mac,
5215                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5216                 }
5217                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5218         }
5219         DELAY(10);
5220
5221         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5222         tmp1++;
5223         tmp1 >>= 9;
5224
5225         for (i = 0; i < 16; i++) {
5226                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5227                 BWN_RF_WRITE(mac, 0x78, radio78);
5228                 DELAY(10);
5229                 for (j = 0; j < 16; j++) {
5230                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5231                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5232                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5233                         if (phy->gmode || phy->rev >= 2) {
5234                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5235                                     bwn_rf_2050_rfoverval(mac,
5236                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5237                         }
5238                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5239                         DELAY(10);
5240                         if (phy->gmode || phy->rev >= 2) {
5241                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5242                                     bwn_rf_2050_rfoverval(mac,
5243                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5244                         }
5245                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5246                         DELAY(10);
5247                         if (phy->gmode || phy->rev >= 2) {
5248                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5249                                     bwn_rf_2050_rfoverval(mac,
5250                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5251                         }
5252                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5253                         DELAY(10);
5254                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5255                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5256                         if (phy->gmode || phy->rev >= 2) {
5257                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5258                                     bwn_rf_2050_rfoverval(mac,
5259                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5260                         }
5261                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5262                 }
5263                 tmp2++;
5264                 tmp2 >>= 8;
5265                 if (tmp1 < tmp2)
5266                         break;
5267         }
5268
5269         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5270         BWN_RF_WRITE(mac, 0x51, radio1);
5271         BWN_RF_WRITE(mac, 0x52, radio2);
5272         BWN_RF_WRITE(mac, 0x43, radio0);
5273         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5274         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5275         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5276         BWN_WRITE_2(mac, 0x3e6, reg1);
5277         if (phy->analog != 0)
5278                 BWN_WRITE_2(mac, 0x3f4, reg2);
5279         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5280         bwn_spu_workaround(mac, phy->chan);
5281         if (phy->type == BWN_PHYTYPE_B) {
5282                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5283                 BWN_WRITE_2(mac, 0x3ec, reg0);
5284         } else if (phy->gmode) {
5285                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5286                             BWN_READ_2(mac, BWN_PHY_RADIO)
5287                             & 0x7fff);
5288                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5289                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5290                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5291                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5292                               analogoverval);
5293                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5294                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5295                 if (BWN_HAS_LOOPBACK(phy)) {
5296                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5297                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5298                 }
5299         }
5300
5301         return ((i > 15) ? radio78 : rcc);
5302 }
5303
5304 static void
5305 bwn_phy_init_b6(struct bwn_mac *mac)
5306 {
5307         struct bwn_phy *phy = &mac->mac_phy;
5308         struct bwn_phy_g *pg = &phy->phy_g;
5309         struct bwn_softc *sc = mac->mac_sc;
5310         uint16_t offset, val;
5311         uint8_t old_channel;
5312
5313         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5314             ("%s:%d: fail", __func__, __LINE__));
5315
5316         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5317         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5318         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5319                 BWN_RF_WRITE(mac, 0x51, 0x37);
5320                 BWN_RF_WRITE(mac, 0x52, 0x70);
5321                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5322                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5323                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5324                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5325                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5326                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5327                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5328                 bwn_hf_write(mac,
5329                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5330         }
5331         if (phy->rf_rev == 8) {
5332                 BWN_RF_WRITE(mac, 0x51, 0);
5333                 BWN_RF_WRITE(mac, 0x52, 0x40);
5334                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5335                 BWN_RF_WRITE(mac, 0x54, 0x98);
5336                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5337                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5338                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5339                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5340                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5341                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5342                 } else {
5343                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5344                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5345                 }
5346                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5347                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5348                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5349                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5350         }
5351         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5352                 BWN_PHY_WRITE(mac, offset, val);
5353                 val -= 0x0202;
5354         }
5355         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5356                 BWN_PHY_WRITE(mac, offset, val);
5357                 val -= 0x0202;
5358         }
5359         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5360                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5361                 val += 0x0202;
5362         }
5363         if (phy->type == BWN_PHYTYPE_G) {
5364                 BWN_RF_SET(mac, 0x007a, 0x0020);
5365                 BWN_RF_SET(mac, 0x0051, 0x0004);
5366                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5367                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5368                 BWN_PHY_WRITE(mac, 0x5b, 0);
5369                 BWN_PHY_WRITE(mac, 0x5c, 0);
5370         }
5371
5372         old_channel = phy->chan;
5373         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5374
5375         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5376         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5377         DELAY(40);
5378         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5379                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5380                 BWN_RF_WRITE(mac, 0x50, 0x20);
5381         }
5382         if (phy->rf_rev <= 2) {
5383                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5384                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5385                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5386                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5387         }
5388         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5389
5390         bwn_phy_g_switch_chan(mac, old_channel, 0);
5391
5392         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5393         if (phy->rf_rev >= 6)
5394                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5395         else
5396                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5397         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5398         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5399             pg->pg_txctl);
5400         if (phy->rf_rev <= 5)
5401                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5402         if (phy->rf_rev <= 2)
5403                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5404
5405         if (phy->analog == 4) {
5406                 BWN_WRITE_2(mac, 0x3e4, 9);
5407                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5408         } else
5409                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5410         if (phy->type == BWN_PHYTYPE_B)
5411                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5412         else if (phy->type == BWN_PHYTYPE_G)
5413                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5414 }
5415
5416 static void
5417 bwn_phy_init_a(struct bwn_mac *mac)
5418 {
5419         struct bwn_phy *phy = &mac->mac_phy;
5420         struct bwn_softc *sc = mac->mac_sc;
5421
5422         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5423             ("%s:%d: fail", __func__, __LINE__));
5424
5425         if (phy->rev >= 6) {
5426                 if (phy->type == BWN_PHYTYPE_A)
5427                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5428                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5429                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5430                 else
5431                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5432         }
5433
5434         bwn_wa_init(mac);
5435
5436         if (phy->type == BWN_PHYTYPE_G &&
5437             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5438                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5439 }
5440
5441 static void
5442 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5443 {
5444         int i;
5445
5446         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5447                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5448 }
5449
5450 static void
5451 bwn_wa_agc(struct bwn_mac *mac)
5452 {
5453         struct bwn_phy *phy = &mac->mac_phy;
5454
5455         if (phy->rev == 1) {
5456                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5457                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5458                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5460                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5461                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5462                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5463                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5464                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5465         } else {
5466                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5467                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5468                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5469                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5470         }
5471
5472         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5473             0x5700);
5474         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5475         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5476         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5477         BWN_RF_SET(mac, 0x7a, 0x0008);
5478         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5479         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5480         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5481         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5482         if (phy->rev == 1)
5483                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5484         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5485         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5486         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5487         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5488         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5491         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5492         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5493         if (phy->rev == 1) {
5494                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5495                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5496         } else {
5497                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5498                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5499                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5500                 if (phy->rev >= 6) {
5501                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5502                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5503                             (uint16_t)~0xf000, 0x3000);
5504                 }
5505         }
5506         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5507         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5508         if (phy->rev == 1) {
5509                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5510                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5511                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5512                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5513                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5514                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5515                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5516                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5517         } else {
5518                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5519                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5520                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5521                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5522         }
5523         if (phy->rev >= 6) {
5524                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5525                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5526         }
5527         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5528 }
5529
5530 static void
5531 bwn_wa_grev1(struct bwn_mac *mac)
5532 {
5533         struct bwn_phy *phy = &mac->mac_phy;
5534         int i;
5535         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5536         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5537         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5538
5539         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5540
5541         /* init CRSTHRES and ANTDWELL */
5542         if (phy->rev == 1) {
5543                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5544         } else if (phy->rev == 2) {
5545                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5546                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5547                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5548         } else {
5549                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5550                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5551                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5552                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5553         }
5554         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5555         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5556         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5557
5558         /* XXX support PHY-A??? */
5559         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5560                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5561                     bwn_tab_finefreqg[i]);
5562
5563         /* XXX support PHY-A??? */
5564         if (phy->rev == 1)
5565                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5566                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5567                             bwn_tab_noise_g1[i]);
5568         else
5569                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5570                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5571                             bwn_tab_noise_g2[i]);
5572
5573
5574         for (i = 0; i < N(bwn_tab_rotor); i++)
5575                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5576                     bwn_tab_rotor[i]);
5577
5578         /* XXX support PHY-A??? */
5579         if (phy->rev >= 6) {
5580                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5581                     BWN_PHY_ENCORE_EN)
5582                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5583                 else
5584                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5585         } else
5586                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5587
5588         for (i = 0; i < N(bwn_tab_retard); i++)
5589                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5590                     bwn_tab_retard[i]);
5591
5592         if (phy->rev == 1) {
5593                 for (i = 0; i < 16; i++)
5594                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5595                             i, 0x0020);
5596         } else {
5597                 for (i = 0; i < 32; i++)
5598                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5599         }
5600
5601         bwn_wa_agc(mac);
5602 }
5603
5604 static void
5605 bwn_wa_grev26789(struct bwn_mac *mac)
5606 {
5607         struct bwn_phy *phy = &mac->mac_phy;
5608         int i;
5609         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5610         uint16_t ofdmrev;
5611
5612         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5613
5614         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5615
5616         /* init CRSTHRES and ANTDWELL */
5617         if (phy->rev == 1)
5618                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5619         else if (phy->rev == 2) {
5620                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5621                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5622                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5623         } else {
5624                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5625                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5626                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5627                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5628         }
5629
5630         for (i = 0; i < 64; i++)
5631                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5632
5633         /* XXX support PHY-A??? */
5634         if (phy->rev == 1)
5635                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5636                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5637                             bwn_tab_noise_g1[i]);
5638         else
5639                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5640                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5641                             bwn_tab_noise_g2[i]);
5642
5643         /* XXX support PHY-A??? */
5644         if (phy->rev >= 6) {
5645                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5646                     BWN_PHY_ENCORE_EN)
5647                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5648                 else
5649                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5650         } else
5651                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5652
5653         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5654                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5655                     bwn_tab_sigmasqr2[i]);
5656
5657         if (phy->rev == 1) {
5658                 for (i = 0; i < 16; i++)
5659                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5660                             0x0020);
5661         } else {
5662                 for (i = 0; i < 32; i++)
5663                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5664         }
5665
5666         bwn_wa_agc(mac);
5667
5668         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5669         if (ofdmrev > 2) {
5670                 if (phy->type == BWN_PHYTYPE_A)
5671                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5672                 else
5673                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5674         } else {
5675                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5676                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5677                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5678         }
5679
5680         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5681         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5682 }
5683
5684 static void
5685 bwn_wa_init(struct bwn_mac *mac)
5686 {
5687         struct bwn_phy *phy = &mac->mac_phy;
5688         struct bwn_softc *sc = mac->mac_sc;
5689
5690         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5691
5692         switch (phy->rev) {
5693         case 1:
5694                 bwn_wa_grev1(mac);
5695                 break;
5696         case 2:
5697         case 6:
5698         case 7:
5699         case 8:
5700         case 9:
5701                 bwn_wa_grev26789(mac);
5702                 break;
5703         default:
5704                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5705         }
5706
5707         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5708             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5709             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5710                 if (phy->rev < 2) {
5711                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5712                             0x0002);
5713                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5714                             0x0001);
5715                 } else {
5716                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5717                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5718                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5719                              BWN_BFL_EXTLNA) &&
5720                             (phy->rev >= 7)) {
5721                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5722                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5723                                     0x0020, 0x0001);
5724                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5725                                     0x0021, 0x0001);
5726                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5727                                     0x0022, 0x0001);
5728                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5729                                     0x0023, 0x0000);
5730                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5731                                     0x0000, 0x0000);
5732                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5733                                     0x0003, 0x0002);
5734                         }
5735                 }
5736         }
5737         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5738                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5739                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5740         }
5741
5742         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5743         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5744 }
5745
5746 static void
5747 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5748     uint16_t value)
5749 {
5750         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5751         uint16_t addr;
5752
5753         addr = table + offset;
5754         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5755             (addr - 1 != pg->pg_ofdmtab_addr)) {
5756                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5757                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5758         }
5759         pg->pg_ofdmtab_addr = addr;
5760         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5761 }
5762
5763 static void
5764 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5765     uint32_t value)
5766 {
5767         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5768         uint16_t addr;
5769
5770         addr = table + offset;
5771         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5772             (addr - 1 != pg->pg_ofdmtab_addr)) {
5773                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5774                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5775         }
5776         pg->pg_ofdmtab_addr = addr;
5777
5778         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5779         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5780 }
5781
5782 static void
5783 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5784     uint16_t value)
5785 {
5786
5787         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5788         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5789 }
5790
5791 static void
5792 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5793 {
5794         struct bwn_phy *phy = &mac->mac_phy;
5795         struct bwn_softc *sc = mac->mac_sc;
5796         unsigned int i, max_loop;
5797         uint16_t value;
5798         uint32_t buffer[5] = {
5799                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5800         };
5801
5802         if (ofdm) {
5803                 max_loop = 0x1e;
5804                 buffer[0] = 0x000201cc;
5805         } else {
5806                 max_loop = 0xfa;
5807                 buffer[0] = 0x000b846e;
5808         }
5809
5810         BWN_ASSERT_LOCKED(mac->mac_sc);
5811
5812         for (i = 0; i < 5; i++)
5813                 bwn_ram_write(mac, i * 4, buffer[i]);
5814
5815         BWN_WRITE_2(mac, 0x0568, 0x0000);
5816         BWN_WRITE_2(mac, 0x07c0,
5817             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5818         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5819         BWN_WRITE_2(mac, 0x050c, value);
5820         if (phy->type == BWN_PHYTYPE_LP)
5821                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5822         BWN_WRITE_2(mac, 0x0508, 0x0000);
5823         BWN_WRITE_2(mac, 0x050a, 0x0000);
5824         BWN_WRITE_2(mac, 0x054c, 0x0000);
5825         BWN_WRITE_2(mac, 0x056a, 0x0014);
5826         BWN_WRITE_2(mac, 0x0568, 0x0826);
5827         BWN_WRITE_2(mac, 0x0500, 0x0000);
5828         if (phy->type == BWN_PHYTYPE_LP)
5829                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5830         else
5831                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5832
5833         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5834                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5835         for (i = 0x00; i < max_loop; i++) {
5836                 value = BWN_READ_2(mac, 0x050e);
5837                 if (value & 0x0080)
5838                         break;
5839                 DELAY(10);
5840         }
5841         for (i = 0x00; i < 0x0a; i++) {
5842                 value = BWN_READ_2(mac, 0x050e);
5843                 if (value & 0x0400)
5844                         break;
5845                 DELAY(10);
5846         }
5847         for (i = 0x00; i < 0x19; i++) {
5848                 value = BWN_READ_2(mac, 0x0690);
5849                 if (!(value & 0x0100))
5850                         break;
5851                 DELAY(10);
5852         }
5853         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5854                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5855 }
5856
5857 static void
5858 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5859 {
5860         uint32_t macctl;
5861
5862         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5863
5864         macctl = BWN_READ_4(mac, BWN_MACCTL);
5865         if (macctl & BWN_MACCTL_BIGENDIAN)
5866                 printf("TODO: need swap\n");
5867
5868         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5869         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5870         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5871 }
5872
5873 static void
5874 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5875 {
5876         uint16_t value;
5877
5878         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5879             ("%s:%d: fail", __func__, __LINE__));
5880
5881         value = (uint8_t) (ctl->q);
5882         value |= ((uint8_t) (ctl->i)) << 8;
5883         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5884 }
5885
5886 static uint16_t
5887 bwn_lo_calcfeed(struct bwn_mac *mac,
5888     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5889 {
5890         struct bwn_phy *phy = &mac->mac_phy;
5891         struct bwn_softc *sc = mac->mac_sc;
5892         uint16_t rfover;
5893         uint16_t feedthrough;
5894
5895         if (phy->gmode) {
5896                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5897                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5898
5899                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5900                     ("%s:%d: fail", __func__, __LINE__));
5901                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5902                     ("%s:%d: fail", __func__, __LINE__));
5903
5904                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5905
5906                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5907                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5908                     phy->rev > 6)
5909                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5910
5911                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5912                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5913                 DELAY(10);
5914                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5915                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5916                 DELAY(10);
5917                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5918                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5919                 DELAY(10);
5920                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5921         } else {
5922                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5923                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5924                 DELAY(10);
5925                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5926                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5927                 DELAY(10);
5928                 pga |= BWN_PHY_PGACTL_LPF;
5929                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5930         }
5931         DELAY(21);
5932         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5933
5934         return (feedthrough);
5935 }
5936
5937 static uint16_t
5938 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5939     uint16_t *value, uint16_t *pad_mix_gain)
5940 {
5941         struct bwn_phy *phy = &mac->mac_phy;
5942         uint16_t reg, v, padmix;
5943
5944         if (phy->type == BWN_PHYTYPE_B) {
5945                 v = 0x30;
5946                 if (phy->rf_rev <= 5) {
5947                         reg = 0x43;
5948                         padmix = 0;
5949                 } else {
5950                         reg = 0x52;
5951                         padmix = 5;
5952                 }
5953         } else {
5954                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5955                         reg = 0x43;
5956                         v = 0x10;
5957                         padmix = 2;
5958                 } else {
5959                         reg = 0x52;
5960                         v = 0x30;
5961                         padmix = 5;
5962                 }
5963         }
5964         if (value)
5965                 *value = v;
5966         if (pad_mix_gain)
5967                 *pad_mix_gain = padmix;
5968
5969         return (reg);
5970 }
5971
5972 static void
5973 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5974 {
5975         struct bwn_phy *phy = &mac->mac_phy;
5976         struct bwn_phy_g *pg = &phy->phy_g;
5977         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5978         uint16_t reg, mask;
5979         uint16_t trsw_rx, pga;
5980         uint16_t rf_pctl_reg;
5981
5982         static const uint8_t tx_bias_values[] = {
5983                 0x09, 0x08, 0x0a, 0x01, 0x00,
5984                 0x02, 0x05, 0x04, 0x06,
5985         };
5986         static const uint8_t tx_magn_values[] = {
5987                 0x70, 0x40,
5988         };
5989
5990         if (!BWN_HAS_LOOPBACK(phy)) {
5991                 rf_pctl_reg = 6;
5992                 trsw_rx = 2;
5993                 pga = 0;
5994         } else {
5995                 int lb_gain;
5996
5997                 trsw_rx = 0;
5998                 lb_gain = pg->pg_max_lb_gain / 2;
5999                 if (lb_gain > 10) {
6000                         rf_pctl_reg = 0;
6001                         pga = abs(10 - lb_gain) / 6;
6002                         pga = MIN(MAX(pga, 0), 15);
6003                 } else {
6004                         int cmp_val;
6005                         int tmp;
6006
6007                         pga = 0;
6008                         cmp_val = 0x24;
6009                         if ((phy->rev >= 2) &&
6010                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6011                                 cmp_val = 0x3c;
6012                         tmp = lb_gain;
6013                         if ((10 - lb_gain) < cmp_val)
6014                                 tmp = (10 - lb_gain);
6015                         if (tmp < 0)
6016                                 tmp += 6;
6017                         else
6018                                 tmp += 3;
6019                         cmp_val /= 4;
6020                         tmp /= 4;
6021                         if (tmp >= cmp_val)
6022                                 rf_pctl_reg = cmp_val;
6023                         else
6024                                 rf_pctl_reg = tmp;
6025                 }
6026         }
6027         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6028         bwn_phy_g_set_bbatt(mac, 2);
6029
6030         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6031         mask = ~mask;
6032         BWN_RF_MASK(mac, reg, mask);
6033
6034         if (BWN_HAS_TXMAG(phy)) {
6035                 int i, j;
6036                 int feedthrough;
6037                 int min_feedth = 0xffff;
6038                 uint8_t tx_magn, tx_bias;
6039
6040                 for (i = 0; i < N(tx_magn_values); i++) {
6041                         tx_magn = tx_magn_values[i];
6042                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6043                         for (j = 0; j < N(tx_bias_values); j++) {
6044                                 tx_bias = tx_bias_values[j];
6045                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6046                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6047                                     trsw_rx);
6048                                 if (feedthrough < min_feedth) {
6049                                         lo->tx_bias = tx_bias;
6050                                         lo->tx_magn = tx_magn;
6051                                         min_feedth = feedthrough;
6052                                 }
6053                                 if (lo->tx_bias == 0)
6054                                         break;
6055                         }
6056                         BWN_RF_WRITE(mac, 0x52,
6057                                           (BWN_RF_READ(mac, 0x52)
6058                                            & 0xff00) | lo->tx_bias | lo->
6059                                           tx_magn);
6060                 }
6061         } else {
6062                 lo->tx_magn = 0;
6063                 lo->tx_bias = 0;
6064                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6065         }
6066
6067         BWN_GETTIME(lo->txctl_measured_time);
6068 }
6069
6070 static void
6071 bwn_lo_get_powervector(struct bwn_mac *mac)
6072 {
6073         struct bwn_phy *phy = &mac->mac_phy;
6074         struct bwn_phy_g *pg = &phy->phy_g;
6075         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6076         int i;
6077         uint64_t tmp;
6078         uint64_t power_vector = 0;
6079
6080         for (i = 0; i < 8; i += 2) {
6081                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6082                 power_vector |= (tmp << (i * 8));
6083                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6084         }
6085         if (power_vector)
6086                 lo->power_vector = power_vector;
6087
6088         BWN_GETTIME(lo->pwr_vec_read_time);
6089 }
6090
6091 static void
6092 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6093     int use_trsw_rx)
6094 {
6095         struct bwn_phy *phy = &mac->mac_phy;
6096         struct bwn_phy_g *pg = &phy->phy_g;
6097         uint16_t tmp;
6098
6099         if (max_rx_gain < 0)
6100                 max_rx_gain = 0;
6101
6102         if (BWN_HAS_LOOPBACK(phy)) {
6103                 int trsw_rx = 0;
6104                 int trsw_rx_gain;
6105
6106                 if (use_trsw_rx) {
6107                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6108                         if (max_rx_gain >= trsw_rx_gain) {
6109                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6110                                 trsw_rx = 0x20;
6111                         }
6112                 } else
6113                         trsw_rx_gain = max_rx_gain;
6114                 if (trsw_rx_gain < 9) {
6115                         pg->pg_lna_lod_gain = 0;
6116                 } else {
6117                         pg->pg_lna_lod_gain = 1;
6118                         trsw_rx_gain -= 8;
6119                 }
6120                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6121                 pg->pg_pga_gain = trsw_rx_gain / 3;
6122                 if (pg->pg_pga_gain >= 5) {
6123                         pg->pg_pga_gain -= 5;
6124                         pg->pg_lna_gain = 2;
6125                 } else
6126                         pg->pg_lna_gain = 0;
6127         } else {
6128                 pg->pg_lna_gain = 0;
6129                 pg->pg_trsw_rx_gain = 0x20;
6130                 if (max_rx_gain >= 0x14) {
6131                         pg->pg_lna_lod_gain = 1;
6132                         pg->pg_pga_gain = 2;
6133                 } else if (max_rx_gain >= 0x12) {
6134                         pg->pg_lna_lod_gain = 1;
6135                         pg->pg_pga_gain = 1;
6136                 } else if (max_rx_gain >= 0xf) {
6137                         pg->pg_lna_lod_gain = 1;
6138                         pg->pg_pga_gain = 0;
6139                 } else {
6140                         pg->pg_lna_lod_gain = 0;
6141                         pg->pg_pga_gain = 0;
6142                 }
6143         }
6144
6145         tmp = BWN_RF_READ(mac, 0x7a);
6146         if (pg->pg_lna_lod_gain == 0)
6147                 tmp &= ~0x0008;
6148         else
6149                 tmp |= 0x0008;
6150         BWN_RF_WRITE(mac, 0x7a, tmp);
6151 }
6152
6153 static void
6154 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6155 {
6156         struct bwn_phy *phy = &mac->mac_phy;
6157         struct bwn_phy_g *pg = &phy->phy_g;
6158         struct bwn_softc *sc = mac->mac_sc;
6159         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6160         struct timespec ts;
6161         uint16_t tmp;
6162
6163         if (bwn_has_hwpctl(mac)) {
6164                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6165                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6166                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6167                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6168                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6169
6170                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6171                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6172                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6173                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6174         }
6175         if (phy->type == BWN_PHYTYPE_B &&
6176             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6177                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6178                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6179         }
6180         if (phy->rev >= 2) {
6181                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6182                 sav->phy_analogoverval =
6183                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6184                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6185                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6186                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6187                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6188                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6189
6190                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6191                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6192                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6193                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6194                 if (phy->type == BWN_PHYTYPE_G) {
6195                         if ((phy->rev >= 7) &&
6196                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6197                              BWN_BFL_EXTLNA)) {
6198                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6199                         } else {
6200                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6201                         }
6202                 } else {
6203                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6204                 }
6205                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6206         }
6207         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6208         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6209         sav->rf0 = BWN_RF_READ(mac, 0x43);
6210         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6211         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6212         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6213         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6214         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6215
6216         if (!BWN_HAS_TXMAG(phy)) {
6217                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6218                 sav->rf2 &= 0x00f0;
6219         }
6220         if (phy->type == BWN_PHYTYPE_B) {
6221                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6222                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6223                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6224                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6225         } else {
6226                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6227                             | 0x8000);
6228         }
6229         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6230                     & 0xf000);
6231
6232         tmp =
6233             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6234         BWN_PHY_WRITE(mac, tmp, 0x007f);
6235
6236         tmp = sav->phy_syncctl;
6237         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6238         tmp = sav->rf1;
6239         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6240
6241         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6242         if (phy->type == BWN_PHYTYPE_G ||
6243             (phy->type == BWN_PHYTYPE_B &&
6244              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6245                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6246         } else
6247                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6248         if (phy->rev >= 2)
6249                 bwn_dummy_transmission(mac, 0, 1);
6250         bwn_phy_g_switch_chan(mac, 6, 0);
6251         BWN_RF_READ(mac, 0x51);
6252         if (phy->type == BWN_PHYTYPE_G)
6253                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6254
6255         nanouptime(&ts);
6256         if (time_before(lo->txctl_measured_time,
6257             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6258                 bwn_lo_measure_txctl_values(mac);
6259
6260         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6261                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6262         else {
6263                 if (phy->type == BWN_PHYTYPE_B)
6264                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6265                 else
6266                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6267         }
6268 }
6269
6270 static void
6271 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6272 {
6273         struct bwn_phy *phy = &mac->mac_phy;
6274         struct bwn_phy_g *pg = &phy->phy_g;
6275         uint16_t tmp;
6276
6277         if (phy->rev >= 2) {
6278                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6279                 tmp = (pg->pg_pga_gain << 8);
6280                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6281                 DELAY(5);
6282                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6283                 DELAY(2);
6284                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6285         } else {
6286                 tmp = (pg->pg_pga_gain | 0xefa0);
6287                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6288         }
6289         if (phy->type == BWN_PHYTYPE_G) {
6290                 if (phy->rev >= 3)
6291                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6292                 else
6293                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6294                 if (phy->rev >= 2)
6295                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6296                 else
6297                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6298         }
6299         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6300         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6301         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6302         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6303         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6304         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6305         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6306         if (!BWN_HAS_TXMAG(phy)) {
6307                 tmp = sav->rf2;
6308                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6309         }
6310         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6311         if (phy->type == BWN_PHYTYPE_B &&
6312             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6313                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6314                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6315         }
6316         if (phy->rev >= 2) {
6317                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6318                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6319                               sav->phy_analogoverval);
6320                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6321                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6322                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6323                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6324                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6325         }
6326         if (bwn_has_hwpctl(mac)) {
6327                 tmp = (sav->phy_lomask & 0xbfff);
6328                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6329                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6330                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6331                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6332                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6333         }
6334         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6335 }
6336
6337 static int
6338 bwn_lo_probe_loctl(struct bwn_mac *mac,
6339     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6340 {
6341         struct bwn_phy *phy = &mac->mac_phy;
6342         struct bwn_phy_g *pg = &phy->phy_g;
6343         struct bwn_loctl orig, test;
6344         struct bwn_loctl prev = { -100, -100 };
6345         static const struct bwn_loctl modifiers[] = {
6346                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6347                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6348         };
6349         int begin, end, lower = 0, i;
6350         uint16_t feedth;
6351
6352         if (d->curstate == 0) {
6353                 begin = 1;
6354                 end = 8;
6355         } else if (d->curstate % 2 == 0) {
6356                 begin = d->curstate - 1;
6357                 end = d->curstate + 1;
6358         } else {
6359                 begin = d->curstate - 2;
6360                 end = d->curstate + 2;
6361         }
6362         if (begin < 1)
6363                 begin += 8;
6364         if (end > 8)
6365                 end -= 8;
6366
6367         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6368         i = begin;
6369         d->curstate = i;
6370         while (1) {
6371                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6372                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6373                 test.i += modifiers[i - 1].i * d->multipler;
6374                 test.q += modifiers[i - 1].q * d->multipler;
6375                 if ((test.i != prev.i || test.q != prev.q) &&
6376                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6377                         bwn_lo_write(mac, &test);
6378                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6379                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6380                         if (feedth < d->feedth) {
6381                                 memcpy(probe, &test,
6382                                     sizeof(struct bwn_loctl));
6383                                 lower = 1;
6384                                 d->feedth = feedth;
6385                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6386                                         break;
6387                         }
6388                 }
6389                 memcpy(&prev, &test, sizeof(prev));
6390                 if (i == end)
6391                         break;
6392                 if (i == 8)
6393                         i = 1;
6394                 else
6395                         i++;
6396                 d->curstate = i;
6397         }
6398
6399         return (lower);
6400 }
6401
6402 static void
6403 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6404 {
6405         struct bwn_phy *phy = &mac->mac_phy;
6406         struct bwn_phy_g *pg = &phy->phy_g;
6407         struct bwn_lo_g_sm d;
6408         struct bwn_loctl probe;
6409         int lower, repeat, cnt = 0;
6410         uint16_t feedth;
6411
6412         d.nmeasure = 0;
6413         d.multipler = 1;
6414         if (BWN_HAS_LOOPBACK(phy))
6415                 d.multipler = 3;
6416
6417         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6418         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6419
6420         do {
6421                 bwn_lo_write(mac, &d.loctl);
6422                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6423                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6424                 if (feedth < 0x258) {
6425                         if (feedth >= 0x12c)
6426                                 *rxgain += 6;
6427                         else
6428                                 *rxgain += 3;
6429                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6430                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6431                 }
6432                 d.feedth = feedth;
6433                 d.curstate = 0;
6434                 do {
6435                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6436                             ("%s:%d: fail", __func__, __LINE__));
6437                         memcpy(&probe, &d.loctl,
6438                                sizeof(struct bwn_loctl));
6439                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6440                         if (!lower)
6441                                 break;
6442                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6443                                 break;
6444                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6445                         d.nmeasure++;
6446                 } while (d.nmeasure < 24);
6447                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6448
6449                 if (BWN_HAS_LOOPBACK(phy)) {
6450                         if (d.feedth > 0x1194)
6451                                 *rxgain -= 6;
6452                         else if (d.feedth < 0x5dc)
6453                                 *rxgain += 3;
6454                         if (cnt == 0) {
6455                                 if (d.feedth <= 0x5dc) {
6456                                         d.multipler = 1;
6457                                         cnt++;
6458                                 } else
6459                                         d.multipler = 2;
6460                         } else if (cnt == 2)
6461                                 d.multipler = 1;
6462                 }
6463                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6464         } while (++cnt < repeat);
6465 }
6466
6467 static struct bwn_lo_calib *
6468 bwn_lo_calibset(struct bwn_mac *mac,
6469     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6470 {
6471         struct bwn_phy *phy = &mac->mac_phy;
6472         struct bwn_phy_g *pg = &phy->phy_g;
6473         struct bwn_loctl loctl = { 0, 0 };
6474         struct bwn_lo_calib *cal;
6475         struct bwn_lo_g_value sval = { 0 };
6476         int rxgain;
6477         uint16_t pad, reg, value;
6478
6479         sval.old_channel = phy->chan;
6480         bwn_mac_suspend(mac);
6481         bwn_lo_save(mac, &sval);
6482
6483         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6484         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6485         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6486
6487         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6488         if (rfatt->padmix)
6489                 rxgain -= pad;
6490         if (BWN_HAS_LOOPBACK(phy))
6491                 rxgain += pg->pg_max_lb_gain;
6492         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6493         bwn_phy_g_set_bbatt(mac, bbatt->att);
6494         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6495
6496         bwn_lo_restore(mac, &sval);
6497         bwn_mac_enable(mac);
6498
6499         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6500         if (!cal) {
6501                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6502                 return (NULL);
6503         }
6504         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6505         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6506         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6507
6508         BWN_GETTIME(cal->calib_time);
6509
6510         return (cal);
6511 }
6512
6513 static struct bwn_lo_calib *
6514 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6515     const struct bwn_rfatt *rfatt)
6516 {
6517         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6518         struct bwn_lo_calib *c;
6519
6520         TAILQ_FOREACH(c, &lo->calib_list, list) {
6521                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6522                         continue;
6523                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6524                         continue;
6525                 return (c);
6526         }
6527
6528         c = bwn_lo_calibset(mac, bbatt, rfatt);
6529         if (!c)
6530                 return (NULL);
6531         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6532
6533         return (c);
6534 }
6535
6536 static void
6537 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6538 {
6539         struct bwn_phy *phy = &mac->mac_phy;
6540         struct bwn_phy_g *pg = &phy->phy_g;
6541         struct bwn_softc *sc = mac->mac_sc;
6542         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6543         const struct bwn_rfatt *rfatt;
6544         const struct bwn_bbatt *bbatt;
6545         uint64_t pvector;
6546         int i;
6547         int rf_offset, bb_offset;
6548         uint8_t changed = 0;
6549
6550         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6551         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6552             ("%s:%d: fail", __func__, __LINE__));
6553
6554         pvector = lo->power_vector;
6555         if (!update && !pvector)
6556                 return;
6557
6558         bwn_mac_suspend(mac);
6559
6560         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6561                 struct bwn_lo_calib *cal;
6562                 int idx;
6563                 uint16_t val;
6564
6565                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6566                         continue;
6567                 bb_offset = i / lo->rfatt.len;
6568                 rf_offset = i % lo->rfatt.len;
6569                 bbatt = &(lo->bbatt.array[bb_offset]);
6570                 rfatt = &(lo->rfatt.array[rf_offset]);
6571
6572                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6573                 if (!cal) {
6574                         device_printf(sc->sc_dev, "LO: Could not "
6575                             "calibrate DC table entry\n");
6576                         continue;
6577                 }
6578                 val = (uint8_t)(cal->ctl.q);
6579                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6580                 free(cal, M_DEVBUF);
6581
6582                 idx = i / 2;
6583                 if (i % 2)
6584                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6585                             | ((val & 0x00ff) << 8);
6586                 else
6587                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6588                             | (val & 0x00ff);
6589                 changed = 1;
6590         }
6591         if (changed) {
6592                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6593                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6594         }
6595         bwn_mac_enable(mac);
6596 }
6597
6598 static void
6599 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6600 {
6601
6602         if (!rf->padmix)
6603                 return;
6604         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6605                 rf->att = 4;
6606 }
6607
6608 static void
6609 bwn_lo_g_adjust(struct bwn_mac *mac)
6610 {
6611         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6612         struct bwn_lo_calib *cal;
6613         struct bwn_rfatt rf;
6614
6615         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6616         bwn_lo_fixup_rfatt(&rf);
6617
6618         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6619         if (!cal)
6620                 return;
6621         bwn_lo_write(mac, &cal->ctl);
6622 }
6623
6624 static void
6625 bwn_lo_g_init(struct bwn_mac *mac)
6626 {
6627
6628         if (!bwn_has_hwpctl(mac))
6629                 return;
6630
6631         bwn_lo_get_powervector(mac);
6632         bwn_phy_g_dc_lookup_init(mac, 1);
6633 }
6634
6635 static void
6636 bwn_mac_suspend(struct bwn_mac *mac)
6637 {
6638         struct bwn_softc *sc = mac->mac_sc;
6639         int i;
6640         uint32_t tmp;
6641
6642         KASSERT(mac->mac_suspended >= 0,
6643             ("%s:%d: fail", __func__, __LINE__));
6644
6645         if (mac->mac_suspended == 0) {
6646                 bwn_psctl(mac, BWN_PS_AWAKE);
6647                 BWN_WRITE_4(mac, BWN_MACCTL,
6648                             BWN_READ_4(mac, BWN_MACCTL)
6649                             & ~BWN_MACCTL_ON);
6650                 BWN_READ_4(mac, BWN_MACCTL);
6651                 for (i = 35; i; i--) {
6652                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6653                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6654                                 goto out;
6655                         DELAY(10);
6656                 }
6657                 for (i = 40; i; i--) {
6658                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6659                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6660                                 goto out;
6661                         DELAY(1000);
6662                 }
6663                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6664         }
6665 out:
6666         mac->mac_suspended++;
6667 }
6668
6669 static void
6670 bwn_mac_enable(struct bwn_mac *mac)
6671 {
6672         struct bwn_softc *sc = mac->mac_sc;
6673         uint16_t state;
6674
6675         state = bwn_shm_read_2(mac, BWN_SHARED,
6676             BWN_SHARED_UCODESTAT);
6677         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6678             state != BWN_SHARED_UCODESTAT_SLEEP)
6679                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6680
6681         mac->mac_suspended--;
6682         KASSERT(mac->mac_suspended >= 0,
6683             ("%s:%d: fail", __func__, __LINE__));
6684         if (mac->mac_suspended == 0) {
6685                 BWN_WRITE_4(mac, BWN_MACCTL,
6686                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6687                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6688                 BWN_READ_4(mac, BWN_MACCTL);
6689                 BWN_READ_4(mac, BWN_INTR_REASON);
6690                 bwn_psctl(mac, 0);
6691         }
6692 }
6693
6694 static void
6695 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6696 {
6697         struct bwn_softc *sc = mac->mac_sc;
6698         int i;
6699         uint16_t ucstat;
6700
6701         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6702             ("%s:%d: fail", __func__, __LINE__));
6703         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6704             ("%s:%d: fail", __func__, __LINE__));
6705
6706         /* XXX forcibly awake and hwps-off */
6707
6708         BWN_WRITE_4(mac, BWN_MACCTL,
6709             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6710             ~BWN_MACCTL_HWPS);
6711         BWN_READ_4(mac, BWN_MACCTL);
6712         if (siba_get_revid(sc->sc_dev) >= 5) {
6713                 for (i = 0; i < 100; i++) {
6714                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6715                             BWN_SHARED_UCODESTAT);
6716                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6717                                 break;
6718                         DELAY(10);
6719                 }
6720         }
6721 }
6722
6723 static int16_t
6724 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6725 {
6726
6727         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6728         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6729 }
6730
6731 static void
6732 bwn_nrssi_threshold(struct bwn_mac *mac)
6733 {
6734         struct bwn_phy *phy = &mac->mac_phy;
6735         struct bwn_phy_g *pg = &phy->phy_g;
6736         struct bwn_softc *sc = mac->mac_sc;
6737         int32_t a, b;
6738         int16_t tmp16;
6739         uint16_t tmpu16;
6740
6741         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6742
6743         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6744                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6745                         a = 0x13;
6746                         b = 0x12;
6747                 } else {
6748                         a = 0xe;
6749                         b = 0x11;
6750                 }
6751
6752                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6753                 a += (pg->pg_nrssi[0] << 6);
6754                 a += (a < 32) ? 31 : 32;
6755                 a = a >> 6;
6756                 a = MIN(MAX(a, -31), 31);
6757
6758                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6759                 b += (pg->pg_nrssi[0] << 6);
6760                 if (b < 32)
6761                         b += 31;
6762                 else
6763                         b += 32;
6764                 b = b >> 6;
6765                 b = MIN(MAX(b, -31), 31);
6766
6767                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6768                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6769                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6770                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6771                 return;
6772         }
6773
6774         tmp16 = bwn_nrssi_read(mac, 0x20);
6775         if (tmp16 >= 0x20)
6776                 tmp16 -= 0x40;
6777         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6778 }
6779
6780 static void
6781 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6782 {
6783 #define SAVE_RF_MAX             3
6784 #define SAVE_PHY_COMM_MAX       4
6785 #define SAVE_PHY3_MAX           8
6786         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6787                 { 0x7a, 0x52, 0x43 };
6788         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6789                 { 0x15, 0x5a, 0x59, 0x58 };
6790         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6791                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6792                 0x0801, 0x0060, 0x0014, 0x0478
6793         };
6794         struct bwn_phy *phy = &mac->mac_phy;
6795         struct bwn_phy_g *pg = &phy->phy_g;
6796         int32_t i, tmp32, phy3_idx = 0;
6797         uint16_t delta, tmp;
6798         uint16_t save_rf[SAVE_RF_MAX];
6799         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6800         uint16_t save_phy3[SAVE_PHY3_MAX];
6801         uint16_t ant_div, phy0, chan_ex;
6802         int16_t nrssi0, nrssi1;
6803
6804         KASSERT(phy->type == BWN_PHYTYPE_G,
6805             ("%s:%d: fail", __func__, __LINE__));
6806
6807         if (phy->rf_rev >= 9)
6808                 return;
6809         if (phy->rf_rev == 8)
6810                 bwn_nrssi_offset(mac);
6811
6812         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6813         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6814
6815         /*
6816          * Save RF/PHY registers for later restoration
6817          */
6818         ant_div = BWN_READ_2(mac, 0x03e2);
6819         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6820         for (i = 0; i < SAVE_RF_MAX; ++i)
6821                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6822         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6823                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6824
6825         phy0 = BWN_READ_2(mac, BWN_PHY0);
6826         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6827         if (phy->rev >= 3) {
6828                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6829                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6830                 BWN_PHY_WRITE(mac, 0x002e, 0);
6831                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6832                 switch (phy->rev) {
6833                 case 4:
6834                 case 6:
6835                 case 7:
6836                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6837                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6838                         break;
6839                 case 3:
6840                 case 5:
6841                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6842                         break;
6843                 }
6844                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6845                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6846         }
6847         /*
6848          * Calculate nrssi0
6849          */
6850         BWN_RF_SET(mac, 0x007a, 0x0070);
6851         bwn_set_all_gains(mac, 0, 8, 0);
6852         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6853         if (phy->rev >= 2) {
6854                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6855                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6856         }
6857         BWN_RF_SET(mac, 0x007a, 0x0080);
6858         DELAY(20);
6859
6860         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6861         if (nrssi0 >= 0x0020)
6862                 nrssi0 -= 0x0040;
6863
6864         /*
6865          * Calculate nrssi1
6866          */
6867         BWN_RF_MASK(mac, 0x007a, 0x007f);
6868         if (phy->rev >= 2)
6869                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6870
6871         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6872             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6873         BWN_RF_SET(mac, 0x007a, 0x000f);
6874         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6875         if (phy->rev >= 2) {
6876                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6877                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6878         }
6879
6880         bwn_set_all_gains(mac, 3, 0, 1);
6881         if (phy->rf_rev == 8) {
6882                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6883         } else {
6884                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6885                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6886                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6887                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6888         }
6889         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6890         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6891         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6892         DELAY(20);
6893         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6894
6895         /*
6896          * Install calculated narrow RSSI values
6897          */
6898         if (nrssi1 >= 0x0020)
6899                 nrssi1 -= 0x0040;
6900         if (nrssi0 == nrssi1)
6901                 pg->pg_nrssi_slope = 0x00010000;
6902         else
6903                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6904         if (nrssi0 >= -4) {
6905                 pg->pg_nrssi[0] = nrssi1;
6906                 pg->pg_nrssi[1] = nrssi0;
6907         }
6908
6909         /*
6910          * Restore saved RF/PHY registers
6911          */
6912         if (phy->rev >= 3) {
6913                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6914                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6915                             save_phy3[phy3_idx]);
6916                 }
6917         }
6918         if (phy->rev >= 2) {
6919                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6920                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6921         }
6922
6923         for (i = 0; i < SAVE_RF_MAX; ++i)
6924                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6925
6926         BWN_WRITE_2(mac, 0x03e2, ant_div);
6927         BWN_WRITE_2(mac, 0x03e6, phy0);
6928         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6929
6930         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6931                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6932
6933         bwn_spu_workaround(mac, phy->chan);
6934         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6935         bwn_set_original_gains(mac);
6936         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6937         if (phy->rev >= 3) {
6938                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6939                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6940                             save_phy3[phy3_idx]);
6941                 }
6942         }
6943
6944         delta = 0x1f - pg->pg_nrssi[0];
6945         for (i = 0; i < 64; i++) {
6946                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6947                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6948                 pg->pg_nrssi_lt[i] = tmp32;
6949         }
6950
6951         bwn_nrssi_threshold(mac);
6952 #undef SAVE_RF_MAX
6953 #undef SAVE_PHY_COMM_MAX
6954 #undef SAVE_PHY3_MAX
6955 }
6956
6957 static void
6958 bwn_nrssi_offset(struct bwn_mac *mac)
6959 {
6960 #define SAVE_RF_MAX             2
6961 #define SAVE_PHY_COMM_MAX       10
6962 #define SAVE_PHY6_MAX           8
6963         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6964                 { 0x7a, 0x43 };
6965         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6966                 0x0001, 0x0811, 0x0812, 0x0814,
6967                 0x0815, 0x005a, 0x0059, 0x0058,
6968                 0x000a, 0x0003
6969         };
6970         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6971                 0x002e, 0x002f, 0x080f, 0x0810,
6972                 0x0801, 0x0060, 0x0014, 0x0478
6973         };
6974         struct bwn_phy *phy = &mac->mac_phy;
6975         int i, phy6_idx = 0;
6976         uint16_t save_rf[SAVE_RF_MAX];
6977         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6978         uint16_t save_phy6[SAVE_PHY6_MAX];
6979         int16_t nrssi;
6980         uint16_t saved = 0xffff;
6981
6982         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6983                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6984         for (i = 0; i < SAVE_RF_MAX; ++i)
6985                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6986
6987         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6988         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6989         BWN_PHY_SET(mac, 0x0811, 0x000c);
6990         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6991         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6992         if (phy->rev >= 6) {
6993                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6994                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6995
6996                 BWN_PHY_WRITE(mac, 0x002e, 0);
6997                 BWN_PHY_WRITE(mac, 0x002f, 0);
6998                 BWN_PHY_WRITE(mac, 0x080f, 0);
6999                 BWN_PHY_WRITE(mac, 0x0810, 0);
7000                 BWN_PHY_SET(mac, 0x0478, 0x0100);
7001                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7002                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7003                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7004         }
7005         BWN_RF_SET(mac, 0x007a, 0x0070);
7006         BWN_RF_SET(mac, 0x007a, 0x0080);
7007         DELAY(30);
7008
7009         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7010         if (nrssi >= 0x20)
7011                 nrssi -= 0x40;
7012         if (nrssi == 31) {
7013                 for (i = 7; i >= 4; i--) {
7014                         BWN_RF_WRITE(mac, 0x007b, i);
7015                         DELAY(20);
7016                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7017                             0x003f);
7018                         if (nrssi >= 0x20)
7019                                 nrssi -= 0x40;
7020                         if (nrssi < 31 && saved == 0xffff)
7021                                 saved = i;
7022                 }
7023                 if (saved == 0xffff)
7024                         saved = 4;
7025         } else {
7026                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7027                 if (phy->rev != 1) {
7028                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7029                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7030                 }
7031                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7032                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7033                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7034                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7035                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7036                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7037                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7038                 if (phy->rev == 0)
7039                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7040                 else
7041                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7042                 if (phy->rev != 1) {
7043                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7044                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7045                 }
7046                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7047                 BWN_RF_SET(mac, 0x007a, 0x000f);
7048                 bwn_set_all_gains(mac, 3, 0, 1);
7049                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7050                 DELAY(30);
7051                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7052                 if (nrssi >= 0x20)
7053                         nrssi -= 0x40;
7054                 if (nrssi == -32) {
7055                         for (i = 0; i < 4; i++) {
7056                                 BWN_RF_WRITE(mac, 0x007b, i);
7057                                 DELAY(20);
7058                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7059                                     0x047f) >> 8) & 0x003f);
7060                                 if (nrssi >= 0x20)
7061                                         nrssi -= 0x40;
7062                                 if (nrssi > -31 && saved == 0xffff)
7063                                         saved = i;
7064                         }
7065                         if (saved == 0xffff)
7066                                 saved = 3;
7067                 } else
7068                         saved = 0;
7069         }
7070         BWN_RF_WRITE(mac, 0x007b, saved);
7071
7072         /*
7073          * Restore saved RF/PHY registers
7074          */
7075         if (phy->rev >= 6) {
7076                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7077                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7078                             save_phy6[phy6_idx]);
7079                 }
7080         }
7081         if (phy->rev != 1) {
7082                 for (i = 3; i < 5; i++)
7083                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7084                             save_phy_comm[i]);
7085         }
7086         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7087                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7088
7089         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7090                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7091
7092         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7093         BWN_PHY_SET(mac, 0x0429, 0x8000);
7094         bwn_set_original_gains(mac);
7095         if (phy->rev >= 6) {
7096                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7097                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7098                             save_phy6[phy6_idx]);
7099                 }
7100         }
7101
7102         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7103         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7104         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7105 }
7106
7107 static void
7108 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7109     int16_t third)
7110 {
7111         struct bwn_phy *phy = &mac->mac_phy;
7112         uint16_t i;
7113         uint16_t start = 0x08, end = 0x18;
7114         uint16_t tmp;
7115         uint16_t table;
7116
7117         if (phy->rev <= 1) {
7118                 start = 0x10;
7119                 end = 0x20;
7120         }
7121
7122         table = BWN_OFDMTAB_GAINX;
7123         if (phy->rev <= 1)
7124                 table = BWN_OFDMTAB_GAINX_R1;
7125         for (i = 0; i < 4; i++)
7126                 bwn_ofdmtab_write_2(mac, table, i, first);
7127
7128         for (i = start; i < end; i++)
7129                 bwn_ofdmtab_write_2(mac, table, i, second);
7130
7131         if (third != -1) {
7132                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7133                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7134                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7135                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7136         }
7137         bwn_dummy_transmission(mac, 0, 1);
7138 }
7139
7140 static void
7141 bwn_set_original_gains(struct bwn_mac *mac)
7142 {
7143         struct bwn_phy *phy = &mac->mac_phy;
7144         uint16_t i, tmp;
7145         uint16_t table;
7146         uint16_t start = 0x0008, end = 0x0018;
7147
7148         if (phy->rev <= 1) {
7149                 start = 0x0010;
7150                 end = 0x0020;
7151         }
7152
7153         table = BWN_OFDMTAB_GAINX;
7154         if (phy->rev <= 1)
7155                 table = BWN_OFDMTAB_GAINX_R1;
7156         for (i = 0; i < 4; i++) {
7157                 tmp = (i & 0xfffc);
7158                 tmp |= (i & 0x0001) << 1;
7159                 tmp |= (i & 0x0002) >> 1;
7160
7161                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7162         }
7163
7164         for (i = start; i < end; i++)
7165                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7166
7167         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7168         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7169         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7170         bwn_dummy_transmission(mac, 0, 1);
7171 }
7172
7173 static void
7174 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7175 {
7176         struct bwn_phy *phy = &mac->mac_phy;
7177         struct bwn_phy_g *pg = &phy->phy_g;
7178         struct bwn_rfatt old_rfatt, rfatt;
7179         struct bwn_bbatt old_bbatt, bbatt;
7180         struct bwn_softc *sc = mac->mac_sc;
7181         uint8_t old_txctl = 0;
7182
7183         KASSERT(phy->type == BWN_PHYTYPE_G,
7184             ("%s:%d: fail", __func__, __LINE__));
7185
7186         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7187             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7188                 return;
7189
7190         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7191
7192         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7193
7194         if (!phy->gmode)
7195                 return;
7196         bwn_hwpctl_early_init(mac);
7197         if (pg->pg_curtssi == 0) {
7198                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7199                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7200                 } else {
7201                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7202                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7203                         old_txctl = pg->pg_txctl;
7204
7205                         bbatt.att = 11;
7206                         if (phy->rf_rev == 8) {
7207                                 rfatt.att = 15;
7208                                 rfatt.padmix = 1;
7209                         } else {
7210                                 rfatt.att = 9;
7211                                 rfatt.padmix = 0;
7212                         }
7213                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7214                 }
7215                 bwn_dummy_transmission(mac, 0, 1);
7216                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7217                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7218                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7219                 else
7220                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7221                             &old_rfatt, old_txctl);
7222         }
7223         bwn_hwpctl_init_gphy(mac);
7224
7225         /* clear TSSI */
7226         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7227         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7228         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7229         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7230 }
7231
7232 static void
7233 bwn_hwpctl_early_init(struct bwn_mac *mac)
7234 {
7235         struct bwn_phy *phy = &mac->mac_phy;
7236
7237         if (!bwn_has_hwpctl(mac)) {
7238                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7239                 return;
7240         }
7241
7242         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7243         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7244         BWN_PHY_SET(mac, 0x047c, 0x0002);
7245         BWN_PHY_SET(mac, 0x047a, 0xf000);
7246         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7247                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7248                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7249                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7250                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7251                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7252         } else {
7253                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7254                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7255                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7256                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7257                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7258                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7259                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7260         }
7261 }
7262
7263 static void
7264 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7265 {
7266         struct bwn_phy *phy = &mac->mac_phy;
7267         struct bwn_phy_g *pg = &phy->phy_g;
7268         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7269         int i;
7270         uint16_t nr_written = 0, tmp, value;
7271         uint8_t rf, bb;
7272
7273         if (!bwn_has_hwpctl(mac)) {
7274                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7275                 return;
7276         }
7277
7278         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7279             (pg->pg_idletssi - pg->pg_curtssi));
7280         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7281             (pg->pg_idletssi - pg->pg_curtssi));
7282
7283         for (i = 0; i < 32; i++)
7284                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7285         for (i = 32; i < 64; i++)
7286                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7287         for (i = 0; i < 64; i += 2) {
7288                 value = (uint16_t) pg->pg_tssi2dbm[i];
7289                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7290                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7291         }
7292
7293         for (rf = 0; rf < lo->rfatt.len; rf++) {
7294                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7295                         if (nr_written >= 0x40)
7296                                 return;
7297                         tmp = lo->bbatt.array[bb].att;
7298                         tmp <<= 8;
7299                         if (phy->rf_rev == 8)
7300                                 tmp |= 0x50;
7301                         else
7302                                 tmp |= 0x40;
7303                         tmp |= lo->rfatt.array[rf].att;
7304                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7305                         nr_written++;
7306                 }
7307         }
7308
7309         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7310         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7311
7312         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7313         BWN_PHY_SET(mac, 0x0478, 0x0800);
7314         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7315         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7316
7317         bwn_phy_g_dc_lookup_init(mac, 1);
7318         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7319 }
7320
7321 static void
7322 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7323 {
7324         struct bwn_softc *sc = mac->mac_sc;
7325
7326         if (spu != 0)
7327                 bwn_spu_workaround(mac, channel);
7328
7329         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7330
7331         if (channel == 14) {
7332                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7333                         bwn_hf_write(mac,
7334                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7335                 else
7336                         bwn_hf_write(mac,
7337                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7338                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7339                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7340                 return;
7341         }
7342
7343         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7344             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7345 }
7346
7347 static uint16_t
7348 bwn_phy_g_chan2freq(uint8_t channel)
7349 {
7350         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7351
7352         KASSERT(channel >= 1 && channel <= 14,
7353             ("%s:%d: fail", __func__, __LINE__));
7354
7355         return (bwn_phy_g_rf_channels[channel - 1]);
7356 }
7357
7358 static void
7359 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7360     const struct bwn_rfatt *rfatt, uint8_t txctl)
7361 {
7362         struct bwn_phy *phy = &mac->mac_phy;
7363         struct bwn_phy_g *pg = &phy->phy_g;
7364         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7365         uint16_t bb, rf;
7366         uint16_t tx_bias, tx_magn;
7367
7368         bb = bbatt->att;
7369         rf = rfatt->att;
7370         tx_bias = lo->tx_bias;
7371         tx_magn = lo->tx_magn;
7372         if (tx_bias == 0xff)
7373                 tx_bias = 0;
7374
7375         pg->pg_txctl = txctl;
7376         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7377         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7378         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7379         bwn_phy_g_set_bbatt(mac, bb);
7380         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7381         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7382                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7383         else {
7384                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7385                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7386         }
7387         if (BWN_HAS_TXMAG(phy))
7388                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7389         else
7390                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7391         bwn_lo_g_adjust(mac);
7392 }
7393
7394 static void
7395 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7396     uint16_t bbatt)
7397 {
7398         struct bwn_phy *phy = &mac->mac_phy;
7399
7400         if (phy->analog == 0) {
7401                 BWN_WRITE_2(mac, BWN_PHY0,
7402                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7403                 return;
7404         }
7405         if (phy->analog > 1) {
7406                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7407                 return;
7408         }
7409         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7410 }
7411
7412 static uint16_t
7413 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7414 {
7415         struct bwn_phy *phy = &mac->mac_phy;
7416         struct bwn_phy_g *pg = &phy->phy_g;
7417         struct bwn_softc *sc = mac->mac_sc;
7418         int max_lb_gain;
7419         uint16_t extlna;
7420         uint16_t i;
7421
7422         if (phy->gmode == 0)
7423                 return (0);
7424
7425         if (BWN_HAS_LOOPBACK(phy)) {
7426                 max_lb_gain = pg->pg_max_lb_gain;
7427                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7428                 if (max_lb_gain >= 0x46) {
7429                         extlna = 0x3000;
7430                         max_lb_gain -= 0x46;
7431                 } else if (max_lb_gain >= 0x3a) {
7432                         extlna = 0x1000;
7433                         max_lb_gain -= 0x3a;
7434                 } else if (max_lb_gain >= 0x2e) {
7435                         extlna = 0x2000;
7436                         max_lb_gain -= 0x2e;
7437                 } else {
7438                         extlna = 0;
7439                         max_lb_gain -= 0x10;
7440                 }
7441
7442                 for (i = 0; i < 16; i++) {
7443                         max_lb_gain -= (i * 6);
7444                         if (max_lb_gain < 6)
7445                                 break;
7446                 }
7447
7448                 if ((phy->rev < 7) ||
7449                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7450                         if (reg == BWN_PHY_RFOVER) {
7451                                 return (0x1b3);
7452                         } else if (reg == BWN_PHY_RFOVERVAL) {
7453                                 extlna |= (i << 8);
7454                                 switch (lpd) {
7455                                 case BWN_LPD(0, 1, 1):
7456                                         return (0x0f92);
7457                                 case BWN_LPD(0, 0, 1):
7458                                 case BWN_LPD(1, 0, 1):
7459                                         return (0x0092 | extlna);
7460                                 case BWN_LPD(1, 0, 0):
7461                                         return (0x0093 | extlna);
7462                                 }
7463                                 KASSERT(0 == 1,
7464                                     ("%s:%d: fail", __func__, __LINE__));
7465                         }
7466                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7467                 } else {
7468                         if (reg == BWN_PHY_RFOVER)
7469                                 return (0x9b3);
7470                         if (reg == BWN_PHY_RFOVERVAL) {
7471                                 if (extlna)
7472                                         extlna |= 0x8000;
7473                                 extlna |= (i << 8);
7474                                 switch (lpd) {
7475                                 case BWN_LPD(0, 1, 1):
7476                                         return (0x8f92);
7477                                 case BWN_LPD(0, 0, 1):
7478                                         return (0x8092 | extlna);
7479                                 case BWN_LPD(1, 0, 1):
7480                                         return (0x2092 | extlna);
7481                                 case BWN_LPD(1, 0, 0):
7482                                         return (0x2093 | extlna);
7483                                 }
7484                                 KASSERT(0 == 1,
7485                                     ("%s:%d: fail", __func__, __LINE__));
7486                         }
7487                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7488                 }
7489                 return (0);
7490         }
7491
7492         if ((phy->rev < 7) ||
7493             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7494                 if (reg == BWN_PHY_RFOVER) {
7495                         return (0x1b3);
7496                 } else if (reg == BWN_PHY_RFOVERVAL) {
7497                         switch (lpd) {
7498                         case BWN_LPD(0, 1, 1):
7499                                 return (0x0fb2);
7500                         case BWN_LPD(0, 0, 1):
7501                                 return (0x00b2);
7502                         case BWN_LPD(1, 0, 1):
7503                                 return (0x30b2);
7504                         case BWN_LPD(1, 0, 0):
7505                                 return (0x30b3);
7506                         }
7507                         KASSERT(0 == 1,
7508                             ("%s:%d: fail", __func__, __LINE__));
7509                 }
7510                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7511         } else {
7512                 if (reg == BWN_PHY_RFOVER) {
7513                         return (0x9b3);
7514                 } else if (reg == BWN_PHY_RFOVERVAL) {
7515                         switch (lpd) {
7516                         case BWN_LPD(0, 1, 1):
7517                                 return (0x8fb2);
7518                         case BWN_LPD(0, 0, 1):
7519                                 return (0x80b2);
7520                         case BWN_LPD(1, 0, 1):
7521                                 return (0x20b2);
7522                         case BWN_LPD(1, 0, 0):
7523                                 return (0x20b3);
7524                         }
7525                         KASSERT(0 == 1,
7526                             ("%s:%d: fail", __func__, __LINE__));
7527                 }
7528                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7529         }
7530         return (0);
7531 }
7532
7533 static void
7534 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7535 {
7536
7537         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7538                 return;
7539         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7540             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7541         DELAY(1000);
7542         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7543 }
7544
7545 static int
7546 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7547 {
7548         struct bwn_softc *sc = mac->mac_sc;
7549         struct bwn_fw *fw = &mac->mac_fw;
7550         const uint8_t rev = siba_get_revid(sc->sc_dev);
7551         const char *filename;
7552         uint32_t high;
7553         int error;
7554
7555         /* microcode */
7556         if (rev >= 5 && rev <= 10)
7557                 filename = "ucode5";
7558         else if (rev >= 11 && rev <= 12)
7559                 filename = "ucode11";
7560         else if (rev == 13)
7561                 filename = "ucode13";
7562         else if (rev == 14)
7563                 filename = "ucode14";
7564         else if (rev >= 15)
7565                 filename = "ucode15";
7566         else {
7567                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7568                 bwn_release_firmware(mac);
7569                 return (EOPNOTSUPP);
7570         }
7571         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7572         if (error) {
7573                 bwn_release_firmware(mac);
7574                 return (error);
7575         }
7576
7577         /* PCM */
7578         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7579         if (rev >= 5 && rev <= 10) {
7580                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7581                 if (error == ENOENT)
7582                         fw->no_pcmfile = 1;
7583                 else if (error) {
7584                         bwn_release_firmware(mac);
7585                         return (error);
7586                 }
7587         } else if (rev < 11) {
7588                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7589                 return (EOPNOTSUPP);
7590         }
7591
7592         /* initvals */
7593         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7594         switch (mac->mac_phy.type) {
7595         case BWN_PHYTYPE_A:
7596                 if (rev < 5 || rev > 10)
7597                         goto fail1;
7598                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7599                         filename = "a0g1initvals5";
7600                 else
7601                         filename = "a0g0initvals5";
7602                 break;
7603         case BWN_PHYTYPE_G:
7604                 if (rev >= 5 && rev <= 10)
7605                         filename = "b0g0initvals5";
7606                 else if (rev >= 13)
7607                         filename = "b0g0initvals13";
7608                 else
7609                         goto fail1;
7610                 break;
7611         case BWN_PHYTYPE_LP:
7612                 if (rev == 13)
7613                         filename = "lp0initvals13";
7614                 else if (rev == 14)
7615                         filename = "lp0initvals14";
7616                 else if (rev >= 15)
7617                         filename = "lp0initvals15";
7618                 else
7619                         goto fail1;
7620                 break;
7621         case BWN_PHYTYPE_N:
7622                 if (rev >= 11 && rev <= 12)
7623                         filename = "n0initvals11";
7624                 else
7625                         goto fail1;
7626                 break;
7627         default:
7628                 goto fail1;
7629         }
7630         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7631         if (error) {
7632                 bwn_release_firmware(mac);
7633                 return (error);
7634         }
7635
7636         /* bandswitch initvals */
7637         switch (mac->mac_phy.type) {
7638         case BWN_PHYTYPE_A:
7639                 if (rev >= 5 && rev <= 10) {
7640                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7641                                 filename = "a0g1bsinitvals5";
7642                         else
7643                                 filename = "a0g0bsinitvals5";
7644                 } else if (rev >= 11)
7645                         filename = NULL;
7646                 else
7647                         goto fail1;
7648                 break;
7649         case BWN_PHYTYPE_G:
7650                 if (rev >= 5 && rev <= 10)
7651                         filename = "b0g0bsinitvals5";
7652                 else if (rev >= 11)
7653                         filename = NULL;
7654                 else
7655                         goto fail1;
7656                 break;
7657         case BWN_PHYTYPE_LP:
7658                 if (rev == 13)
7659                         filename = "lp0bsinitvals13";
7660                 else if (rev == 14)
7661                         filename = "lp0bsinitvals14";
7662                 else if (rev >= 15)
7663                         filename = "lp0bsinitvals15";
7664                 else
7665                         goto fail1;
7666                 break;
7667         case BWN_PHYTYPE_N:
7668                 if (rev >= 11 && rev <= 12)
7669                         filename = "n0bsinitvals11";
7670                 else
7671                         goto fail1;
7672                 break;
7673         default:
7674                 goto fail1;
7675         }
7676         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7677         if (error) {
7678                 bwn_release_firmware(mac);
7679                 return (error);
7680         }
7681         return (0);
7682 fail1:
7683         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7684         bwn_release_firmware(mac);
7685         return (EOPNOTSUPP);
7686 }
7687
7688 static int
7689 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7690     const char *name, struct bwn_fwfile *bfw)
7691 {
7692         const struct bwn_fwhdr *hdr;
7693         struct bwn_softc *sc = mac->mac_sc;
7694         const struct firmware *fw;
7695         char namebuf[64];
7696
7697         if (name == NULL) {
7698                 bwn_do_release_fw(bfw);
7699                 return (0);
7700         }
7701         if (bfw->filename != NULL) {
7702                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7703                         return (0);
7704                 bwn_do_release_fw(bfw);
7705         }
7706
7707         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7708             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7709             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7710         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7711         fw = firmware_get(namebuf);
7712         if (fw == NULL) {
7713                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7714                     namebuf);
7715                 return (ENOENT);
7716         }
7717         if (fw->datasize < sizeof(struct bwn_fwhdr))
7718                 goto fail;
7719         hdr = (const struct bwn_fwhdr *)(fw->data);
7720         switch (hdr->type) {
7721         case BWN_FWTYPE_UCODE:
7722         case BWN_FWTYPE_PCM:
7723                 if (be32toh(hdr->size) !=
7724                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7725                         goto fail;
7726                 /* FALLTHROUGH */
7727         case BWN_FWTYPE_IV:
7728                 if (hdr->ver != 1)
7729                         goto fail;
7730                 break;
7731         default:
7732                 goto fail;
7733         }
7734         bfw->filename = name;
7735         bfw->fw = fw;
7736         bfw->type = type;
7737         return (0);
7738 fail:
7739         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7740         if (fw != NULL)
7741                 firmware_put(fw, FIRMWARE_UNLOAD);
7742         return (EPROTO);
7743 }
7744
7745 static void
7746 bwn_release_firmware(struct bwn_mac *mac)
7747 {
7748
7749         bwn_do_release_fw(&mac->mac_fw.ucode);
7750         bwn_do_release_fw(&mac->mac_fw.pcm);
7751         bwn_do_release_fw(&mac->mac_fw.initvals);
7752         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7753 }
7754
7755 static void
7756 bwn_do_release_fw(struct bwn_fwfile *bfw)
7757 {
7758
7759         if (bfw->fw != NULL)
7760                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7761         bfw->fw = NULL;
7762         bfw->filename = NULL;
7763 }
7764
7765 static int
7766 bwn_fw_loaducode(struct bwn_mac *mac)
7767 {
7768 #define GETFWOFFSET(fwp, offset)        \
7769         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7770 #define GETFWSIZE(fwp, offset)  \
7771         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7772         struct bwn_softc *sc = mac->mac_sc;
7773         const uint32_t *data;
7774         unsigned int i;
7775         uint32_t ctl;
7776         uint16_t date, fwcaps, time;
7777         int error = 0;
7778
7779         ctl = BWN_READ_4(mac, BWN_MACCTL);
7780         ctl |= BWN_MACCTL_MCODE_JMP0;
7781         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7782             __LINE__));
7783         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7784         for (i = 0; i < 64; i++)
7785                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7786         for (i = 0; i < 4096; i += 2)
7787                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7788
7789         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7790         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7791         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7792              i++) {
7793                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7794                 DELAY(10);
7795         }
7796
7797         if (mac->mac_fw.pcm.fw) {
7798                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7799                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7800                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7801                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7802                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7803                     sizeof(struct bwn_fwhdr)); i++) {
7804                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7805                         DELAY(10);
7806                 }
7807         }
7808
7809         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7810         BWN_WRITE_4(mac, BWN_MACCTL,
7811             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7812             BWN_MACCTL_MCODE_RUN);
7813
7814         for (i = 0; i < 21; i++) {
7815                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7816                         break;
7817                 if (i >= 20) {
7818                         device_printf(sc->sc_dev, "ucode timeout\n");
7819                         error = ENXIO;
7820                         goto error;
7821                 }
7822                 DELAY(50000);
7823         }
7824         BWN_READ_4(mac, BWN_INTR_REASON);
7825
7826         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7827         if (mac->mac_fw.rev <= 0x128) {
7828                 device_printf(sc->sc_dev, "the firmware is too old\n");
7829                 error = EOPNOTSUPP;
7830                 goto error;
7831         }
7832         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7833             BWN_SHARED_UCODE_PATCH);
7834         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7835         mac->mac_fw.opensource = (date == 0xffff);
7836         if (bwn_wme != 0)
7837                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7838         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7839
7840         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7841         if (mac->mac_fw.opensource == 0) {
7842                 device_printf(sc->sc_dev,
7843                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7844                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7845                 if (mac->mac_fw.no_pcmfile)
7846                         device_printf(sc->sc_dev,
7847                             "no HW crypto acceleration due to pcm5\n");
7848         } else {
7849                 mac->mac_fw.patch = time;
7850                 fwcaps = bwn_fwcaps_read(mac);
7851                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7852                         device_printf(sc->sc_dev,
7853                             "disabling HW crypto acceleration\n");
7854                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7855                 }
7856                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7857                         device_printf(sc->sc_dev, "disabling WME support\n");
7858                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7859                 }
7860         }
7861
7862         if (BWN_ISOLDFMT(mac))
7863                 device_printf(sc->sc_dev, "using old firmware image\n");
7864
7865         return (0);
7866
7867 error:
7868         BWN_WRITE_4(mac, BWN_MACCTL,
7869             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7870             BWN_MACCTL_MCODE_JMP0);
7871
7872         return (error);
7873 #undef GETFWSIZE
7874 #undef GETFWOFFSET
7875 }
7876
7877 /* OpenFirmware only */
7878 static uint16_t
7879 bwn_fwcaps_read(struct bwn_mac *mac)
7880 {
7881
7882         KASSERT(mac->mac_fw.opensource == 1,
7883             ("%s:%d: fail", __func__, __LINE__));
7884         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7885 }
7886
7887 static int
7888 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7889     size_t count, size_t array_size)
7890 {
7891 #define GET_NEXTIV16(iv)                                                \
7892         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7893             sizeof(uint16_t) + sizeof(uint16_t)))
7894 #define GET_NEXTIV32(iv)                                                \
7895         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7896             sizeof(uint16_t) + sizeof(uint32_t)))
7897         struct bwn_softc *sc = mac->mac_sc;
7898         const struct bwn_fwinitvals *iv;
7899         uint16_t offset;
7900         size_t i;
7901         uint8_t bit32;
7902
7903         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7904             ("%s:%d: fail", __func__, __LINE__));
7905         iv = ivals;
7906         for (i = 0; i < count; i++) {
7907                 if (array_size < sizeof(iv->offset_size))
7908                         goto fail;
7909                 array_size -= sizeof(iv->offset_size);
7910                 offset = be16toh(iv->offset_size);
7911                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7912                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7913                 if (offset >= 0x1000)
7914                         goto fail;
7915                 if (bit32) {
7916                         if (array_size < sizeof(iv->data.d32))
7917                                 goto fail;
7918                         array_size -= sizeof(iv->data.d32);
7919                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7920                         iv = GET_NEXTIV32(iv);
7921                 } else {
7922
7923                         if (array_size < sizeof(iv->data.d16))
7924                                 goto fail;
7925                         array_size -= sizeof(iv->data.d16);
7926                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7927
7928                         iv = GET_NEXTIV16(iv);
7929                 }
7930         }
7931         if (array_size != 0)
7932                 goto fail;
7933         return (0);
7934 fail:
7935         device_printf(sc->sc_dev, "initvals: invalid format\n");
7936         return (EPROTO);
7937 #undef GET_NEXTIV16
7938 #undef GET_NEXTIV32
7939 }
7940
7941 static int
7942 bwn_switch_channel(struct bwn_mac *mac, int chan)
7943 {
7944         struct bwn_phy *phy = &(mac->mac_phy);
7945         struct bwn_softc *sc = mac->mac_sc;
7946         struct ifnet *ifp = sc->sc_ifp;
7947         struct ieee80211com *ic = ifp->if_l2com;
7948         uint16_t channelcookie, savedcookie;
7949         int error;
7950
7951         if (chan == 0xffff)
7952                 chan = phy->get_default_chan(mac);
7953
7954         channelcookie = chan;
7955         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7956                 channelcookie |= 0x100;
7957         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7958         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7959         error = phy->switch_channel(mac, chan);
7960         if (error)
7961                 goto fail;
7962
7963         mac->mac_phy.chan = chan;
7964         DELAY(8000);
7965         return (0);
7966 fail:
7967         device_printf(sc->sc_dev, "failed to switch channel\n");
7968         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7969         return (error);
7970 }
7971
7972 static uint16_t
7973 bwn_ant2phy(int antenna)
7974 {
7975
7976         switch (antenna) {
7977         case BWN_ANT0:
7978                 return (BWN_TX_PHY_ANT0);
7979         case BWN_ANT1:
7980                 return (BWN_TX_PHY_ANT1);
7981         case BWN_ANT2:
7982                 return (BWN_TX_PHY_ANT2);
7983         case BWN_ANT3:
7984                 return (BWN_TX_PHY_ANT3);
7985         case BWN_ANTAUTO:
7986                 return (BWN_TX_PHY_ANT01AUTO);
7987         }
7988         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7989         return (0);
7990 }
7991
7992 static void
7993 bwn_wme_load(struct bwn_mac *mac)
7994 {
7995         struct bwn_softc *sc = mac->mac_sc;
7996         int i;
7997
7998         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7999             ("%s:%d: fail", __func__, __LINE__));
8000
8001         bwn_mac_suspend(mac);
8002         for (i = 0; i < N(sc->sc_wmeParams); i++)
8003                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8004                     bwn_wme_shm_offsets[i]);
8005         bwn_mac_enable(mac);
8006 }
8007
8008 static void
8009 bwn_wme_loadparams(struct bwn_mac *mac,
8010     const struct wmeParams *p, uint16_t shm_offset)
8011 {
8012 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8013         struct bwn_softc *sc = mac->mac_sc;
8014         uint16_t params[BWN_NR_WMEPARAMS];
8015         int slot, tmp;
8016         unsigned int i;
8017
8018         slot = BWN_READ_2(mac, BWN_RNG) &
8019             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8020
8021         memset(&params, 0, sizeof(params));
8022
8023         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8024             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8025             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8026
8027         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8028         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8029         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8030         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8031         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8032         params[BWN_WMEPARAM_BSLOTS] = slot;
8033         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8034
8035         for (i = 0; i < N(params); i++) {
8036                 if (i == BWN_WMEPARAM_STATUS) {
8037                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8038                             shm_offset + (i * 2));
8039                         tmp |= 0x100;
8040                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8041                             tmp);
8042                 } else {
8043                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8044                             params[i]);
8045                 }
8046         }
8047 }
8048
8049 static void
8050 bwn_mac_write_bssid(struct bwn_mac *mac)
8051 {
8052         struct bwn_softc *sc = mac->mac_sc;
8053         uint32_t tmp;
8054         int i;
8055         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8056
8057         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8058         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8059         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8060             IEEE80211_ADDR_LEN);
8061
8062         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8063                 tmp = (uint32_t) (mac_bssid[i + 0]);
8064                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8065                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8066                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8067                 bwn_ram_write(mac, 0x20 + i, tmp);
8068         }
8069 }
8070
8071 static void
8072 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8073     const uint8_t *macaddr)
8074 {
8075         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8076         uint16_t data;
8077
8078         if (!mac)
8079                 macaddr = zero;
8080
8081         offset |= 0x0020;
8082         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8083
8084         data = macaddr[0];
8085         data |= macaddr[1] << 8;
8086         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8087         data = macaddr[2];
8088         data |= macaddr[3] << 8;
8089         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8090         data = macaddr[4];
8091         data |= macaddr[5] << 8;
8092         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8093 }
8094
8095 static void
8096 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8097     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8098 {
8099         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8100         uint8_t per_sta_keys_start = 8;
8101
8102         if (BWN_SEC_NEWAPI(mac))
8103                 per_sta_keys_start = 4;
8104
8105         KASSERT(index < mac->mac_max_nr_keys,
8106             ("%s:%d: fail", __func__, __LINE__));
8107         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8108             ("%s:%d: fail", __func__, __LINE__));
8109
8110         if (index >= per_sta_keys_start)
8111                 bwn_key_macwrite(mac, index, NULL);
8112         if (key)
8113                 memcpy(buf, key, key_len);
8114         bwn_key_write(mac, index, algorithm, buf);
8115         if (index >= per_sta_keys_start)
8116                 bwn_key_macwrite(mac, index, mac_addr);
8117
8118         mac->mac_key[index].algorithm = algorithm;
8119 }
8120
8121 static void
8122 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8123 {
8124         struct bwn_softc *sc = mac->mac_sc;
8125         uint32_t addrtmp[2] = { 0, 0 };
8126         uint8_t start = 8;
8127
8128         if (BWN_SEC_NEWAPI(mac))
8129                 start = 4;
8130
8131         KASSERT(index >= start,
8132             ("%s:%d: fail", __func__, __LINE__));
8133         index -= start;
8134
8135         if (addr) {
8136                 addrtmp[0] = addr[0];
8137                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8138                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8139                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8140                 addrtmp[1] = addr[4];
8141                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8142         }
8143
8144         if (siba_get_revid(sc->sc_dev) >= 5) {
8145                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8146                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8147         } else {
8148                 if (index >= 8) {
8149                         bwn_shm_write_4(mac, BWN_SHARED,
8150                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8151                         bwn_shm_write_2(mac, BWN_SHARED,
8152                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8153                 }
8154         }
8155 }
8156
8157 static void
8158 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8159     const uint8_t *key)
8160 {
8161         unsigned int i;
8162         uint32_t offset;
8163         uint16_t kidx, value;
8164
8165         kidx = BWN_SEC_KEY2FW(mac, index);
8166         bwn_shm_write_2(mac, BWN_SHARED,
8167             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8168
8169         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8170         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8171                 value = key[i];
8172                 value |= (uint16_t)(key[i + 1]) << 8;
8173                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8174         }
8175 }
8176
8177 static void
8178 bwn_phy_exit(struct bwn_mac *mac)
8179 {
8180
8181         mac->mac_phy.rf_onoff(mac, 0);
8182         if (mac->mac_phy.exit != NULL)
8183                 mac->mac_phy.exit(mac);
8184 }
8185
8186 static void
8187 bwn_dma_free(struct bwn_mac *mac)
8188 {
8189         struct bwn_dma *dma;
8190
8191         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8192                 return;
8193         dma = &mac->mac_method.dma;
8194
8195         bwn_dma_ringfree(&dma->rx);
8196         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8197         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8198         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8199         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8200         bwn_dma_ringfree(&dma->mcast);
8201 }
8202
8203 static void
8204 bwn_core_stop(struct bwn_mac *mac)
8205 {
8206         struct bwn_softc *sc = mac->mac_sc;
8207
8208         BWN_ASSERT_LOCKED(sc);
8209
8210         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8211                 return;
8212
8213         callout_stop(&sc->sc_rfswitch_ch);
8214         callout_stop(&sc->sc_task_ch);
8215         callout_stop(&sc->sc_watchdog_ch);
8216         sc->sc_watchdog_timer = 0;
8217         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8218         BWN_READ_4(mac, BWN_INTR_MASK);
8219         bwn_mac_suspend(mac);
8220
8221         mac->mac_status = BWN_MAC_STATUS_INITED;
8222 }
8223
8224 static int
8225 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8226 {
8227         struct bwn_mac *up_dev = NULL;
8228         struct bwn_mac *down_dev;
8229         struct bwn_mac *mac;
8230         int err, status;
8231         uint8_t gmode;
8232
8233         BWN_ASSERT_LOCKED(sc);
8234
8235         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8236                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8237                     mac->mac_phy.supports_2ghz) {
8238                         up_dev = mac;
8239                         gmode = 1;
8240                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8241                     mac->mac_phy.supports_5ghz) {
8242                         up_dev = mac;
8243                         gmode = 0;
8244                 } else {
8245                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8246                         return (EINVAL);
8247                 }
8248                 if (up_dev != NULL)
8249                         break;
8250         }
8251         if (up_dev == NULL) {
8252                 device_printf(sc->sc_dev, "Could not find a device\n");
8253                 return (ENODEV);
8254         }
8255         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8256                 return (0);
8257
8258         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8259             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8260
8261         down_dev = sc->sc_curmac;
8262         status = down_dev->mac_status;
8263         if (status >= BWN_MAC_STATUS_STARTED)
8264                 bwn_core_stop(down_dev);
8265         if (status >= BWN_MAC_STATUS_INITED)
8266                 bwn_core_exit(down_dev);
8267
8268         if (down_dev != up_dev)
8269                 bwn_phy_reset(down_dev);
8270
8271         up_dev->mac_phy.gmode = gmode;
8272         if (status >= BWN_MAC_STATUS_INITED) {
8273                 err = bwn_core_init(up_dev);
8274                 if (err) {
8275                         device_printf(sc->sc_dev,
8276                             "fatal: failed to initialize for %s-GHz\n",
8277                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8278                         goto fail;
8279                 }
8280         }
8281         if (status >= BWN_MAC_STATUS_STARTED)
8282                 bwn_core_start(up_dev);
8283         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8284         sc->sc_curmac = up_dev;
8285
8286         return (0);
8287 fail:
8288         sc->sc_curmac = NULL;
8289         return (err);
8290 }
8291
8292 static void
8293 bwn_rf_turnon(struct bwn_mac *mac)
8294 {
8295
8296         bwn_mac_suspend(mac);
8297         mac->mac_phy.rf_onoff(mac, 1);
8298         mac->mac_phy.rf_on = 1;
8299         bwn_mac_enable(mac);
8300 }
8301
8302 static void
8303 bwn_rf_turnoff(struct bwn_mac *mac)
8304 {
8305
8306         bwn_mac_suspend(mac);
8307         mac->mac_phy.rf_onoff(mac, 0);
8308         mac->mac_phy.rf_on = 0;
8309         bwn_mac_enable(mac);
8310 }
8311
8312 static void
8313 bwn_phy_reset(struct bwn_mac *mac)
8314 {
8315         struct bwn_softc *sc = mac->mac_sc;
8316
8317         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8318             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8319              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8320         DELAY(1000);
8321         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8322             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8323             BWN_TGSLOW_PHYRESET);
8324         DELAY(1000);
8325 }
8326
8327 static int
8328 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8329 {
8330         struct bwn_vap *bvp = BWN_VAP(vap);
8331         struct ieee80211com *ic= vap->iv_ic;
8332         struct ifnet *ifp = ic->ic_ifp;
8333         enum ieee80211_state ostate = vap->iv_state;
8334         struct bwn_softc *sc = ifp->if_softc;
8335         struct bwn_mac *mac = sc->sc_curmac;
8336         int error;
8337
8338         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8339             ieee80211_state_name[vap->iv_state],
8340             ieee80211_state_name[nstate]);
8341
8342         error = bvp->bv_newstate(vap, nstate, arg);
8343         if (error != 0)
8344                 return (error);
8345
8346         BWN_LOCK(sc);
8347
8348         bwn_led_newstate(mac, nstate);
8349
8350         /*
8351          * Clear the BSSID when we stop a STA
8352          */
8353         if (vap->iv_opmode == IEEE80211_M_STA) {
8354                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8355                         /*
8356                          * Clear out the BSSID.  If we reassociate to
8357                          * the same AP, this will reinialize things
8358                          * correctly...
8359                          */
8360                         if (ic->ic_opmode == IEEE80211_M_STA &&
8361                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8362                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8363                                 bwn_set_macaddr(mac);
8364                         }
8365                 }
8366         }
8367
8368         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8369             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8370                 /* XXX nothing to do? */
8371         } else if (nstate == IEEE80211_S_RUN) {
8372                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8373                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8374                 bwn_set_opmode(mac);
8375                 bwn_set_pretbtt(mac);
8376                 bwn_spu_setdelay(mac, 0);
8377                 bwn_set_macaddr(mac);
8378         }
8379
8380         BWN_UNLOCK(sc);
8381
8382         return (error);
8383 }
8384
8385 static void
8386 bwn_set_pretbtt(struct bwn_mac *mac)
8387 {
8388         struct bwn_softc *sc = mac->mac_sc;
8389         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8390         uint16_t pretbtt;
8391
8392         if (ic->ic_opmode == IEEE80211_M_IBSS)
8393                 pretbtt = 2;
8394         else
8395                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8396         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8397         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8398 }
8399
8400 static int
8401 bwn_intr(void *arg)
8402 {
8403         struct bwn_mac *mac = arg;
8404         struct bwn_softc *sc = mac->mac_sc;
8405         uint32_t reason;
8406
8407         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8408             (sc->sc_flags & BWN_FLAG_INVALID))
8409                 return (FILTER_STRAY);
8410
8411         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8412         if (reason == 0xffffffff)       /* shared IRQ */
8413                 return (FILTER_STRAY);
8414         reason &= mac->mac_intr_mask;
8415         if (reason == 0)
8416                 return (FILTER_HANDLED);
8417
8418         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8419         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8420         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8421         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8422         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8423         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8424         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8425         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8426         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8427         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8428         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8429
8430         /* Disable interrupts. */
8431         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8432
8433         mac->mac_reason_intr = reason;
8434
8435         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8436         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8437
8438         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8439         return (FILTER_HANDLED);
8440 }
8441
8442 static void
8443 bwn_intrtask(void *arg, int npending)
8444 {
8445         struct bwn_mac *mac = arg;
8446         struct bwn_softc *sc = mac->mac_sc;
8447         struct ifnet *ifp = sc->sc_ifp;
8448         uint32_t merged = 0;
8449         int i, tx = 0, rx = 0;
8450
8451         BWN_LOCK(sc);
8452         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8453             (sc->sc_flags & BWN_FLAG_INVALID)) {
8454                 BWN_UNLOCK(sc);
8455                 return;
8456         }
8457
8458         for (i = 0; i < N(mac->mac_reason); i++)
8459                 merged |= mac->mac_reason[i];
8460
8461         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8462                 device_printf(sc->sc_dev, "MAC trans error\n");
8463
8464         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8465                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8466                 mac->mac_phy.txerrors--;
8467                 if (mac->mac_phy.txerrors == 0) {
8468                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8469                         bwn_restart(mac, "PHY TX errors");
8470                 }
8471         }
8472
8473         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8474                 if (merged & BWN_DMAINTR_FATALMASK) {
8475                         device_printf(sc->sc_dev,
8476                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8477                             mac->mac_reason[0], mac->mac_reason[1],
8478                             mac->mac_reason[2], mac->mac_reason[3],
8479                             mac->mac_reason[4], mac->mac_reason[5]);
8480                         bwn_restart(mac, "DMA error");
8481                         BWN_UNLOCK(sc);
8482                         return;
8483                 }
8484                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8485                         device_printf(sc->sc_dev,
8486                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8487                             mac->mac_reason[0], mac->mac_reason[1],
8488                             mac->mac_reason[2], mac->mac_reason[3],
8489                             mac->mac_reason[4], mac->mac_reason[5]);
8490                 }
8491         }
8492
8493         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8494                 bwn_intr_ucode_debug(mac);
8495         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8496                 bwn_intr_tbtt_indication(mac);
8497         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8498                 bwn_intr_atim_end(mac);
8499         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8500                 bwn_intr_beacon(mac);
8501         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8502                 bwn_intr_pmq(mac);
8503         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8504                 bwn_intr_noise(mac);
8505
8506         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8507                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8508                         bwn_dma_rx(mac->mac_method.dma.rx);
8509                         rx = 1;
8510                 }
8511         } else
8512                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8513
8514         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8515         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8519
8520         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8521                 bwn_intr_txeof(mac);
8522                 tx = 1;
8523         }
8524
8525         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8526
8527         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8528                 int evt = BWN_LED_EVENT_NONE;
8529
8530                 if (tx && rx) {
8531                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8532                                 evt = BWN_LED_EVENT_RX;
8533                         else
8534                                 evt = BWN_LED_EVENT_TX;
8535                 } else if (tx) {
8536                         evt = BWN_LED_EVENT_TX;
8537                 } else if (rx) {
8538                         evt = BWN_LED_EVENT_RX;
8539                 } else if (rx == 0) {
8540                         evt = BWN_LED_EVENT_POLL;
8541                 }
8542
8543                 if (evt != BWN_LED_EVENT_NONE)
8544                         bwn_led_event(mac, evt);
8545        }
8546
8547         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8548                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8549                         bwn_start_locked(ifp);
8550         }
8551
8552         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8553         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8554
8555         BWN_UNLOCK(sc);
8556 }
8557
8558 static void
8559 bwn_restart(struct bwn_mac *mac, const char *msg)
8560 {
8561         struct bwn_softc *sc = mac->mac_sc;
8562         struct ifnet *ifp = sc->sc_ifp;
8563         struct ieee80211com *ic = ifp->if_l2com;
8564
8565         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8566                 return;
8567
8568         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8569         ieee80211_runtask(ic, &mac->mac_hwreset);
8570 }
8571
8572 static void
8573 bwn_intr_ucode_debug(struct bwn_mac *mac)
8574 {
8575         struct bwn_softc *sc = mac->mac_sc;
8576         uint16_t reason;
8577
8578         if (mac->mac_fw.opensource == 0)
8579                 return;
8580
8581         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8582         switch (reason) {
8583         case BWN_DEBUGINTR_PANIC:
8584                 bwn_handle_fwpanic(mac);
8585                 break;
8586         case BWN_DEBUGINTR_DUMP_SHM:
8587                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8588                 break;
8589         case BWN_DEBUGINTR_DUMP_REGS:
8590                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8591                 break;
8592         case BWN_DEBUGINTR_MARKER:
8593                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8594                 break;
8595         default:
8596                 device_printf(sc->sc_dev,
8597                     "ucode debug unknown reason: %#x\n", reason);
8598         }
8599
8600         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8601             BWN_DEBUGINTR_ACK);
8602 }
8603
8604 static void
8605 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8606 {
8607         struct bwn_softc *sc = mac->mac_sc;
8608         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8609
8610         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8611                 bwn_psctl(mac, 0);
8612         if (ic->ic_opmode == IEEE80211_M_IBSS)
8613                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8614 }
8615
8616 static void
8617 bwn_intr_atim_end(struct bwn_mac *mac)
8618 {
8619
8620         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8621                 BWN_WRITE_4(mac, BWN_MACCMD,
8622                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8623                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8624         }
8625 }
8626
8627 static void
8628 bwn_intr_beacon(struct bwn_mac *mac)
8629 {
8630         struct bwn_softc *sc = mac->mac_sc;
8631         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8632         uint32_t cmd, beacon0, beacon1;
8633
8634         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8635             ic->ic_opmode == IEEE80211_M_MBSS)
8636                 return;
8637
8638         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8639
8640         cmd = BWN_READ_4(mac, BWN_MACCMD);
8641         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8642         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8643
8644         if (beacon0 && beacon1) {
8645                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8646                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8647                 return;
8648         }
8649
8650         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8651                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8652                 bwn_load_beacon0(mac);
8653                 bwn_load_beacon1(mac);
8654                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8655                 cmd |= BWN_MACCMD_BEACON0_VALID;
8656                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8657         } else {
8658                 if (!beacon0) {
8659                         bwn_load_beacon0(mac);
8660                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8661                         cmd |= BWN_MACCMD_BEACON0_VALID;
8662                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8663                 } else if (!beacon1) {
8664                         bwn_load_beacon1(mac);
8665                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8666                         cmd |= BWN_MACCMD_BEACON1_VALID;
8667                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8668                 }
8669         }
8670 }
8671
8672 static void
8673 bwn_intr_pmq(struct bwn_mac *mac)
8674 {
8675         uint32_t tmp;
8676
8677         while (1) {
8678                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8679                 if (!(tmp & 0x00000008))
8680                         break;
8681         }
8682         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8683 }
8684
8685 static void
8686 bwn_intr_noise(struct bwn_mac *mac)
8687 {
8688         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8689         uint16_t tmp;
8690         uint8_t noise[4];
8691         uint8_t i, j;
8692         int32_t average;
8693
8694         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8695                 return;
8696
8697         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8698         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8699         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8700             noise[3] == 0x7f)
8701                 goto new;
8702
8703         KASSERT(mac->mac_noise.noi_nsamples < 8,
8704             ("%s:%d: fail", __func__, __LINE__));
8705         i = mac->mac_noise.noi_nsamples;
8706         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8707         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8708         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8709         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8710         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8711         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8712         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8713         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8714         mac->mac_noise.noi_nsamples++;
8715         if (mac->mac_noise.noi_nsamples == 8) {
8716                 average = 0;
8717                 for (i = 0; i < 8; i++) {
8718                         for (j = 0; j < 4; j++)
8719                                 average += mac->mac_noise.noi_samples[i][j];
8720                 }
8721                 average = (((average / 32) * 125) + 64) / 128;
8722                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8723                 if (tmp >= 8)
8724                         average += 2;
8725                 else
8726                         average -= 25;
8727                 average -= (tmp == 8) ? 72 : 48;
8728
8729                 mac->mac_stats.link_noise = average;
8730                 mac->mac_noise.noi_running = 0;
8731                 return;
8732         }
8733 new:
8734         bwn_noise_gensample(mac);
8735 }
8736
8737 static int
8738 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8739 {
8740         struct bwn_mac *mac = prq->prq_mac;
8741         struct bwn_softc *sc = mac->mac_sc;
8742         unsigned int i;
8743
8744         BWN_ASSERT_LOCKED(sc);
8745
8746         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8747                 return (0);
8748
8749         for (i = 0; i < 5000; i++) {
8750                 if (bwn_pio_rxeof(prq) == 0)
8751                         break;
8752         }
8753         if (i >= 5000)
8754                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8755         return ((i > 0) ? 1 : 0);
8756 }
8757
8758 static void
8759 bwn_dma_rx(struct bwn_dma_ring *dr)
8760 {
8761         int slot, curslot;
8762
8763         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8764         curslot = dr->get_curslot(dr);
8765         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8766             ("%s:%d: fail", __func__, __LINE__));
8767
8768         slot = dr->dr_curslot;
8769         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8770                 bwn_dma_rxeof(dr, &slot);
8771
8772         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8773             BUS_DMASYNC_PREWRITE);
8774
8775         dr->set_curslot(dr, slot);
8776         dr->dr_curslot = slot;
8777 }
8778
8779 static void
8780 bwn_intr_txeof(struct bwn_mac *mac)
8781 {
8782         struct bwn_txstatus stat;
8783         uint32_t stat0, stat1;
8784         uint16_t tmp;
8785
8786         BWN_ASSERT_LOCKED(mac->mac_sc);
8787
8788         while (1) {
8789                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8790                 if (!(stat0 & 0x00000001))
8791                         break;
8792                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8793
8794                 stat.cookie = (stat0 >> 16);
8795                 stat.seq = (stat1 & 0x0000ffff);
8796                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8797                 tmp = (stat0 & 0x0000ffff);
8798                 stat.framecnt = ((tmp & 0xf000) >> 12);
8799                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8800                 stat.sreason = ((tmp & 0x001c) >> 2);
8801                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8802                 stat.im = (tmp & 0x0040) ? 1 : 0;
8803                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8804                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8805
8806                 bwn_handle_txeof(mac, &stat);
8807         }
8808 }
8809
8810 static void
8811 bwn_hwreset(void *arg, int npending)
8812 {
8813         struct bwn_mac *mac = arg;
8814         struct bwn_softc *sc = mac->mac_sc;
8815         int error = 0;
8816         int prev_status;
8817
8818         BWN_LOCK(sc);
8819
8820         prev_status = mac->mac_status;
8821         if (prev_status >= BWN_MAC_STATUS_STARTED)
8822                 bwn_core_stop(mac);
8823         if (prev_status >= BWN_MAC_STATUS_INITED)
8824                 bwn_core_exit(mac);
8825
8826         if (prev_status >= BWN_MAC_STATUS_INITED) {
8827                 error = bwn_core_init(mac);
8828                 if (error)
8829                         goto out;
8830         }
8831         if (prev_status >= BWN_MAC_STATUS_STARTED)
8832                 bwn_core_start(mac);
8833 out:
8834         if (error) {
8835                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8836                 sc->sc_curmac = NULL;
8837         }
8838         BWN_UNLOCK(sc);
8839 }
8840
8841 static void
8842 bwn_handle_fwpanic(struct bwn_mac *mac)
8843 {
8844         struct bwn_softc *sc = mac->mac_sc;
8845         uint16_t reason;
8846
8847         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8848         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8849
8850         if (reason == BWN_FWPANIC_RESTART)
8851                 bwn_restart(mac, "ucode panic");
8852 }
8853
8854 static void
8855 bwn_load_beacon0(struct bwn_mac *mac)
8856 {
8857
8858         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8859 }
8860
8861 static void
8862 bwn_load_beacon1(struct bwn_mac *mac)
8863 {
8864
8865         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8866 }
8867
8868 static uint32_t
8869 bwn_jssi_read(struct bwn_mac *mac)
8870 {
8871         uint32_t val = 0;
8872
8873         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8874         val <<= 16;
8875         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8876
8877         return (val);
8878 }
8879
8880 static void
8881 bwn_noise_gensample(struct bwn_mac *mac)
8882 {
8883         uint32_t jssi = 0x7f7f7f7f;
8884
8885         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8886         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8887         BWN_WRITE_4(mac, BWN_MACCMD,
8888             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8889 }
8890
8891 static int
8892 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8893 {
8894         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8895
8896         return (dr->dr_numslots - dr->dr_usedslot);
8897 }
8898
8899 static int
8900 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8901 {
8902         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8903
8904         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8905             ("%s:%d: fail", __func__, __LINE__));
8906         if (slot == dr->dr_numslots - 1)
8907                 return (0);
8908         return (slot + 1);
8909 }
8910
8911 static void
8912 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8913 {
8914         struct bwn_mac *mac = dr->dr_mac;
8915         struct bwn_softc *sc = mac->mac_sc;
8916         struct bwn_dma *dma = &mac->mac_method.dma;
8917         struct bwn_dmadesc_generic *desc;
8918         struct bwn_dmadesc_meta *meta;
8919         struct bwn_rxhdr4 *rxhdr;
8920         struct ifnet *ifp = sc->sc_ifp;
8921         struct mbuf *m;
8922         uint32_t macstat;
8923         int32_t tmp;
8924         int cnt = 0;
8925         uint16_t len;
8926
8927         dr->getdesc(dr, *slot, &desc, &meta);
8928
8929         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8930         m = meta->mt_m;
8931
8932         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8933                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8934                 return;
8935         }
8936
8937         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8938         len = le16toh(rxhdr->frame_len);
8939         if (len <= 0) {
8940                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8941                 return;
8942         }
8943         if (bwn_dma_check_redzone(dr, m)) {
8944                 device_printf(sc->sc_dev, "redzone error.\n");
8945                 bwn_dma_set_redzone(dr, m);
8946                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8947                     BUS_DMASYNC_PREWRITE);
8948                 return;
8949         }
8950         if (len > dr->dr_rx_bufsize) {
8951                 tmp = len;
8952                 while (1) {
8953                         dr->getdesc(dr, *slot, &desc, &meta);
8954                         bwn_dma_set_redzone(dr, meta->mt_m);
8955                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8956                             BUS_DMASYNC_PREWRITE);
8957                         *slot = bwn_dma_nextslot(dr, *slot);
8958                         cnt++;
8959                         tmp -= dr->dr_rx_bufsize;
8960                         if (tmp <= 0)
8961                                 break;
8962                 }
8963                 device_printf(sc->sc_dev, "too small buffer "
8964                        "(len %u buffer %u dropped %d)\n",
8965                        len, dr->dr_rx_bufsize, cnt);
8966                 return;
8967         }
8968         macstat = le32toh(rxhdr->mac_status);
8969         if (macstat & BWN_RX_MAC_FCSERR) {
8970                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8971                         device_printf(sc->sc_dev, "RX drop\n");
8972                         return;
8973                 }
8974         }
8975
8976         m->m_pkthdr.rcvif = ifp;
8977         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8978         m_adj(m, dr->dr_frameoffset);
8979
8980         bwn_rxeof(dr->dr_mac, m, rxhdr);
8981 }
8982
8983 static void
8984 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8985 {
8986         struct bwn_dma_ring *dr;
8987         struct bwn_dmadesc_generic *desc;
8988         struct bwn_dmadesc_meta *meta;
8989         struct bwn_pio_txqueue *tq;
8990         struct bwn_pio_txpkt *tp = NULL;
8991         struct bwn_softc *sc = mac->mac_sc;
8992         struct bwn_stats *stats = &mac->mac_stats;
8993         struct ieee80211_node *ni;
8994         struct ieee80211vap *vap;
8995         int retrycnt = 0, slot;
8996
8997         BWN_ASSERT_LOCKED(mac->mac_sc);
8998
8999         if (status->im)
9000                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9001         if (status->ampdu)
9002                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9003         if (status->rtscnt) {
9004                 if (status->rtscnt == 0xf)
9005                         stats->rtsfail++;
9006                 else
9007                         stats->rts++;
9008         }
9009
9010         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9011                 if (status->ack) {
9012                         dr = bwn_dma_parse_cookie(mac, status,
9013                             status->cookie, &slot);
9014                         if (dr == NULL) {
9015                                 device_printf(sc->sc_dev,
9016                                     "failed to parse cookie\n");
9017                                 return;
9018                         }
9019                         while (1) {
9020                                 dr->getdesc(dr, slot, &desc, &meta);
9021                                 if (meta->mt_islast) {
9022                                         ni = meta->mt_ni;
9023                                         vap = ni->ni_vap;
9024                                         ieee80211_ratectl_tx_complete(vap, ni,
9025                                             status->ack ?
9026                                               IEEE80211_RATECTL_TX_SUCCESS :
9027                                               IEEE80211_RATECTL_TX_FAILURE,
9028                                             &retrycnt, 0);
9029                                         break;
9030                                 }
9031                                 slot = bwn_dma_nextslot(dr, slot);
9032                         }
9033                 }
9034                 bwn_dma_handle_txeof(mac, status);
9035         } else {
9036                 if (status->ack) {
9037                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9038                         if (tq == NULL) {
9039                                 device_printf(sc->sc_dev,
9040                                     "failed to parse cookie\n");
9041                                 return;
9042                         }
9043                         ni = tp->tp_ni;
9044                         vap = ni->ni_vap;
9045                         ieee80211_ratectl_tx_complete(vap, ni,
9046                             status->ack ?
9047                               IEEE80211_RATECTL_TX_SUCCESS :
9048                               IEEE80211_RATECTL_TX_FAILURE,
9049                             &retrycnt, 0);
9050                 }
9051                 bwn_pio_handle_txeof(mac, status);
9052         }
9053
9054         bwn_phy_txpower_check(mac, 0);
9055 }
9056
9057 static uint8_t
9058 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9059 {
9060         struct bwn_mac *mac = prq->prq_mac;
9061         struct bwn_softc *sc = mac->mac_sc;
9062         struct bwn_rxhdr4 rxhdr;
9063         struct ifnet *ifp = sc->sc_ifp;
9064         struct mbuf *m;
9065         uint32_t ctl32, macstat, v32;
9066         unsigned int i, padding;
9067         uint16_t ctl16, len, totlen, v16;
9068         unsigned char *mp;
9069         char *data;
9070
9071         memset(&rxhdr, 0, sizeof(rxhdr));
9072
9073         if (prq->prq_rev >= 8) {
9074                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9075                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9076                         return (0);
9077                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9078                     BWN_PIO8_RXCTL_FRAMEREADY);
9079                 for (i = 0; i < 10; i++) {
9080                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9081                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9082                                 goto ready;
9083                         DELAY(10);
9084                 }
9085         } else {
9086                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9087                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9088                         return (0);
9089                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9090                     BWN_PIO_RXCTL_FRAMEREADY);
9091                 for (i = 0; i < 10; i++) {
9092                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9093                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9094                                 goto ready;
9095                         DELAY(10);
9096                 }
9097         }
9098         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9099         return (1);
9100 ready:
9101         if (prq->prq_rev >= 8)
9102                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9103                     prq->prq_base + BWN_PIO8_RXDATA);
9104         else
9105                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9106                     prq->prq_base + BWN_PIO_RXDATA);
9107         len = le16toh(rxhdr.frame_len);
9108         if (len > 0x700) {
9109                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9110                 goto error;
9111         }
9112         if (len == 0) {
9113                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9114                 goto error;
9115         }
9116
9117         macstat = le32toh(rxhdr.mac_status);
9118         if (macstat & BWN_RX_MAC_FCSERR) {
9119                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9120                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9121                         goto error;
9122                 }
9123         }
9124
9125         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9126         totlen = len + padding;
9127         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9128         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9129         if (m == NULL) {
9130                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9131                 goto error;
9132         }
9133         mp = mtod(m, unsigned char *);
9134         if (prq->prq_rev >= 8) {
9135                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9136                     prq->prq_base + BWN_PIO8_RXDATA);
9137                 if (totlen & 3) {
9138                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9139                         data = &(mp[totlen - 1]);
9140                         switch (totlen & 3) {
9141                         case 3:
9142                                 *data = (v32 >> 16);
9143                                 data--;
9144                         case 2:
9145                                 *data = (v32 >> 8);
9146                                 data--;
9147                         case 1:
9148                                 *data = v32;
9149                         }
9150                 }
9151         } else {
9152                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9153                     prq->prq_base + BWN_PIO_RXDATA);
9154                 if (totlen & 1) {
9155                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9156                         mp[totlen - 1] = v16;
9157                 }
9158         }
9159
9160         m->m_pkthdr.rcvif = ifp;
9161         m->m_len = m->m_pkthdr.len = totlen;
9162
9163         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9164
9165         return (1);
9166 error:
9167         if (prq->prq_rev >= 8)
9168                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9169                     BWN_PIO8_RXCTL_DATAREADY);
9170         else
9171                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9172         return (1);
9173 }
9174
9175 static int
9176 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9177     struct bwn_dmadesc_meta *meta, int init)
9178 {
9179         struct bwn_mac *mac = dr->dr_mac;
9180         struct bwn_dma *dma = &mac->mac_method.dma;
9181         struct bwn_rxhdr4 *hdr;
9182         bus_dmamap_t map;
9183         bus_addr_t paddr;
9184         struct mbuf *m;
9185         int error;
9186
9187         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9188         if (m == NULL) {
9189                 error = ENOBUFS;
9190
9191                 /*
9192                  * If the NIC is up and running, we need to:
9193                  * - Clear RX buffer's header.
9194                  * - Restore RX descriptor settings.
9195                  */
9196                 if (init)
9197                         return (error);
9198                 else
9199                         goto back;
9200         }
9201         m->m_len = m->m_pkthdr.len = MCLBYTES;
9202
9203         bwn_dma_set_redzone(dr, m);
9204
9205         /*
9206          * Try to load RX buf into temporary DMA map
9207          */
9208         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9209             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9210         if (error) {
9211                 m_freem(m);
9212
9213                 /*
9214                  * See the comment above
9215                  */
9216                 if (init)
9217                         return (error);
9218                 else
9219                         goto back;
9220         }
9221
9222         if (!init)
9223                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9224         meta->mt_m = m;
9225         meta->mt_paddr = paddr;
9226
9227         /*
9228          * Swap RX buf's DMA map with the loaded temporary one
9229          */
9230         map = meta->mt_dmap;
9231         meta->mt_dmap = dr->dr_spare_dmap;
9232         dr->dr_spare_dmap = map;
9233
9234 back:
9235         /*
9236          * Clear RX buf header
9237          */
9238         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9239         bzero(hdr, sizeof(*hdr));
9240         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9241             BUS_DMASYNC_PREWRITE);
9242
9243         /*
9244          * Setup RX buf descriptor
9245          */
9246         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9247             sizeof(*hdr), 0, 0, 0);
9248         return (error);
9249 }
9250
9251 static void
9252 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9253                  bus_size_t mapsz __unused, int error)
9254 {
9255
9256         if (!error) {
9257                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9258                 *((bus_addr_t *)arg) = seg->ds_addr;
9259         }
9260 }
9261
9262 static int
9263 bwn_hwrate2ieeerate(int rate)
9264 {
9265
9266         switch (rate) {
9267         case BWN_CCK_RATE_1MB:
9268                 return (2);
9269         case BWN_CCK_RATE_2MB:
9270                 return (4);
9271         case BWN_CCK_RATE_5MB:
9272                 return (11);
9273         case BWN_CCK_RATE_11MB:
9274                 return (22);
9275         case BWN_OFDM_RATE_6MB:
9276                 return (12);
9277         case BWN_OFDM_RATE_9MB:
9278                 return (18);
9279         case BWN_OFDM_RATE_12MB:
9280                 return (24);
9281         case BWN_OFDM_RATE_18MB:
9282                 return (36);
9283         case BWN_OFDM_RATE_24MB:
9284                 return (48);
9285         case BWN_OFDM_RATE_36MB:
9286                 return (72);
9287         case BWN_OFDM_RATE_48MB:
9288                 return (96);
9289         case BWN_OFDM_RATE_54MB:
9290                 return (108);
9291         default:
9292                 printf("Ooops\n");
9293                 return (0);
9294         }
9295 }
9296
9297 static void
9298 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9299 {
9300         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9301         struct bwn_plcp6 *plcp;
9302         struct bwn_softc *sc = mac->mac_sc;
9303         struct ieee80211_frame_min *wh;
9304         struct ieee80211_node *ni;
9305         struct ifnet *ifp = sc->sc_ifp;
9306         struct ieee80211com *ic = ifp->if_l2com;
9307         uint32_t macstat;
9308         int padding, rate, rssi = 0, noise = 0, type;
9309         uint16_t phytype, phystat0, phystat3, chanstat;
9310         unsigned char *mp = mtod(m, unsigned char *);
9311         static int rx_mac_dec_rpt = 0;
9312
9313         BWN_ASSERT_LOCKED(sc);
9314
9315         phystat0 = le16toh(rxhdr->phy_status0);
9316         phystat3 = le16toh(rxhdr->phy_status3);
9317         macstat = le32toh(rxhdr->mac_status);
9318         chanstat = le16toh(rxhdr->channel);
9319         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9320
9321         if (macstat & BWN_RX_MAC_FCSERR)
9322                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9323         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9324                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9325         if (macstat & BWN_RX_MAC_DECERR)
9326                 goto drop;
9327
9328         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9329         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9330                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9331                     m->m_pkthdr.len);
9332                 goto drop;
9333         }
9334         plcp = (struct bwn_plcp6 *)(mp + padding);
9335         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9336         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9337                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9338                     m->m_pkthdr.len);
9339                 goto drop;
9340         }
9341         wh = mtod(m, struct ieee80211_frame_min *);
9342
9343         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9344                 device_printf(sc->sc_dev,
9345                     "RX decryption attempted (old %d keyidx %#x)\n",
9346                     BWN_ISOLDFMT(mac),
9347                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9348
9349         /* XXX calculating RSSI & noise & antenna */
9350
9351         if (phystat0 & BWN_RX_PHYST0_OFDM)
9352                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9353                     phytype == BWN_PHYTYPE_A);
9354         else
9355                 rate = bwn_plcp_get_cckrate(mac, plcp);
9356         if (rate == -1) {
9357                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9358                         goto drop;
9359         }
9360         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9361
9362         /* RX radio tap */
9363         if (ieee80211_radiotap_active(ic))
9364                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9365         m_adj(m, -IEEE80211_CRC_LEN);
9366
9367         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9368         noise = mac->mac_stats.link_noise;
9369
9370         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
9371
9372         BWN_UNLOCK(sc);
9373
9374         ni = ieee80211_find_rxnode(ic, wh);
9375         if (ni != NULL) {
9376                 type = ieee80211_input(ni, m, rssi, noise);
9377                 ieee80211_free_node(ni);
9378         } else
9379                 type = ieee80211_input_all(ic, m, rssi, noise);
9380
9381         BWN_LOCK(sc);
9382         return;
9383 drop:
9384         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9385 }
9386
9387 static void
9388 bwn_dma_handle_txeof(struct bwn_mac *mac,
9389     const struct bwn_txstatus *status)
9390 {
9391         struct bwn_dma *dma = &mac->mac_method.dma;
9392         struct bwn_dma_ring *dr;
9393         struct bwn_dmadesc_generic *desc;
9394         struct bwn_dmadesc_meta *meta;
9395         struct bwn_softc *sc = mac->mac_sc;
9396         struct ieee80211_node *ni;
9397         struct ifnet *ifp = sc->sc_ifp;
9398         struct mbuf *m;
9399         int slot;
9400
9401         BWN_ASSERT_LOCKED(sc);
9402
9403         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9404         if (dr == NULL) {
9405                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9406                 return;
9407         }
9408         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9409
9410         while (1) {
9411                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9412                     ("%s:%d: fail", __func__, __LINE__));
9413                 dr->getdesc(dr, slot, &desc, &meta);
9414
9415                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9416                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9417                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9418                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9419
9420                 if (meta->mt_islast) {
9421                         KASSERT(meta->mt_m != NULL,
9422                             ("%s:%d: fail", __func__, __LINE__));
9423
9424                         ni = meta->mt_ni;
9425                         m = meta->mt_m;
9426                         if (ni != NULL) {
9427                                 /*
9428                                  * Do any tx complete callback. Note this must
9429                                  * be done before releasing the node reference.
9430                                  */
9431                                 if (m->m_flags & M_TXCB)
9432                                         ieee80211_process_callback(ni, m, 0);
9433                                 ieee80211_free_node(ni);
9434                                 meta->mt_ni = NULL;
9435                         }
9436                         m_freem(m);
9437                         meta->mt_m = NULL;
9438                 } else {
9439                         KASSERT(meta->mt_m == NULL,
9440                             ("%s:%d: fail", __func__, __LINE__));
9441                 }
9442
9443                 dr->dr_usedslot--;
9444                 if (meta->mt_islast) {
9445                         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9446                         break;
9447                 }
9448                 slot = bwn_dma_nextslot(dr, slot);
9449         }
9450         sc->sc_watchdog_timer = 0;
9451         if (dr->dr_stop) {
9452                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9453                     ("%s:%d: fail", __func__, __LINE__));
9454                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9455                 dr->dr_stop = 0;
9456         }
9457 }
9458
9459 static void
9460 bwn_pio_handle_txeof(struct bwn_mac *mac,
9461     const struct bwn_txstatus *status)
9462 {
9463         struct bwn_pio_txqueue *tq;
9464         struct bwn_pio_txpkt *tp = NULL;
9465         struct bwn_softc *sc = mac->mac_sc;
9466         struct ifnet *ifp = sc->sc_ifp;
9467
9468         BWN_ASSERT_LOCKED(sc);
9469
9470         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9471         if (tq == NULL)
9472                 return;
9473
9474         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9475         tq->tq_free++;
9476
9477         if (tp->tp_ni != NULL) {
9478                 /*
9479                  * Do any tx complete callback.  Note this must
9480                  * be done before releasing the node reference.
9481                  */
9482                 if (tp->tp_m->m_flags & M_TXCB)
9483                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9484                 ieee80211_free_node(tp->tp_ni);
9485                 tp->tp_ni = NULL;
9486         }
9487         m_freem(tp->tp_m);
9488         tp->tp_m = NULL;
9489         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9490
9491         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9492
9493         sc->sc_watchdog_timer = 0;
9494         if (tq->tq_stop) {
9495                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9496                 tq->tq_stop = 0;
9497         }
9498 }
9499
9500 static void
9501 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9502 {
9503         struct bwn_softc *sc = mac->mac_sc;
9504         struct bwn_phy *phy = &mac->mac_phy;
9505         struct ifnet *ifp = sc->sc_ifp;
9506         struct ieee80211com *ic = ifp->if_l2com;
9507         unsigned long now;
9508         int result;
9509
9510         BWN_GETTIME(now);
9511
9512         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9513                 return;
9514         phy->nexttime = now + 2 * 1000;
9515
9516         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9517             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9518                 return;
9519
9520         if (phy->recalc_txpwr != NULL) {
9521                 result = phy->recalc_txpwr(mac,
9522                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9523                 if (result == BWN_TXPWR_RES_DONE)
9524                         return;
9525                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9526                     ("%s: fail", __func__));
9527                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9528
9529                 ieee80211_runtask(ic, &mac->mac_txpower);
9530         }
9531 }
9532
9533 static uint16_t
9534 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9535 {
9536
9537         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9538 }
9539
9540 static uint32_t
9541 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9542 {
9543
9544         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9545 }
9546
9547 static void
9548 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9549 {
9550
9551         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9552 }
9553
9554 static void
9555 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9556 {
9557
9558         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9559 }
9560
9561 static int
9562 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9563 {
9564
9565         switch (rate) {
9566         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9567         case 12:
9568                 return (BWN_OFDM_RATE_6MB);
9569         case 18:
9570                 return (BWN_OFDM_RATE_9MB);
9571         case 24:
9572                 return (BWN_OFDM_RATE_12MB);
9573         case 36:
9574                 return (BWN_OFDM_RATE_18MB);
9575         case 48:
9576                 return (BWN_OFDM_RATE_24MB);
9577         case 72:
9578                 return (BWN_OFDM_RATE_36MB);
9579         case 96:
9580                 return (BWN_OFDM_RATE_48MB);
9581         case 108:
9582                 return (BWN_OFDM_RATE_54MB);
9583         /* CCK rates (NB: not IEEE std, device-specific) */
9584         case 2:
9585                 return (BWN_CCK_RATE_1MB);
9586         case 4:
9587                 return (BWN_CCK_RATE_2MB);
9588         case 11:
9589                 return (BWN_CCK_RATE_5MB);
9590         case 22:
9591                 return (BWN_CCK_RATE_11MB);
9592         }
9593
9594         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9595         return (BWN_CCK_RATE_1MB);
9596 }
9597
9598 static int
9599 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9600     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9601 {
9602         const struct bwn_phy *phy = &mac->mac_phy;
9603         struct bwn_softc *sc = mac->mac_sc;
9604         struct ieee80211_frame *wh;
9605         struct ieee80211_frame *protwh;
9606         struct ieee80211_frame_cts *cts;
9607         struct ieee80211_frame_rts *rts;
9608         const struct ieee80211_txparam *tp;
9609         struct ieee80211vap *vap = ni->ni_vap;
9610         struct ifnet *ifp = sc->sc_ifp;
9611         struct ieee80211com *ic = ifp->if_l2com;
9612         struct mbuf *mprot;
9613         unsigned int len;
9614         uint32_t macctl = 0;
9615         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9616         uint16_t phyctl = 0;
9617         uint8_t rate, rate_fb;
9618
9619         wh = mtod(m, struct ieee80211_frame *);
9620         memset(txhdr, 0, sizeof(*txhdr));
9621
9622         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9623         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9624         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9625
9626         /*
9627          * Find TX rate
9628          */
9629         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9630         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9631                 rate = rate_fb = tp->mgmtrate;
9632         else if (ismcast)
9633                 rate = rate_fb = tp->mcastrate;
9634         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9635                 rate = rate_fb = tp->ucastrate;
9636         else {
9637                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9638                 rate = ni->ni_txrate;
9639
9640                 if (rix > 0)
9641                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9642                             IEEE80211_RATE_VAL;
9643                 else
9644                         rate_fb = rate;
9645         }
9646
9647         sc->sc_tx_rate = rate;
9648
9649         rate = bwn_ieeerate2hwrate(sc, rate);
9650         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9651
9652         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9653             bwn_plcp_getcck(rate);
9654         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9655         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9656
9657         if ((rate_fb == rate) ||
9658             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9659             (*(u_int16_t *)wh->i_dur == htole16(0)))
9660                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9661         else
9662                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9663                     m->m_pkthdr.len, rate, isshort);
9664
9665         /* XXX TX encryption */
9666         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9667             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9668             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9669             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9670         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9671             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9672
9673         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9674             BWN_TX_EFT_FB_CCK;
9675         txhdr->chan = phy->chan;
9676         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9677             BWN_TX_PHY_ENC_CCK;
9678         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9679              rate == BWN_CCK_RATE_11MB))
9680                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9681
9682         /* XXX TX antenna selection */
9683
9684         switch (bwn_antenna_sanitize(mac, 0)) {
9685         case 0:
9686                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9687                 break;
9688         case 1:
9689                 phyctl |= BWN_TX_PHY_ANT0;
9690                 break;
9691         case 2:
9692                 phyctl |= BWN_TX_PHY_ANT1;
9693                 break;
9694         case 3:
9695                 phyctl |= BWN_TX_PHY_ANT2;
9696                 break;
9697         case 4:
9698                 phyctl |= BWN_TX_PHY_ANT3;
9699                 break;
9700         default:
9701                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9702         }
9703
9704         if (!ismcast)
9705                 macctl |= BWN_TX_MAC_ACK;
9706
9707         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9708         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9709             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9710                 macctl |= BWN_TX_MAC_LONGFRAME;
9711
9712         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9713                 /* XXX RTS rate is always 1MB??? */
9714                 rts_rate = BWN_CCK_RATE_1MB;
9715                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9716
9717                 protdur = ieee80211_compute_duration(ic->ic_rt,
9718                     m->m_pkthdr.len, rate, isshort) +
9719                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9720
9721                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9722                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9723                             (txhdr->body.old.rts_frame) :
9724                             (txhdr->body.new.rts_frame));
9725                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9726                             protdur);
9727                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9728                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9729                             mprot->m_pkthdr.len);
9730                         m_freem(mprot);
9731                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9732                         len = sizeof(struct ieee80211_frame_cts);
9733                 } else {
9734                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9735                             (txhdr->body.old.rts_frame) :
9736                             (txhdr->body.new.rts_frame));
9737                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9738                             isshort);
9739                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9740                             wh->i_addr2, protdur);
9741                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9742                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9743                             mprot->m_pkthdr.len);
9744                         m_freem(mprot);
9745                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9746                         len = sizeof(struct ieee80211_frame_rts);
9747                 }
9748                 len += IEEE80211_CRC_LEN;
9749                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9750                     &txhdr->body.old.rts_plcp :
9751                     &txhdr->body.new.rts_plcp), len, rts_rate);
9752                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9753                     rts_rate_fb);
9754
9755                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9756                     (&txhdr->body.old.rts_frame) :
9757                     (&txhdr->body.new.rts_frame));
9758                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9759
9760                 if (BWN_ISOFDMRATE(rts_rate)) {
9761                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9762                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9763                 } else {
9764                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9765                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9766                 }
9767                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9768                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9769         }
9770
9771         if (BWN_ISOLDFMT(mac))
9772                 txhdr->body.old.cookie = htole16(cookie);
9773         else
9774                 txhdr->body.new.cookie = htole16(cookie);
9775
9776         txhdr->macctl = htole32(macctl);
9777         txhdr->phyctl = htole16(phyctl);
9778
9779         /*
9780          * TX radio tap
9781          */
9782         if (ieee80211_radiotap_active_vap(vap)) {
9783                 sc->sc_tx_th.wt_flags = 0;
9784                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9785                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9786                 if (isshort &&
9787                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9788                      rate == BWN_CCK_RATE_11MB))
9789                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9790                 sc->sc_tx_th.wt_rate = rate;
9791
9792                 ieee80211_radiotap_tx(vap, m);
9793         }
9794
9795         return (0);
9796 }
9797
9798 static void
9799 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9800     const uint8_t rate)
9801 {
9802         uint32_t d, plen;
9803         uint8_t *raw = plcp->o.raw;
9804
9805         if (BWN_ISOFDMRATE(rate)) {
9806                 d = bwn_plcp_getofdm(rate);
9807                 KASSERT(!(octets & 0xf000),
9808                     ("%s:%d: fail", __func__, __LINE__));
9809                 d |= (octets << 5);
9810                 plcp->o.data = htole32(d);
9811         } else {
9812                 plen = octets * 16 / rate;
9813                 if ((octets * 16 % rate) > 0) {
9814                         plen++;
9815                         if ((rate == BWN_CCK_RATE_11MB)
9816                             && ((octets * 8 % 11) < 4)) {
9817                                 raw[1] = 0x84;
9818                         } else
9819                                 raw[1] = 0x04;
9820                 } else
9821                         raw[1] = 0x04;
9822                 plcp->o.data |= htole32(plen << 16);
9823                 raw[0] = bwn_plcp_getcck(rate);
9824         }
9825 }
9826
9827 static uint8_t
9828 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9829 {
9830         struct bwn_softc *sc = mac->mac_sc;
9831         uint8_t mask;
9832
9833         if (n == 0)
9834                 return (0);
9835         if (mac->mac_phy.gmode)
9836                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9837         else
9838                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9839         if (!(mask & (1 << (n - 1))))
9840                 return (0);
9841         return (n);
9842 }
9843
9844 static uint8_t
9845 bwn_get_fbrate(uint8_t bitrate)
9846 {
9847         switch (bitrate) {
9848         case BWN_CCK_RATE_1MB:
9849                 return (BWN_CCK_RATE_1MB);
9850         case BWN_CCK_RATE_2MB:
9851                 return (BWN_CCK_RATE_1MB);
9852         case BWN_CCK_RATE_5MB:
9853                 return (BWN_CCK_RATE_2MB);
9854         case BWN_CCK_RATE_11MB:
9855                 return (BWN_CCK_RATE_5MB);
9856         case BWN_OFDM_RATE_6MB:
9857                 return (BWN_CCK_RATE_5MB);
9858         case BWN_OFDM_RATE_9MB:
9859                 return (BWN_OFDM_RATE_6MB);
9860         case BWN_OFDM_RATE_12MB:
9861                 return (BWN_OFDM_RATE_9MB);
9862         case BWN_OFDM_RATE_18MB:
9863                 return (BWN_OFDM_RATE_12MB);
9864         case BWN_OFDM_RATE_24MB:
9865                 return (BWN_OFDM_RATE_18MB);
9866         case BWN_OFDM_RATE_36MB:
9867                 return (BWN_OFDM_RATE_24MB);
9868         case BWN_OFDM_RATE_48MB:
9869                 return (BWN_OFDM_RATE_36MB);
9870         case BWN_OFDM_RATE_54MB:
9871                 return (BWN_OFDM_RATE_48MB);
9872         }
9873         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9874         return (0);
9875 }
9876
9877 static uint32_t
9878 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9879     uint32_t ctl, const void *_data, int len)
9880 {
9881         struct bwn_softc *sc = mac->mac_sc;
9882         uint32_t value = 0;
9883         const uint8_t *data = _data;
9884
9885         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9886             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9887         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9888
9889         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9890             tq->tq_base + BWN_PIO8_TXDATA);
9891         if (len & 3) {
9892                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9893                     BWN_PIO8_TXCTL_24_31);
9894                 data = &(data[len - 1]);
9895                 switch (len & 3) {
9896                 case 3:
9897                         ctl |= BWN_PIO8_TXCTL_16_23;
9898                         value |= (uint32_t)(*data) << 16;
9899                         data--;
9900                 case 2:
9901                         ctl |= BWN_PIO8_TXCTL_8_15;
9902                         value |= (uint32_t)(*data) << 8;
9903                         data--;
9904                 case 1:
9905                         value |= (uint32_t)(*data);
9906                 }
9907                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9908                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9909         }
9910
9911         return (ctl);
9912 }
9913
9914 static void
9915 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9916     uint16_t offset, uint32_t value)
9917 {
9918
9919         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9920 }
9921
9922 static uint16_t
9923 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9924     uint16_t ctl, const void *_data, int len)
9925 {
9926         struct bwn_softc *sc = mac->mac_sc;
9927         const uint8_t *data = _data;
9928
9929         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9930         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9931
9932         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9933             tq->tq_base + BWN_PIO_TXDATA);
9934         if (len & 1) {
9935                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9936                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9937                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9938         }
9939
9940         return (ctl);
9941 }
9942
9943 static uint16_t
9944 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9945     uint16_t ctl, struct mbuf *m0)
9946 {
9947         int i, j = 0;
9948         uint16_t data = 0;
9949         const uint8_t *buf;
9950         struct mbuf *m = m0;
9951
9952         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9953         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9954
9955         for (; m != NULL; m = m->m_next) {
9956                 buf = mtod(m, const uint8_t *);
9957                 for (i = 0; i < m->m_len; i++) {
9958                         if (!((j++) % 2))
9959                                 data |= buf[i];
9960                         else {
9961                                 data |= (buf[i] << 8);
9962                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9963                                 data = 0;
9964                         }
9965                 }
9966         }
9967         if (m0->m_pkthdr.len % 2) {
9968                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9969                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9970                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9971         }
9972
9973         return (ctl);
9974 }
9975
9976 static void
9977 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9978 {
9979
9980         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9981                 return;
9982         BWN_WRITE_2(mac, 0x684, 510 + time);
9983         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9984 }
9985
9986 static struct bwn_dma_ring *
9987 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9988 {
9989
9990         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9991                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9992
9993         switch (prio) {
9994         case 3:
9995                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9996         case 2:
9997                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9998         case 0:
9999                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10000         case 1:
10001                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10002         }
10003         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10004         return (NULL);
10005 }
10006
10007 static int
10008 bwn_dma_getslot(struct bwn_dma_ring *dr)
10009 {
10010         int slot;
10011
10012         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10013
10014         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10015         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10016         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10017
10018         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10019         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10020         dr->dr_curslot = slot;
10021         dr->dr_usedslot++;
10022
10023         return (slot);
10024 }
10025
10026 static int
10027 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10028 {
10029         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10030         unsigned int a, b, c, d;
10031         unsigned int avg;
10032         uint32_t tmp;
10033
10034         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10035         a = tmp & 0xff;
10036         b = (tmp >> 8) & 0xff;
10037         c = (tmp >> 16) & 0xff;
10038         d = (tmp >> 24) & 0xff;
10039         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10040             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10041                 return (ENOENT);
10042         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10043             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10044             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10045
10046         if (ofdm) {
10047                 a = (a + 32) & 0x3f;
10048                 b = (b + 32) & 0x3f;
10049                 c = (c + 32) & 0x3f;
10050                 d = (d + 32) & 0x3f;
10051         }
10052
10053         avg = (a + b + c + d + 2) / 4;
10054         if (ofdm) {
10055                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10056                     & BWN_HF_4DB_CCK_POWERBOOST)
10057                         avg = (avg >= 13) ? (avg - 13) : 0;
10058         }
10059         return (avg);
10060 }
10061
10062 static void
10063 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10064 {
10065         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10066         int rfatt = *rfattp;
10067         int bbatt = *bbattp;
10068
10069         while (1) {
10070                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10071                         break;
10072                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10073                         break;
10074                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10075                         break;
10076                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10077                         break;
10078                 if (bbatt > lo->bbatt.max) {
10079                         bbatt -= 4;
10080                         rfatt += 1;
10081                         continue;
10082                 }
10083                 if (bbatt < lo->bbatt.min) {
10084                         bbatt += 4;
10085                         rfatt -= 1;
10086                         continue;
10087                 }
10088                 if (rfatt > lo->rfatt.max) {
10089                         rfatt -= 1;
10090                         bbatt += 4;
10091                         continue;
10092                 }
10093                 if (rfatt < lo->rfatt.min) {
10094                         rfatt += 1;
10095                         bbatt -= 4;
10096                         continue;
10097                 }
10098                 break;
10099         }
10100
10101         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10102         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10103 }
10104
10105 static void
10106 bwn_phy_lock(struct bwn_mac *mac)
10107 {
10108         struct bwn_softc *sc = mac->mac_sc;
10109         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10110
10111         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10112             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10113
10114         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10115                 bwn_psctl(mac, BWN_PS_AWAKE);
10116 }
10117
10118 static void
10119 bwn_phy_unlock(struct bwn_mac *mac)
10120 {
10121         struct bwn_softc *sc = mac->mac_sc;
10122         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10123
10124         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10125             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10126
10127         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10128                 bwn_psctl(mac, 0);
10129 }
10130
10131 static void
10132 bwn_rf_lock(struct bwn_mac *mac)
10133 {
10134
10135         BWN_WRITE_4(mac, BWN_MACCTL,
10136             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10137         BWN_READ_4(mac, BWN_MACCTL);
10138         DELAY(10);
10139 }
10140
10141 static void
10142 bwn_rf_unlock(struct bwn_mac *mac)
10143 {
10144
10145         BWN_READ_2(mac, BWN_PHYVER);
10146         BWN_WRITE_4(mac, BWN_MACCTL,
10147             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10148 }
10149
10150 static struct bwn_pio_txqueue *
10151 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10152     struct bwn_pio_txpkt **pack)
10153 {
10154         struct bwn_pio *pio = &mac->mac_method.pio;
10155         struct bwn_pio_txqueue *tq = NULL;
10156         unsigned int index;
10157
10158         switch (cookie & 0xf000) {
10159         case 0x1000:
10160                 tq = &pio->wme[WME_AC_BK];
10161                 break;
10162         case 0x2000:
10163                 tq = &pio->wme[WME_AC_BE];
10164                 break;
10165         case 0x3000:
10166                 tq = &pio->wme[WME_AC_VI];
10167                 break;
10168         case 0x4000:
10169                 tq = &pio->wme[WME_AC_VO];
10170                 break;
10171         case 0x5000:
10172                 tq = &pio->mcast;
10173                 break;
10174         }
10175         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10176         if (tq == NULL)
10177                 return (NULL);
10178         index = (cookie & 0x0fff);
10179         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10180         if (index >= N(tq->tq_pkts))
10181                 return (NULL);
10182         *pack = &tq->tq_pkts[index];
10183         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10184         return (tq);
10185 }
10186
10187 static void
10188 bwn_txpwr(void *arg, int npending)
10189 {
10190         struct bwn_mac *mac = arg;
10191         struct bwn_softc *sc = mac->mac_sc;
10192
10193         BWN_LOCK(sc);
10194         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10195             mac->mac_phy.set_txpwr != NULL)
10196                 mac->mac_phy.set_txpwr(mac);
10197         BWN_UNLOCK(sc);
10198 }
10199
10200 static void
10201 bwn_task_15s(struct bwn_mac *mac)
10202 {
10203         uint16_t reg;
10204
10205         if (mac->mac_fw.opensource) {
10206                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10207                 if (reg) {
10208                         bwn_restart(mac, "fw watchdog");
10209                         return;
10210                 }
10211                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10212         }
10213         if (mac->mac_phy.task_15s)
10214                 mac->mac_phy.task_15s(mac);
10215
10216         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10217 }
10218
10219 static void
10220 bwn_task_30s(struct bwn_mac *mac)
10221 {
10222
10223         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10224                 return;
10225         mac->mac_noise.noi_running = 1;
10226         mac->mac_noise.noi_nsamples = 0;
10227
10228         bwn_noise_gensample(mac);
10229 }
10230
10231 static void
10232 bwn_task_60s(struct bwn_mac *mac)
10233 {
10234
10235         if (mac->mac_phy.task_60s)
10236                 mac->mac_phy.task_60s(mac);
10237         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10238 }
10239
10240 static void
10241 bwn_tasks(void *arg)
10242 {
10243         struct bwn_mac *mac = arg;
10244         struct bwn_softc *sc = mac->mac_sc;
10245
10246         BWN_ASSERT_LOCKED(sc);
10247         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10248                 return;
10249
10250         if (mac->mac_task_state % 4 == 0)
10251                 bwn_task_60s(mac);
10252         if (mac->mac_task_state % 2 == 0)
10253                 bwn_task_30s(mac);
10254         bwn_task_15s(mac);
10255
10256         mac->mac_task_state++;
10257         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10258 }
10259
10260 static int
10261 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10262 {
10263         struct bwn_softc *sc = mac->mac_sc;
10264
10265         KASSERT(a == 0, ("not support APHY\n"));
10266
10267         switch (plcp->o.raw[0] & 0xf) {
10268         case 0xb:
10269                 return (BWN_OFDM_RATE_6MB);
10270         case 0xf:
10271                 return (BWN_OFDM_RATE_9MB);
10272         case 0xa:
10273                 return (BWN_OFDM_RATE_12MB);
10274         case 0xe:
10275                 return (BWN_OFDM_RATE_18MB);
10276         case 0x9:
10277                 return (BWN_OFDM_RATE_24MB);
10278         case 0xd:
10279                 return (BWN_OFDM_RATE_36MB);
10280         case 0x8:
10281                 return (BWN_OFDM_RATE_48MB);
10282         case 0xc:
10283                 return (BWN_OFDM_RATE_54MB);
10284         }
10285         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10286             plcp->o.raw[0] & 0xf);
10287         return (-1);
10288 }
10289
10290 static int
10291 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10292 {
10293         struct bwn_softc *sc = mac->mac_sc;
10294
10295         switch (plcp->o.raw[0]) {
10296         case 0x0a:
10297                 return (BWN_CCK_RATE_1MB);
10298         case 0x14:
10299                 return (BWN_CCK_RATE_2MB);
10300         case 0x37:
10301                 return (BWN_CCK_RATE_5MB);
10302         case 0x6e:
10303                 return (BWN_CCK_RATE_11MB);
10304         }
10305         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10306         return (-1);
10307 }
10308
10309 static void
10310 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10311     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10312     int rssi, int noise)
10313 {
10314         struct bwn_softc *sc = mac->mac_sc;
10315         const struct ieee80211_frame_min *wh;
10316         uint64_t tsf;
10317         uint16_t low_mactime_now;
10318
10319         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10320                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10321
10322         wh = mtod(m, const struct ieee80211_frame_min *);
10323         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10324                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10325
10326         bwn_tsf_read(mac, &tsf);
10327         low_mactime_now = tsf;
10328         tsf = tsf & ~0xffffULL;
10329         tsf += le16toh(rxhdr->mac_time);
10330         if (low_mactime_now < le16toh(rxhdr->mac_time))
10331                 tsf -= 0x10000;
10332
10333         sc->sc_rx_th.wr_tsf = tsf;
10334         sc->sc_rx_th.wr_rate = rate;
10335         sc->sc_rx_th.wr_antsignal = rssi;
10336         sc->sc_rx_th.wr_antnoise = noise;
10337 }
10338
10339 static void
10340 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10341 {
10342         uint32_t low, high;
10343
10344         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10345             ("%s:%d: fail", __func__, __LINE__));
10346
10347         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10348         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10349         *tsf = high;
10350         *tsf <<= 32;
10351         *tsf |= low;
10352 }
10353
10354 static int
10355 bwn_dma_attach(struct bwn_mac *mac)
10356 {
10357         struct bwn_dma *dma = &mac->mac_method.dma;
10358         struct bwn_softc *sc = mac->mac_sc;
10359         bus_addr_t lowaddr = 0;
10360         int error;
10361
10362         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10363                 return (0);
10364
10365         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10366
10367         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10368
10369         dma->dmatype = bwn_dma_gettype(mac);
10370         if (dma->dmatype == BWN_DMA_30BIT)
10371                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10372         else if (dma->dmatype == BWN_DMA_32BIT)
10373                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10374         else
10375                 lowaddr = BUS_SPACE_MAXADDR;
10376
10377         /*
10378          * Create top level DMA tag
10379          */
10380         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10381                                BWN_ALIGN, 0,            /* alignment, bounds */
10382                                lowaddr,                 /* lowaddr */
10383                                BUS_SPACE_MAXADDR,       /* highaddr */
10384                                NULL, NULL,              /* filter, filterarg */
10385                                BUS_SPACE_MAXSIZE,       /* maxsize */
10386                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10387                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10388                                0,                       /* flags */
10389                                NULL, NULL,              /* lockfunc, lockarg */
10390                                &dma->parent_dtag);
10391         if (error) {
10392                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10393                 return (error);
10394         }
10395
10396         /*
10397          * Create TX/RX mbuf DMA tag
10398          */
10399         error = bus_dma_tag_create(dma->parent_dtag,
10400                                 1,
10401                                 0,
10402                                 BUS_SPACE_MAXADDR,
10403                                 BUS_SPACE_MAXADDR,
10404                                 NULL, NULL,
10405                                 MCLBYTES,
10406                                 1,
10407                                 BUS_SPACE_MAXSIZE_32BIT,
10408                                 0,
10409                                 NULL, NULL,
10410                                 &dma->rxbuf_dtag);
10411         if (error) {
10412                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10413                 goto fail0;
10414         }
10415         error = bus_dma_tag_create(dma->parent_dtag,
10416                                 1,
10417                                 0,
10418                                 BUS_SPACE_MAXADDR,
10419                                 BUS_SPACE_MAXADDR,
10420                                 NULL, NULL,
10421                                 MCLBYTES,
10422                                 1,
10423                                 BUS_SPACE_MAXSIZE_32BIT,
10424                                 0,
10425                                 NULL, NULL,
10426                                 &dma->txbuf_dtag);
10427         if (error) {
10428                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10429                 goto fail1;
10430         }
10431
10432         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10433         if (!dma->wme[WME_AC_BK])
10434                 goto fail2;
10435
10436         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10437         if (!dma->wme[WME_AC_BE])
10438                 goto fail3;
10439
10440         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10441         if (!dma->wme[WME_AC_VI])
10442                 goto fail4;
10443
10444         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10445         if (!dma->wme[WME_AC_VO])
10446                 goto fail5;
10447
10448         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10449         if (!dma->mcast)
10450                 goto fail6;
10451         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10452         if (!dma->rx)
10453                 goto fail7;
10454
10455         return (error);
10456
10457 fail7:  bwn_dma_ringfree(&dma->mcast);
10458 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10459 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10460 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10461 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10462 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10463 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10464 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10465         return (error);
10466 }
10467
10468 static struct bwn_dma_ring *
10469 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10470     uint16_t cookie, int *slot)
10471 {
10472         struct bwn_dma *dma = &mac->mac_method.dma;
10473         struct bwn_dma_ring *dr;
10474         struct bwn_softc *sc = mac->mac_sc;
10475
10476         BWN_ASSERT_LOCKED(mac->mac_sc);
10477
10478         switch (cookie & 0xf000) {
10479         case 0x1000:
10480                 dr = dma->wme[WME_AC_BK];
10481                 break;
10482         case 0x2000:
10483                 dr = dma->wme[WME_AC_BE];
10484                 break;
10485         case 0x3000:
10486                 dr = dma->wme[WME_AC_VI];
10487                 break;
10488         case 0x4000:
10489                 dr = dma->wme[WME_AC_VO];
10490                 break;
10491         case 0x5000:
10492                 dr = dma->mcast;
10493                 break;
10494         default:
10495                 dr = NULL;
10496                 KASSERT(0 == 1,
10497                     ("invalid cookie value %d", cookie & 0xf000));
10498         }
10499         *slot = (cookie & 0x0fff);
10500         if (*slot < 0 || *slot >= dr->dr_numslots) {
10501                 /*
10502                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10503                  * that it occurs events which have same H/W sequence numbers.
10504                  * When it's occurred just prints a WARNING msgs and ignores.
10505                  */
10506                 KASSERT(status->seq == dma->lastseq,
10507                     ("%s:%d: fail", __func__, __LINE__));
10508                 device_printf(sc->sc_dev,
10509                     "out of slot ranges (0 < %d < %d)\n", *slot,
10510                     dr->dr_numslots);
10511                 return (NULL);
10512         }
10513         dma->lastseq = status->seq;
10514         return (dr);
10515 }
10516
10517 static void
10518 bwn_dma_stop(struct bwn_mac *mac)
10519 {
10520         struct bwn_dma *dma;
10521
10522         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10523                 return;
10524         dma = &mac->mac_method.dma;
10525
10526         bwn_dma_ringstop(&dma->rx);
10527         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10528         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10529         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10530         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10531         bwn_dma_ringstop(&dma->mcast);
10532 }
10533
10534 static void
10535 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10536 {
10537
10538         if (dr == NULL)
10539                 return;
10540
10541         bwn_dma_cleanup(*dr);
10542 }
10543
10544 static void
10545 bwn_pio_stop(struct bwn_mac *mac)
10546 {
10547         struct bwn_pio *pio;
10548
10549         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10550                 return;
10551         pio = &mac->mac_method.pio;
10552
10553         bwn_destroy_queue_tx(&pio->mcast);
10554         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10555         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10556         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10557         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10558 }
10559
10560 static void
10561 bwn_led_attach(struct bwn_mac *mac)
10562 {
10563         struct bwn_softc *sc = mac->mac_sc;
10564         const uint8_t *led_act = NULL;
10565         uint16_t val[BWN_LED_MAX];
10566         int i;
10567
10568         sc->sc_led_idle = (2350 * hz) / 1000;
10569         sc->sc_led_blink = 1;
10570
10571         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10572                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10573                     bwn_vendor_led_act[i].vid) {
10574                         led_act = bwn_vendor_led_act[i].led_act;
10575                         break;
10576                 }
10577         }
10578         if (led_act == NULL)
10579                 led_act = bwn_default_led_act;
10580
10581         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10582         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10583         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10584         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10585
10586         for (i = 0; i < BWN_LED_MAX; ++i) {
10587                 struct bwn_led *led = &sc->sc_leds[i];
10588
10589                 if (val[i] == 0xff) {
10590                         led->led_act = led_act[i];
10591                 } else {
10592                         if (val[i] & BWN_LED_ACT_LOW)
10593                                 led->led_flags |= BWN_LED_F_ACTLOW;
10594                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10595                 }
10596                 led->led_mask = (1 << i);
10597
10598                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10599                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10600                     led->led_act == BWN_LED_ACT_BLINK) {
10601                         led->led_flags |= BWN_LED_F_BLINK;
10602                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10603                                 led->led_flags |= BWN_LED_F_POLLABLE;
10604                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10605                                 led->led_flags |= BWN_LED_F_SLOW;
10606
10607                         if (sc->sc_blink_led == NULL) {
10608                                 sc->sc_blink_led = led;
10609                                 if (led->led_flags & BWN_LED_F_SLOW)
10610                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10611                         }
10612                 }
10613
10614                 DPRINTF(sc, BWN_DEBUG_LED,
10615                     "%dth led, act %d, lowact %d\n", i,
10616                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10617         }
10618         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10619 }
10620
10621 static __inline uint16_t
10622 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10623 {
10624
10625         if (led->led_flags & BWN_LED_F_ACTLOW)
10626                 on = !on;
10627         if (on)
10628                 val |= led->led_mask;
10629         else
10630                 val &= ~led->led_mask;
10631         return val;
10632 }
10633
10634 static void
10635 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10636 {
10637         struct bwn_softc *sc = mac->mac_sc;
10638         struct ifnet *ifp = sc->sc_ifp;
10639         struct ieee80211com *ic = ifp->if_l2com;
10640         uint16_t val;
10641         int i;
10642
10643         if (nstate == IEEE80211_S_INIT) {
10644                 callout_stop(&sc->sc_led_blink_ch);
10645                 sc->sc_led_blinking = 0;
10646         }
10647
10648         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10649                 return;
10650
10651         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10652         for (i = 0; i < BWN_LED_MAX; ++i) {
10653                 struct bwn_led *led = &sc->sc_leds[i];
10654                 int on;
10655
10656                 if (led->led_act == BWN_LED_ACT_UNKN ||
10657                     led->led_act == BWN_LED_ACT_NULL)
10658                         continue;
10659
10660                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10661                     nstate != IEEE80211_S_INIT)
10662                         continue;
10663
10664                 switch (led->led_act) {
10665                 case BWN_LED_ACT_ON:    /* Always on */
10666                         on = 1;
10667                         break;
10668                 case BWN_LED_ACT_OFF:   /* Always off */
10669                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10670                         on = 0;
10671                         break;
10672                 default:
10673                         on = 1;
10674                         switch (nstate) {
10675                         case IEEE80211_S_INIT:
10676                                 on = 0;
10677                                 break;
10678                         case IEEE80211_S_RUN:
10679                                 if (led->led_act == BWN_LED_ACT_11G &&
10680                                     ic->ic_curmode != IEEE80211_MODE_11G)
10681                                         on = 0;
10682                                 break;
10683                         default:
10684                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10685                                         on = 0;
10686                                 break;
10687                         }
10688                         break;
10689                 }
10690
10691                 val = bwn_led_onoff(led, val, on);
10692         }
10693         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10694 }
10695
10696 static void
10697 bwn_led_event(struct bwn_mac *mac, int event)
10698 {
10699         struct bwn_softc *sc = mac->mac_sc;
10700         struct bwn_led *led = sc->sc_blink_led;
10701         int rate;
10702
10703         if (event == BWN_LED_EVENT_POLL) {
10704                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10705                         return;
10706                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10707                         return;
10708         }
10709
10710         sc->sc_led_ticks = ticks;
10711         if (sc->sc_led_blinking)
10712                 return;
10713
10714         switch (event) {
10715         case BWN_LED_EVENT_RX:
10716                 rate = sc->sc_rx_rate;
10717                 break;
10718         case BWN_LED_EVENT_TX:
10719                 rate = sc->sc_tx_rate;
10720                 break;
10721         case BWN_LED_EVENT_POLL:
10722                 rate = 0;
10723                 break;
10724         default:
10725                 panic("unknown LED event %d\n", event);
10726                 break;
10727         }
10728         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10729             bwn_led_duration[rate].off_dur);
10730 }
10731
10732 static void
10733 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10734 {
10735         struct bwn_softc *sc = mac->mac_sc;
10736         struct bwn_led *led = sc->sc_blink_led;
10737         uint16_t val;
10738
10739         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10740         val = bwn_led_onoff(led, val, 1);
10741         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10742
10743         if (led->led_flags & BWN_LED_F_SLOW) {
10744                 BWN_LED_SLOWDOWN(on_dur);
10745                 BWN_LED_SLOWDOWN(off_dur);
10746         }
10747
10748         sc->sc_led_blinking = 1;
10749         sc->sc_led_blink_offdur = off_dur;
10750
10751         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10752 }
10753
10754 static void
10755 bwn_led_blink_next(void *arg)
10756 {
10757         struct bwn_mac *mac = arg;
10758         struct bwn_softc *sc = mac->mac_sc;
10759         uint16_t val;
10760
10761         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10762         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10763         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10764
10765         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10766             bwn_led_blink_end, mac);
10767 }
10768
10769 static void
10770 bwn_led_blink_end(void *arg)
10771 {
10772         struct bwn_mac *mac = arg;
10773         struct bwn_softc *sc = mac->mac_sc;
10774
10775         sc->sc_led_blinking = 0;
10776 }
10777
10778 static int
10779 bwn_suspend(device_t dev)
10780 {
10781         struct bwn_softc *sc = device_get_softc(dev);
10782
10783         bwn_stop(sc, 1);
10784         return (0);
10785 }
10786
10787 static int
10788 bwn_resume(device_t dev)
10789 {
10790         struct bwn_softc *sc = device_get_softc(dev);
10791         struct ifnet *ifp = sc->sc_ifp;
10792
10793         if (ifp->if_flags & IFF_UP)
10794                 bwn_init(sc);
10795         return (0);
10796 }
10797
10798 static void
10799 bwn_rfswitch(void *arg)
10800 {
10801         struct bwn_softc *sc = arg;
10802         struct bwn_mac *mac = sc->sc_curmac;
10803         int cur = 0, prev = 0;
10804
10805         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10806             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10807
10808         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10809                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10810                         & BWN_RF_HWENABLED_HI_MASK))
10811                         cur = 1;
10812         } else {
10813                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10814                     & BWN_RF_HWENABLED_LO_MASK)
10815                         cur = 1;
10816         }
10817
10818         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10819                 prev = 1;
10820
10821         if (cur != prev) {
10822                 if (cur)
10823                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10824                 else
10825                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10826
10827                 device_printf(sc->sc_dev,
10828                     "status of RF switch is changed to %s\n",
10829                     cur ? "ON" : "OFF");
10830                 if (cur != mac->mac_phy.rf_on) {
10831                         if (cur)
10832                                 bwn_rf_turnon(mac);
10833                         else
10834                                 bwn_rf_turnoff(mac);
10835                 }
10836         }
10837
10838         callout_schedule(&sc->sc_rfswitch_ch, hz);
10839 }
10840
10841 static void
10842 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10843 {
10844         struct bwn_phy *phy = &mac->mac_phy;
10845         struct bwn_phy_lp *plp = &phy->phy_lp;
10846
10847         plp->plp_antenna = BWN_ANT_DEFAULT;
10848 }
10849
10850 static int
10851 bwn_phy_lp_init(struct bwn_mac *mac)
10852 {
10853         static const struct bwn_stxtable tables[] = {
10854                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10855                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10856                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10857                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10858                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10859                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10860                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10861                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10862                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10863                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10864                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10865                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10866                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10867                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10868                 { 2, 11, 0x40, 0, 0x0f }
10869         };
10870         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10871         struct bwn_softc *sc = mac->mac_sc;
10872         const struct bwn_stxtable *st;
10873         struct ifnet *ifp = sc->sc_ifp;
10874         struct ieee80211com *ic = ifp->if_l2com;
10875         int i, error;
10876         uint16_t tmp;
10877
10878         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10879         bwn_phy_lp_bbinit(mac);
10880
10881         /* initialize RF */
10882         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10883         DELAY(1);
10884         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10885         DELAY(1);
10886
10887         if (mac->mac_phy.rf_ver == 0x2062)
10888                 bwn_phy_lp_b2062_init(mac);
10889         else {
10890                 bwn_phy_lp_b2063_init(mac);
10891
10892                 /* synchronize stx table. */
10893                 for (i = 0; i < N(tables); i++) {
10894                         st = &tables[i];
10895                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10896                         tmp >>= st->st_rfshift;
10897                         tmp <<= st->st_physhift;
10898                         BWN_PHY_SETMASK(mac,
10899                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10900                             ~(st->st_mask << st->st_physhift), tmp);
10901                 }
10902
10903                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10904                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10905         }
10906
10907         /* calibrate RC */
10908         if (mac->mac_phy.rev >= 2)
10909                 bwn_phy_lp_rxcal_r2(mac);
10910         else if (!plp->plp_rccap) {
10911                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10912                         bwn_phy_lp_rccal_r12(mac);
10913         } else
10914                 bwn_phy_lp_set_rccap(mac);
10915
10916         error = bwn_phy_lp_switch_channel(mac, 7);
10917         if (error)
10918                 device_printf(sc->sc_dev,
10919                     "failed to change channel 7 (%d)\n", error);
10920         bwn_phy_lp_txpctl_init(mac);
10921         bwn_phy_lp_calib(mac);
10922         return (0);
10923 }
10924
10925 static uint16_t
10926 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10927 {
10928
10929         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10930         return (BWN_READ_2(mac, BWN_PHYDATA));
10931 }
10932
10933 static void
10934 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10935 {
10936
10937         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10938         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10939 }
10940
10941 static void
10942 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10943     uint16_t set)
10944 {
10945
10946         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10947         BWN_WRITE_2(mac, BWN_PHYDATA,
10948             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10949 }
10950
10951 static uint16_t
10952 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10953 {
10954
10955         KASSERT(reg != 1, ("unaccessible register %d", reg));
10956         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10957                 reg |= 0x100;
10958         if (mac->mac_phy.rev >= 2)
10959                 reg |= 0x200;
10960         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10961         return BWN_READ_2(mac, BWN_RFDATALO);
10962 }
10963
10964 static void
10965 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10966 {
10967
10968         KASSERT(reg != 1, ("unaccessible register %d", reg));
10969         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10970         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10971 }
10972
10973 static void
10974 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10975 {
10976
10977         if (on) {
10978                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10979                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10980                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10981                 return;
10982         }
10983
10984         if (mac->mac_phy.rev >= 2) {
10985                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10986                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10987                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10988                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10989                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10990                 return;
10991         }
10992
10993         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10994         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10995         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10996         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10997 }
10998
10999 static int
11000 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11001 {
11002         struct bwn_phy *phy = &mac->mac_phy;
11003         struct bwn_phy_lp *plp = &phy->phy_lp;
11004         int error;
11005
11006         if (phy->rf_ver == 0x2063) {
11007                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11008                 if (error)
11009                         return (error);
11010         } else {
11011                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11012                 if (error)
11013                         return (error);
11014                 bwn_phy_lp_set_anafilter(mac, chan);
11015                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11016         }
11017
11018         plp->plp_chan = chan;
11019         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11020         return (0);
11021 }
11022
11023 static uint32_t
11024 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11025 {
11026         struct bwn_softc *sc = mac->mac_sc;
11027         struct ifnet *ifp = sc->sc_ifp;
11028         struct ieee80211com *ic = ifp->if_l2com;
11029
11030         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11031 }
11032
11033 static void
11034 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11035 {
11036         struct bwn_phy *phy = &mac->mac_phy;
11037         struct bwn_phy_lp *plp = &phy->phy_lp;
11038
11039         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11040                 return;
11041
11042         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11043         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11044         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11045         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11046         plp->plp_antenna = antenna;
11047 }
11048
11049 static void
11050 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11051 {
11052
11053         bwn_phy_lp_calib(mac);
11054 }
11055
11056 static void
11057 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11058 {
11059         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11060         struct bwn_softc *sc = mac->mac_sc;
11061         struct ifnet *ifp = sc->sc_ifp;
11062         struct ieee80211com *ic = ifp->if_l2com;
11063
11064         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11065                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11066                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11067                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11068                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11069                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11070                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11071                 return;
11072         }
11073
11074         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11075         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11076         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11077         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11078         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11079         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11080         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11081         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11082 }
11083
11084 static void
11085 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11086 {
11087
11088         bwn_phy_lp_tblinit(mac);
11089         if (mac->mac_phy.rev >= 2)
11090                 bwn_phy_lp_bbinit_r2(mac);
11091         else
11092                 bwn_phy_lp_bbinit_r01(mac);
11093 }
11094
11095 static void
11096 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11097 {
11098         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11099         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11100         struct bwn_softc *sc = mac->mac_sc;
11101         struct ifnet *ifp = sc->sc_ifp;
11102         struct ieee80211com *ic = ifp->if_l2com;
11103
11104         bwn_phy_lp_set_txgain(mac,
11105             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11106         bwn_phy_lp_set_bbmult(mac, 150);
11107 }
11108
11109 static void
11110 bwn_phy_lp_calib(struct bwn_mac *mac)
11111 {
11112         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11113         struct bwn_softc *sc = mac->mac_sc;
11114         struct ifnet *ifp = sc->sc_ifp;
11115         struct ieee80211com *ic = ifp->if_l2com;
11116         const struct bwn_rxcompco *rc = NULL;
11117         struct bwn_txgain ogain;
11118         int i, omode, oafeovr, orf, obbmult;
11119         uint8_t mode, fc = 0;
11120
11121         if (plp->plp_chanfullcal != plp->plp_chan) {
11122                 plp->plp_chanfullcal = plp->plp_chan;
11123                 fc = 1;
11124         }
11125
11126         bwn_mac_suspend(mac);
11127
11128         /* BlueTooth Coexistance Override */
11129         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11130         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11131
11132         if (mac->mac_phy.rev >= 2)
11133                 bwn_phy_lp_digflt_save(mac);
11134         bwn_phy_lp_get_txpctlmode(mac);
11135         mode = plp->plp_txpctlmode;
11136         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11137         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11138                 bwn_phy_lp_bugfix(mac);
11139         if (mac->mac_phy.rev >= 2 && fc == 1) {
11140                 bwn_phy_lp_get_txpctlmode(mac);
11141                 omode = plp->plp_txpctlmode;
11142                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11143                 if (oafeovr)
11144                         ogain = bwn_phy_lp_get_txgain(mac);
11145                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11146                 obbmult = bwn_phy_lp_get_bbmult(mac);
11147                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11148                 if (oafeovr)
11149                         bwn_phy_lp_set_txgain(mac, &ogain);
11150                 bwn_phy_lp_set_bbmult(mac, obbmult);
11151                 bwn_phy_lp_set_txpctlmode(mac, omode);
11152                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11153         }
11154         bwn_phy_lp_set_txpctlmode(mac, mode);
11155         if (mac->mac_phy.rev >= 2)
11156                 bwn_phy_lp_digflt_restore(mac);
11157
11158         /* do RX IQ Calculation; assumes that noise is true. */
11159         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11160                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11161                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11162                                 rc = &bwn_rxcompco_5354[i];
11163                 }
11164         } else if (mac->mac_phy.rev >= 2)
11165                 rc = &bwn_rxcompco_r2;
11166         else {
11167                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11168                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11169                                 rc = &bwn_rxcompco_r12[i];
11170                 }
11171         }
11172         if (rc == NULL)
11173                 goto fail;
11174
11175         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11176         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11177
11178         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11179
11180         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11181                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11182                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11183         } else {
11184                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11185                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11186         }
11187
11188         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11189         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11190         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11191         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11192         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11193         bwn_phy_lp_set_deaf(mac, 0);
11194         /* XXX no checking return value? */
11195         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11196         bwn_phy_lp_clear_deaf(mac, 0);
11197         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11198         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11199         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11200
11201         /* disable RX GAIN override. */
11202         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11203         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11204         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11205         if (mac->mac_phy.rev >= 2) {
11206                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11207                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11208                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11209                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11210                 }
11211         } else {
11212                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11213         }
11214
11215         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11216         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11217 fail:
11218         bwn_mac_enable(mac);
11219 }
11220
11221 static void
11222 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11223 {
11224
11225         if (on) {
11226                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11227                 return;
11228         }
11229
11230         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11231         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11232 }
11233
11234 static int
11235 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11236 {
11237         static const struct bwn_b206x_chan *bc = NULL;
11238         struct bwn_softc *sc = mac->mac_sc;
11239         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11240             tmp[6];
11241         uint16_t old, scale, tmp16;
11242         int i, div;
11243
11244         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11245                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11246                         bc = &bwn_b2063_chantable[i];
11247                         break;
11248                 }
11249         }
11250         if (bc == NULL)
11251                 return (EINVAL);
11252
11253         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11254         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11255         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11256         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11257         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11258         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11259         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11260         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11261         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11262         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11263         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11264         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11265
11266         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11267         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11268
11269         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11270         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11271         freqref = freqxtal * 3;
11272         div = (freqxtal <= 26000000 ? 1 : 2);
11273         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11274         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11275                 999999) / 1000000) + 1;
11276
11277         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11278         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11279             0xfff8, timeout >> 2);
11280         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11281             0xff9f,timeout << 5);
11282         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11283
11284         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11285         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11286         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11287
11288         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11289             (timeoutref + 1)) - 1;
11290         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11291             0xf0, count >> 8);
11292         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11293
11294         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11295         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11296         while (tmp[1] >= freqref) {
11297                 tmp[0]++;
11298                 tmp[1] -= freqref;
11299         }
11300         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11301         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11302         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11303         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11304         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11305
11306         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11307         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11308         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11309         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11310
11311         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11312         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11313
11314         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11315                 scale = 1;
11316                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11317         } else {
11318                 scale = 0;
11319                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11320         }
11321         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11322         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11323
11324         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11325             (scale + 1);
11326         if (tmp[5] > 150)
11327                 tmp[5] = 0;
11328
11329         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11330         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11331
11332         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11333         if (freqxtal > 26000000)
11334                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11335         else
11336                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11337
11338         if (val[0] == 45)
11339                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11340         else
11341                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11342
11343         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11344         DELAY(1);
11345         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11346
11347         /* VCO Calibration */
11348         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11349         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11350         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11351         DELAY(1);
11352         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11353         DELAY(1);
11354         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11355         DELAY(1);
11356         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11357         DELAY(300);
11358         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11359
11360         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11361         return (0);
11362 }
11363
11364 static int
11365 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11366 {
11367         struct bwn_softc *sc = mac->mac_sc;
11368         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11369         const struct bwn_b206x_chan *bc = NULL;
11370         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11371         uint32_t tmp[9];
11372         int i;
11373
11374         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11375                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11376                         bc = &bwn_b2062_chantable[i];
11377                         break;
11378                 }
11379         }
11380
11381         if (bc == NULL)
11382                 return (EINVAL);
11383
11384         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11385         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11386         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11387         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11388         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11389         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11390         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11391         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11392         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11393         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11394
11395         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11396         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11397         bwn_phy_lp_b2062_reset_pllbias(mac);
11398         tmp[0] = freqxtal / 1000;
11399         tmp[1] = plp->plp_div * 1000;
11400         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11401         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11402                 tmp[2] *= 2;
11403         tmp[3] = 48 * tmp[0];
11404         tmp[5] = tmp[2] / tmp[3];
11405         tmp[6] = tmp[2] % tmp[3];
11406         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11407         tmp[4] = tmp[6] * 0x100;
11408         tmp[5] = tmp[4] / tmp[3];
11409         tmp[6] = tmp[4] % tmp[3];
11410         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11411         tmp[4] = tmp[6] * 0x100;
11412         tmp[5] = tmp[4] / tmp[3];
11413         tmp[6] = tmp[4] % tmp[3];
11414         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11415         tmp[4] = tmp[6] * 0x100;
11416         tmp[5] = tmp[4] / tmp[3];
11417         tmp[6] = tmp[4] % tmp[3];
11418         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11419             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11420         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11421         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11422         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11423         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11424
11425         bwn_phy_lp_b2062_vco_calib(mac);
11426         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11427                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11428                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11429                 bwn_phy_lp_b2062_reset_pllbias(mac);
11430                 bwn_phy_lp_b2062_vco_calib(mac);
11431                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11432                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11433                         return (EIO);
11434                 }
11435         }
11436         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11437         return (0);
11438 }
11439
11440 static void
11441 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11442 {
11443         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11444         uint16_t tmp = (channel == 14);
11445
11446         if (mac->mac_phy.rev < 2) {
11447                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11448                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11449                         bwn_phy_lp_set_rccap(mac);
11450                 return;
11451         }
11452
11453         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11454 }
11455
11456 static void
11457 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11458 {
11459         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11460         struct bwn_softc *sc = mac->mac_sc;
11461         struct ifnet *ifp = sc->sc_ifp;
11462         struct ieee80211com *ic = ifp->if_l2com;
11463         uint16_t iso, tmp[3];
11464
11465         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11466
11467         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11468                 iso = plp->plp_txisoband_m;
11469         else if (freq <= 5320)
11470                 iso = plp->plp_txisoband_l;
11471         else if (freq <= 5700)
11472                 iso = plp->plp_txisoband_m;
11473         else
11474                 iso = plp->plp_txisoband_h;
11475
11476         tmp[0] = ((iso - 26) / 12) << 12;
11477         tmp[1] = tmp[0] + 0x1000;
11478         tmp[2] = tmp[0] + 0x2000;
11479
11480         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11481         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11482 }
11483
11484 static void
11485 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11486 {
11487         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11488         int i;
11489         static const uint16_t addr[] = {
11490                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11491                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11492                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11493                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11494                 BWN_PHY_OFDM(0xcf),
11495         };
11496         static const uint16_t val[] = {
11497                 0xde5e, 0xe832, 0xe331, 0x4d26,
11498                 0x0026, 0x1420, 0x0020, 0xfe08,
11499                 0x0008,
11500         };
11501
11502         for (i = 0; i < N(addr); i++) {
11503                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11504                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11505         }
11506 }
11507
11508 static void
11509 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11510 {
11511         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11512         struct bwn_softc *sc = mac->mac_sc;
11513         uint16_t ctl;
11514
11515         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11516         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11517         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11518                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11519                 break;
11520         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11521                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11522                 break;
11523         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11524                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11525                 break;
11526         default:
11527                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11528                 device_printf(sc->sc_dev, "unknown command mode\n");
11529                 break;
11530         }
11531 }
11532
11533 static void
11534 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11535 {
11536         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11537         uint16_t ctl;
11538         uint8_t old;
11539
11540         bwn_phy_lp_get_txpctlmode(mac);
11541         old = plp->plp_txpctlmode;
11542         if (old == mode)
11543                 return;
11544         plp->plp_txpctlmode = mode;
11545
11546         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11547                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11548                     plp->plp_tssiidx);
11549                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11550                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11551
11552                 /* disable TX GAIN override */
11553                 if (mac->mac_phy.rev < 2)
11554                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11555                 else {
11556                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11557                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11558                 }
11559                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11560
11561                 plp->plp_txpwridx = -1;
11562         }
11563         if (mac->mac_phy.rev >= 2) {
11564                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11565                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11566                 else
11567                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11568         }
11569
11570         /* writes TX Power Control mode */
11571         switch (plp->plp_txpctlmode) {
11572         case BWN_PHYLP_TXPCTL_OFF:
11573                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11574                 break;
11575         case BWN_PHYLP_TXPCTL_ON_HW:
11576                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11577                 break;
11578         case BWN_PHYLP_TXPCTL_ON_SW:
11579                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11580                 break;
11581         default:
11582                 ctl = 0;
11583                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11584         }
11585         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11586             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11587 }
11588
11589 static void
11590 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11591 {
11592         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11593         struct bwn_softc *sc = mac->mac_sc;
11594         const unsigned int size = 256;
11595         struct bwn_txgain tg;
11596         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11597         uint16_t tssinpt, tssiidx, value[2];
11598         uint8_t mode;
11599         int8_t txpwridx;
11600
11601         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11602             M_NOWAIT | M_ZERO);
11603         if (tabs == NULL) {
11604                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11605                 return;
11606         }
11607
11608         bwn_phy_lp_get_txpctlmode(mac);
11609         mode = plp->plp_txpctlmode;
11610         txpwridx = plp->plp_txpwridx;
11611         tssinpt = plp->plp_tssinpt;
11612         tssiidx = plp->plp_tssiidx;
11613
11614         bwn_tab_read_multi(mac,
11615             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11616             BWN_TAB_4(7, 0x140), size, tabs);
11617
11618         bwn_phy_lp_tblinit(mac);
11619         bwn_phy_lp_bbinit(mac);
11620         bwn_phy_lp_txpctl_init(mac);
11621         bwn_phy_lp_rf_onoff(mac, 1);
11622         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11623
11624         bwn_tab_write_multi(mac,
11625             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11626             BWN_TAB_4(7, 0x140), size, tabs);
11627
11628         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11629         plp->plp_tssinpt = tssinpt;
11630         plp->plp_tssiidx = tssiidx;
11631         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11632         if (txpwridx != -1) {
11633                 /* set TX power by index */
11634                 plp->plp_txpwridx = txpwridx;
11635                 bwn_phy_lp_get_txpctlmode(mac);
11636                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11637                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11638                 if (mac->mac_phy.rev >= 2) {
11639                         rxcomp = bwn_tab_read(mac,
11640                             BWN_TAB_4(7, txpwridx + 320));
11641                         txgain = bwn_tab_read(mac,
11642                             BWN_TAB_4(7, txpwridx + 192));
11643                         tg.tg_pad = (txgain >> 16) & 0xff;
11644                         tg.tg_gm = txgain & 0xff;
11645                         tg.tg_pga = (txgain >> 8) & 0xff;
11646                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11647                         bwn_phy_lp_set_txgain(mac, &tg);
11648                 } else {
11649                         rxcomp = bwn_tab_read(mac,
11650                             BWN_TAB_4(10, txpwridx + 320));
11651                         txgain = bwn_tab_read(mac,
11652                             BWN_TAB_4(10, txpwridx + 192));
11653                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11654                             0xf800, (txgain >> 4) & 0x7fff);
11655                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11656                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11657                 }
11658                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11659
11660                 /* set TX IQCC */
11661                 value[0] = (rxcomp >> 10) & 0x3ff;
11662                 value[1] = rxcomp & 0x3ff;
11663                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11664
11665                 coeff = bwn_tab_read(mac,
11666                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11667                     BWN_TAB_4(10, txpwridx + 448));
11668                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11669                 if (mac->mac_phy.rev >= 2) {
11670                         rfpwr = bwn_tab_read(mac,
11671                             BWN_TAB_4(7, txpwridx + 576));
11672                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11673                             rfpwr & 0xffff);
11674                 }
11675                 bwn_phy_lp_set_txgain_override(mac);
11676         }
11677         if (plp->plp_rccap)
11678                 bwn_phy_lp_set_rccap(mac);
11679         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11680         bwn_phy_lp_set_txpctlmode(mac, mode);
11681         free(tabs, M_DEVBUF);
11682 }
11683
11684 static void
11685 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11686 {
11687         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11688         int i;
11689         static const uint16_t addr[] = {
11690                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11691                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11692                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11693                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11694                 BWN_PHY_OFDM(0xcf),
11695         };
11696
11697         for (i = 0; i < N(addr); i++)
11698                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11699 }
11700
11701 static void
11702 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11703 {
11704         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11705
11706         if (mac->mac_phy.rev < 2) {
11707                 bwn_phy_lp_tblinit_r01(mac);
11708                 bwn_phy_lp_tblinit_txgain(mac);
11709                 bwn_phy_lp_set_gaintbl(mac, freq);
11710                 return;
11711         }
11712
11713         bwn_phy_lp_tblinit_r2(mac);
11714         bwn_phy_lp_tblinit_txgain(mac);
11715 }
11716
11717 struct bwn_wpair {
11718         uint16_t                reg;
11719         uint16_t                value;
11720 };
11721
11722 struct bwn_smpair {
11723         uint16_t                offset;
11724         uint16_t                mask;
11725         uint16_t                set;
11726 };
11727
11728 static void
11729 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11730 {
11731         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11732         struct bwn_softc *sc = mac->mac_sc;
11733         struct ifnet *ifp = sc->sc_ifp;
11734         struct ieee80211com *ic = ifp->if_l2com;
11735         static const struct bwn_wpair v1[] = {
11736                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11737                 { BWN_PHY_AFE_CTL, 0x8800 },
11738                 { BWN_PHY_AFE_CTL_OVR, 0 },
11739                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11740                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11741                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11742                 { BWN_PHY_OFDM(0xf9), 0 },
11743                 { BWN_PHY_TR_LOOKUP_1, 0 }
11744         };
11745         static const struct bwn_smpair v2[] = {
11746                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11747                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11748                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11749                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11750                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11751         };
11752         static const struct bwn_smpair v3[] = {
11753                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11754                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11755                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11756                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11757                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11758                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11759                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11760                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11761                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11762                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11763
11764         };
11765         int i;
11766
11767         for (i = 0; i < N(v1); i++)
11768                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11769         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11770         for (i = 0; i < N(v2); i++)
11771                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11772
11773         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11774         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11775         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11776         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11777                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11778                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11779         } else {
11780                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11781         }
11782         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11783         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11784         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11785         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11786         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11787         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11788         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11789         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11790         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11791         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11792         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11793         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11794             (siba_get_chiprev(sc->sc_dev) == 0)) {
11795                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11796                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11797         } else {
11798                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11799                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11800         }
11801         for (i = 0; i < N(v3); i++)
11802                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11803         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11804             (siba_get_chiprev(sc->sc_dev) == 0)) {
11805                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11806                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11807         }
11808
11809         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11810                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11811                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11812                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11813                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11814                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11815                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11816         } else
11817                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11818
11819         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11820         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11821         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11822         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11823         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11824         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11825         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11826             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11827             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11828
11829         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11830             (siba_get_chiprev(sc->sc_dev) == 0)) {
11831                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11832                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11833                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11834         }
11835
11836         bwn_phy_lp_digflt_save(mac);
11837 }
11838
11839 static void
11840 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11841 {
11842         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11843         struct bwn_softc *sc = mac->mac_sc;
11844         struct ifnet *ifp = sc->sc_ifp;
11845         struct ieee80211com *ic = ifp->if_l2com;
11846         static const struct bwn_smpair v1[] = {
11847                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11848                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11849                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11850                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11851                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11852                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11853                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11854         };
11855         static const struct bwn_smpair v2[] = {
11856                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11857                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11858                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11859                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11860                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11861                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11862                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11863                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11864                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11865                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11866                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11867                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11868                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11869                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11870                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11871                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11872         };
11873         static const struct bwn_smpair v3[] = {
11874                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11875                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11876                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11877                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11878                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11879                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11880                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11881                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11882         };
11883         static const struct bwn_smpair v4[] = {
11884                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11885                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11886                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11887                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11888                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11889                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11890                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11891                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11892         };
11893         static const struct bwn_smpair v5[] = {
11894                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11895                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11896                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11897                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11898                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11899                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11900                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11901                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11902         };
11903         int i;
11904         uint16_t tmp, tmp2;
11905
11906         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11907         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11908         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11909         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11910         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11911         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11912         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11913         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11914         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11915         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11916         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11917         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11918         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11919         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11920         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11921         for (i = 0; i < N(v1); i++)
11922                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11923         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11924             0xff00, plp->plp_rxpwroffset);
11925         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11926             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11927            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11928                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11929                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11930                 if (mac->mac_phy.rev == 0)
11931                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11932                             0xffcf, 0x0010);
11933                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11934         } else {
11935                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11936                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11937                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11938         }
11939         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11940         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11941         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11942                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11943         else
11944                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11945         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11946         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11947             0xfff9, (plp->plp_bxarch << 1));
11948         if (mac->mac_phy.rev == 1 &&
11949             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11950                 for (i = 0; i < N(v2); i++)
11951                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11952                             v2[i].set);
11953         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11954             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11955             ((mac->mac_phy.rev == 0) &&
11956              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11957                 for (i = 0; i < N(v3); i++)
11958                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11959                             v3[i].set);
11960         } else if (mac->mac_phy.rev == 1 ||
11961                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11962                 for (i = 0; i < N(v4); i++)
11963                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11964                             v4[i].set);
11965         } else {
11966                 for (i = 0; i < N(v5); i++)
11967                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11968                             v5[i].set);
11969         }
11970         if (mac->mac_phy.rev == 1 &&
11971             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11972                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11973                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11974                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11975                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11976         }
11977         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11978             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11979             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11980                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11981                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11982                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11983                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11984         }
11985         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11986                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11987                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11988                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11989                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11990                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11991                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11992                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11993                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11994         } else {
11995                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11996                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11997         }
11998         if (mac->mac_phy.rev == 1) {
11999                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12000                 tmp2 = (tmp & 0x03e0) >> 5;
12001                 tmp2 |= tmp2 << 5;
12002                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12003                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12004                 tmp2 = (tmp & 0x1f00) >> 8;
12005                 tmp2 |= tmp2 << 5;
12006                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12007                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12008                 tmp2 = tmp & 0x00ff;
12009                 tmp2 |= tmp << 8;
12010                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12011         }
12012 }
12013
12014 struct bwn_b2062_freq {
12015         uint16_t                freq;
12016         uint8_t                 value[6];
12017 };
12018
12019 static void
12020 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12021 {
12022 #define CALC_CTL7(freq, div)                                            \
12023         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12024 #define CALC_CTL18(freq, div)                                           \
12025         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12026 #define CALC_CTL19(freq, div)                                           \
12027         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12028         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12029         struct bwn_softc *sc = mac->mac_sc;
12030         struct ifnet *ifp = sc->sc_ifp;
12031         struct ieee80211com *ic = ifp->if_l2com;
12032         static const struct bwn_b2062_freq freqdata_tab[] = {
12033                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12034                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12035                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12036                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12037                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12038                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12039         };
12040         static const struct bwn_wpair v1[] = {
12041                 { BWN_B2062_N_TXCTL3, 0 },
12042                 { BWN_B2062_N_TXCTL4, 0 },
12043                 { BWN_B2062_N_TXCTL5, 0 },
12044                 { BWN_B2062_N_TXCTL6, 0 },
12045                 { BWN_B2062_N_PDNCTL0, 0x40 },
12046                 { BWN_B2062_N_PDNCTL0, 0 },
12047                 { BWN_B2062_N_CALIB_TS, 0x10 },
12048                 { BWN_B2062_N_CALIB_TS, 0 }
12049         };
12050         const struct bwn_b2062_freq *f = NULL;
12051         uint32_t xtalfreq, ref;
12052         unsigned int i;
12053
12054         bwn_phy_lp_b2062_tblinit(mac);
12055
12056         for (i = 0; i < N(v1); i++)
12057                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12058         if (mac->mac_phy.rev > 0)
12059                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12060                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12061         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12062                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12063         else
12064                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12065
12066         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12067             ("%s:%d: fail", __func__, __LINE__));
12068         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12069         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12070
12071         if (xtalfreq <= 30000000) {
12072                 plp->plp_div = 1;
12073                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12074         } else {
12075                 plp->plp_div = 2;
12076                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12077         }
12078
12079         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12080             CALC_CTL7(xtalfreq, plp->plp_div));
12081         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12082             CALC_CTL18(xtalfreq, plp->plp_div));
12083         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12084             CALC_CTL19(xtalfreq, plp->plp_div));
12085
12086         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12087         ref &= 0xffff;
12088         for (i = 0; i < N(freqdata_tab); i++) {
12089                 if (ref < freqdata_tab[i].freq) {
12090                         f = &freqdata_tab[i];
12091                         break;
12092                 }
12093         }
12094         if (f == NULL)
12095                 f = &freqdata_tab[N(freqdata_tab) - 1];
12096         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12097             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12098         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12099             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12100         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12101         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12102 #undef CALC_CTL7
12103 #undef CALC_CTL18
12104 #undef CALC_CTL19
12105 }
12106
12107 static void
12108 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12109 {
12110
12111         bwn_phy_lp_b2063_tblinit(mac);
12112         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12113         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12114         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12115         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12116         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12117         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12118         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12119         if (mac->mac_phy.rev == 2) {
12120                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12121                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12122                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12123         } else {
12124                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12125                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12126         }
12127 }
12128
12129 static void
12130 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12131 {
12132         struct bwn_softc *sc = mac->mac_sc;
12133         static const struct bwn_wpair v1[] = {
12134                 { BWN_B2063_RX_BB_SP8, 0x0 },
12135                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12136                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12137                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12138                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12139                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12140                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12141                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12142         };
12143         static const struct bwn_wpair v2[] = {
12144                 { BWN_B2063_TX_BB_SP3, 0x0 },
12145                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12146                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12147                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12148                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12149         };
12150         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12151         int i;
12152         uint8_t tmp;
12153
12154         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12155
12156         for (i = 0; i < 2; i++)
12157                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12158         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12159         for (i = 2; i < N(v1); i++)
12160                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12161         for (i = 0; i < 10000; i++) {
12162                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12163                         break;
12164                 DELAY(1000);
12165         }
12166
12167         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12168                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12169
12170         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12171
12172         for (i = 0; i < N(v2); i++)
12173                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12174         if (freqxtal == 24000000) {
12175                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12176                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12177         } else {
12178                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12179                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12180         }
12181         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12182         for (i = 0; i < 10000; i++) {
12183                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12184                         break;
12185                 DELAY(1000);
12186         }
12187         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12188                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12189         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12190 }
12191
12192 static void
12193 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12194 {
12195         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12196         struct bwn_softc *sc = mac->mac_sc;
12197         struct bwn_phy_lp_iq_est ie;
12198         struct bwn_txgain tx_gains;
12199         static const uint32_t pwrtbl[21] = {
12200                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12201                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12202                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12203                 0x0004c, 0x0002c, 0x0001a,
12204         };
12205         uint32_t npwr, ipwr, sqpwr, tmp;
12206         int loopback, i, j, sum, error;
12207         uint16_t save[7];
12208         uint8_t txo, bbmult, txpctlmode;
12209
12210         error = bwn_phy_lp_switch_channel(mac, 7);
12211         if (error)
12212                 device_printf(sc->sc_dev,
12213                     "failed to change channel to 7 (%d)\n", error);
12214         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12215         bbmult = bwn_phy_lp_get_bbmult(mac);
12216         if (txo)
12217                 tx_gains = bwn_phy_lp_get_txgain(mac);
12218
12219         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12220         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12221         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12222         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12223         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12224         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12225         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12226
12227         bwn_phy_lp_get_txpctlmode(mac);
12228         txpctlmode = plp->plp_txpctlmode;
12229         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12230
12231         /* disable CRS */
12232         bwn_phy_lp_set_deaf(mac, 1);
12233         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12234         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12235         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12236         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12237         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12238         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12239         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12240         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12241         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12242         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12243         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12244         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12245         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12246         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12247         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12248         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12249         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12250         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12251         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12252         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12253         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12254         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12255         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12256         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12257
12258         loopback = bwn_phy_lp_loopback(mac);
12259         if (loopback == -1)
12260                 goto done;
12261         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12262         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12263         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12264         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12265         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12266
12267         tmp = 0;
12268         memset(&ie, 0, sizeof(ie));
12269         for (i = 128; i <= 159; i++) {
12270                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12271                 sum = 0;
12272                 for (j = 5; j <= 25; j++) {
12273                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12274                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12275                                 goto done;
12276                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12277                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12278                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12279                             12);
12280                         sum += ((ipwr - npwr) * (ipwr - npwr));
12281                         if ((i == 128) || (sum < tmp)) {
12282                                 plp->plp_rccap = i;
12283                                 tmp = sum;
12284                         }
12285                 }
12286         }
12287         bwn_phy_lp_ddfs_turnoff(mac);
12288 done:
12289         /* restore CRS */
12290         bwn_phy_lp_clear_deaf(mac, 1);
12291         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12292         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12293
12294         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12295         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12296         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12297         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12298         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12299         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12300         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12301
12302         bwn_phy_lp_set_bbmult(mac, bbmult);
12303         if (txo)
12304                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12305         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12306         if (plp->plp_rccap)
12307                 bwn_phy_lp_set_rccap(mac);
12308 }
12309
12310 static void
12311 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12312 {
12313         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12314         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12315
12316         if (mac->mac_phy.rev == 1)
12317                 rc_cap = MIN(rc_cap + 5, 15);
12318
12319         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12320             MAX(plp->plp_rccap - 4, 0x80));
12321         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12322         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12323             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12324 }
12325
12326 static uint32_t
12327 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12328 {
12329         uint32_t i, q, r;
12330
12331         if (div == 0)
12332                 return (0);
12333
12334         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12335                 q <<= 1;
12336                 if (r << 1 >= div) {
12337                         q++;
12338                         r = (r << 1) - div;
12339                 }
12340         }
12341         if (r << 1 >= div)
12342                 q++;
12343         return (q);
12344 }
12345
12346 static void
12347 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12348 {
12349         struct bwn_softc *sc = mac->mac_sc;
12350
12351         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12352         DELAY(20);
12353         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12354                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12355                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12356         } else {
12357                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12358         }
12359         DELAY(5);
12360 }
12361
12362 static void
12363 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12364 {
12365
12366         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12367         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12368         DELAY(200);
12369 }
12370
12371 static void
12372 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12373 {
12374 #define FLAG_A  0x01
12375 #define FLAG_G  0x02
12376         struct bwn_softc *sc = mac->mac_sc;
12377         struct ifnet *ifp = sc->sc_ifp;
12378         struct ieee80211com *ic = ifp->if_l2com;
12379         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12380                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12381                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12382                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12383                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12384                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12385                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12386                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12387                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12388                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12389                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12390                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12391                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12392                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12393                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12399                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12426                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12427         };
12428         const struct bwn_b206x_rfinit_entry *br;
12429         unsigned int i;
12430
12431         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12432                 br = &bwn_b2062_init_tab[i];
12433                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12434                         if (br->br_flags & FLAG_G)
12435                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12436                 } else {
12437                         if (br->br_flags & FLAG_A)
12438                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12439                 }
12440         }
12441 #undef FLAG_A
12442 #undef FLAG_B
12443 }
12444
12445 static void
12446 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12447 {
12448 #define FLAG_A  0x01
12449 #define FLAG_G  0x02
12450         struct bwn_softc *sc = mac->mac_sc;
12451         struct ifnet *ifp = sc->sc_ifp;
12452         struct ieee80211com *ic = ifp->if_l2com;
12453         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12454                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12455                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12456                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12457                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12458                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12459                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12460                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12461                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12462                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12464                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12465                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12466                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12467                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12468                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12469                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12470                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12471                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12472                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12473                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12474                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12475                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12476                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12477                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12478                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12479                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12482                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12483                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12485                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12486                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12487                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12488                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12489                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12493                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12494                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12495                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12496         };
12497         const struct bwn_b206x_rfinit_entry *br;
12498         unsigned int i;
12499
12500         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12501                 br = &bwn_b2063_init_tab[i];
12502                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12503                         if (br->br_flags & FLAG_G)
12504                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12505                 } else {
12506                         if (br->br_flags & FLAG_A)
12507                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12508                 }
12509         }
12510 #undef FLAG_A
12511 #undef FLAG_B
12512 }
12513
12514 static void
12515 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12516     int count, void *_data)
12517 {
12518         unsigned int i;
12519         uint32_t offset, type;
12520         uint8_t *data = _data;
12521
12522         type = BWN_TAB_GETTYPE(typenoffset);
12523         offset = BWN_TAB_GETOFFSET(typenoffset);
12524         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12525
12526         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12527
12528         for (i = 0; i < count; i++) {
12529                 switch (type) {
12530                 case BWN_TAB_8BIT:
12531                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12532                         data++;
12533                         break;
12534                 case BWN_TAB_16BIT:
12535                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12536                             BWN_PHY_TABLEDATALO);
12537                         data += 2;
12538                         break;
12539                 case BWN_TAB_32BIT:
12540                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12541                             BWN_PHY_TABLEDATAHI);
12542                         *((uint32_t *)data) <<= 16;
12543                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12544                             BWN_PHY_TABLEDATALO);
12545                         data += 4;
12546                         break;
12547                 default:
12548                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12549                 }
12550         }
12551 }
12552
12553 static void
12554 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12555     int count, const void *_data)
12556 {
12557         uint32_t offset, type, value;
12558         const uint8_t *data = _data;
12559         unsigned int i;
12560
12561         type = BWN_TAB_GETTYPE(typenoffset);
12562         offset = BWN_TAB_GETOFFSET(typenoffset);
12563         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12564
12565         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12566
12567         for (i = 0; i < count; i++) {
12568                 switch (type) {
12569                 case BWN_TAB_8BIT:
12570                         value = *data;
12571                         data++;
12572                         KASSERT(!(value & ~0xff),
12573                             ("%s:%d: fail", __func__, __LINE__));
12574                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12575                         break;
12576                 case BWN_TAB_16BIT:
12577                         value = *((const uint16_t *)data);
12578                         data += 2;
12579                         KASSERT(!(value & ~0xffff),
12580                             ("%s:%d: fail", __func__, __LINE__));
12581                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12582                         break;
12583                 case BWN_TAB_32BIT:
12584                         value = *((const uint32_t *)data);
12585                         data += 4;
12586                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12587                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12588                         break;
12589                 default:
12590                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12591                 }
12592         }
12593 }
12594
12595 static struct bwn_txgain
12596 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12597 {
12598         struct bwn_txgain tg;
12599         uint16_t tmp;
12600
12601         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12602         if (mac->mac_phy.rev < 2) {
12603                 tmp = BWN_PHY_READ(mac,
12604                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12605                 tg.tg_gm = tmp & 0x0007;
12606                 tg.tg_pga = (tmp & 0x0078) >> 3;
12607                 tg.tg_pad = (tmp & 0x780) >> 7;
12608                 return (tg);
12609         }
12610
12611         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12612         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12613         tg.tg_gm = tmp & 0xff;
12614         tg.tg_pga = (tmp >> 8) & 0xff;
12615         return (tg);
12616 }
12617
12618 static uint8_t
12619 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12620 {
12621
12622         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12623 }
12624
12625 static void
12626 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12627 {
12628         uint16_t pa;
12629
12630         if (mac->mac_phy.rev < 2) {
12631                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12632                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12633                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12634                 bwn_phy_lp_set_txgain_override(mac);
12635                 return;
12636         }
12637
12638         pa = bwn_phy_lp_get_pa_gain(mac);
12639         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12640             (tg->tg_pga << 8) | tg->tg_gm);
12641         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12642             tg->tg_pad | (pa << 6));
12643         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12644         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12645             tg->tg_pad | (pa << 8));
12646         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12647         bwn_phy_lp_set_txgain_override(mac);
12648 }
12649
12650 static void
12651 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12652 {
12653
12654         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12655 }
12656
12657 static void
12658 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12659 {
12660         uint16_t trsw = (tx << 1) | rx;
12661
12662         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12663         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12664 }
12665
12666 static void
12667 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12668 {
12669         struct bwn_softc *sc = mac->mac_sc;
12670         struct ifnet *ifp = sc->sc_ifp;
12671         struct ieee80211com *ic = ifp->if_l2com;
12672         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12673
12674         if (mac->mac_phy.rev < 2) {
12675                 trsw = gain & 0x1;
12676                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12677                 ext_lna = (gain & 2) >> 1;
12678
12679                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12680                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12681                     0xfbff, ext_lna << 10);
12682                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12683                     0xf7ff, ext_lna << 11);
12684                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12685         } else {
12686                 low_gain = gain & 0xffff;
12687                 high_gain = (gain >> 16) & 0xf;
12688                 ext_lna = (gain >> 21) & 0x1;
12689                 trsw = ~(gain >> 20) & 0x1;
12690
12691                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12692                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12693                     0xfdff, ext_lna << 9);
12694                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12695                     0xfbff, ext_lna << 10);
12696                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12697                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12698                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12699                         tmp = (gain >> 2) & 0x3;
12700                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12701                             0xe7ff, tmp<<11);
12702                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12703                             tmp << 3);
12704                 }
12705         }
12706
12707         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12708         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12709         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12710         if (mac->mac_phy.rev >= 2) {
12711                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12712                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12713                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12714                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12715                 }
12716                 return;
12717         }
12718         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12719 }
12720
12721 static void
12722 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12723 {
12724         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12725
12726         if (user)
12727                 plp->plp_crsusr_off = 1;
12728         else
12729                 plp->plp_crssys_off = 1;
12730
12731         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12732 }
12733
12734 static void
12735 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12736 {
12737         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12738         struct bwn_softc *sc = mac->mac_sc;
12739         struct ifnet *ifp = sc->sc_ifp;
12740         struct ieee80211com *ic = ifp->if_l2com;
12741
12742         if (user)
12743                 plp->plp_crsusr_off = 0;
12744         else
12745                 plp->plp_crssys_off = 0;
12746
12747         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12748                 return;
12749
12750         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12751                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12752         else
12753                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12754 }
12755
12756 static unsigned int
12757 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12758 {
12759         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12760         static uint8_t sqrt_table[256] = {
12761                 10, 14, 17, 20, 22, 24, 26, 28,
12762                 30, 31, 33, 34, 36, 37, 38, 40,
12763                 41, 42, 43, 44, 45, 46, 47, 48,
12764                 50, 50, 51, 52, 53, 54, 55, 56,
12765                 57, 58, 59, 60, 60, 61, 62, 63,
12766                 64, 64, 65, 66, 67, 67, 68, 69,
12767                 70, 70, 71, 72, 72, 73, 74, 74,
12768                 75, 76, 76, 77, 78, 78, 79, 80,
12769                 80, 81, 81, 82, 83, 83, 84, 84,
12770                 85, 86, 86, 87, 87, 88, 88, 89,
12771                 90, 90, 91, 91, 92, 92, 93, 93,
12772                 94, 94, 95, 95, 96, 96, 97, 97,
12773                 98, 98, 99, 100, 100, 100, 101, 101,
12774                 102, 102, 103, 103, 104, 104, 105, 105,
12775                 106, 106, 107, 107, 108, 108, 109, 109,
12776                 110, 110, 110, 111, 111, 112, 112, 113,
12777                 113, 114, 114, 114, 115, 115, 116, 116,
12778                 117, 117, 117, 118, 118, 119, 119, 120,
12779                 120, 120, 121, 121, 122, 122, 122, 123,
12780                 123, 124, 124, 124, 125, 125, 126, 126,
12781                 126, 127, 127, 128, 128, 128, 129, 129,
12782                 130, 130, 130, 131, 131, 131, 132, 132,
12783                 133, 133, 133, 134, 134, 134, 135, 135,
12784                 136, 136, 136, 137, 137, 137, 138, 138,
12785                 138, 139, 139, 140, 140, 140, 141, 141,
12786                 141, 142, 142, 142, 143, 143, 143, 144,
12787                 144, 144, 145, 145, 145, 146, 146, 146,
12788                 147, 147, 147, 148, 148, 148, 149, 149,
12789                 150, 150, 150, 150, 151, 151, 151, 152,
12790                 152, 152, 153, 153, 153, 154, 154, 154,
12791                 155, 155, 155, 156, 156, 156, 157, 157,
12792                 157, 158, 158, 158, 159, 159, 159, 160
12793         };
12794
12795         if (x == 0)
12796                 return (0);
12797         if (x >= 256) {
12798                 unsigned int tmp;
12799
12800                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12801                         /* do nothing */ ;
12802                 return (tmp);
12803         }
12804         return (sqrt_table[x - 1] / 10);
12805 }
12806
12807 static int
12808 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12809 {
12810 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12811         int _t;                                                         \
12812         _t = _x - 20;                                                   \
12813         if (_t >= 0) {                                                  \
12814                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12815         } else {                                                        \
12816                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12817         }                                                               \
12818 } while (0)
12819 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12820         int _t;                                                         \
12821         _t = _x - 11;                                                   \
12822         if (_t >= 0)                                                    \
12823                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12824         else                                                            \
12825                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12826 } while (0)
12827         struct bwn_phy_lp_iq_est ie;
12828         uint16_t v0, v1;
12829         int tmp[2], ret;
12830
12831         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12832         v0 = v1 >> 8;
12833         v1 |= 0xff;
12834
12835         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12836         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12837
12838         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12839         if (ret == 0)
12840                 goto done;
12841
12842         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12843                 ret = 0;
12844                 goto done;
12845         }
12846
12847         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12848         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12849
12850         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12851         v0 = tmp[0] >> 3;
12852         v1 = tmp[1] >> 4;
12853 done:
12854         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12855         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12856         return ret;
12857 #undef CALC_COEFF
12858 #undef CALC_COEFF2
12859 }
12860
12861 static void
12862 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12863 {
12864         static const uint16_t noisescale[] = {
12865                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12866                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12867                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12868                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12869                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12870         };
12871         static const uint16_t crsgainnft[] = {
12872                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12873                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12874                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12875                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12876                 0x013d,
12877         };
12878         static const uint16_t filterctl[] = {
12879                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12880                 0xff53, 0x0127,
12881         };
12882         static const uint32_t psctl[] = {
12883                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12884                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12885                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12886                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12887                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12888                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12889                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12890                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12891         };
12892         static const uint16_t ofdmcckgain_r0[] = {
12893                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12894                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12895                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12896                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12897                 0x755d,
12898         };
12899         static const uint16_t ofdmcckgain_r1[] = {
12900                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12901                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12902                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12903                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12904                 0x755d,
12905         };
12906         static const uint16_t gaindelta[] = {
12907                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12908                 0x0000,
12909         };
12910         static const uint32_t txpwrctl[] = {
12911                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12912                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12913                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12914                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12915                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12916                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12917                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12918                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12919                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12920                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12921                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12922                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12923                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000,
12949                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12950                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12951                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12952                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12953                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12954                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12955                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12956                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12957                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12958                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12959                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12960                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12961                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12962                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12963                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12964                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12965                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12966                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12967                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12968                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12969                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12970                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12971                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12972                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12973                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12974                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12975                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12976                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12977                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12978                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12979                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12980                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12981                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12982                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12983                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12991                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12992                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12993                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12994                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12995                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12996                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12997                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12998                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12999                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13000                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13001                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13002                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13003                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13004                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13005                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13006                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13007                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13008                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13009                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13010                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13011                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13012                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13013                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13014                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13015                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13016                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13017                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13018                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13019                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13020                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13021                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13022                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13023                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13024                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13025                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13026                 0x00000702,
13027         };
13028
13029         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13030
13031         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13032             bwn_tab_sigsq_tbl);
13033         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13034         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13035         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13036         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13037         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13038             bwn_tab_pllfrac_tbl);
13039         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13040             bwn_tabl_iqlocal_tbl);
13041         if (mac->mac_phy.rev == 0) {
13042                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13043                     ofdmcckgain_r0);
13044                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13045                     ofdmcckgain_r0);
13046         } else {
13047                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13048                     ofdmcckgain_r1);
13049                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13050                     ofdmcckgain_r1);
13051         }
13052         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13053         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13054 }
13055
13056 static void
13057 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13058 {
13059         struct bwn_softc *sc = mac->mac_sc;
13060         int i;
13061         static const uint16_t noisescale[] = {
13062                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13063                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13068                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13069         };
13070         static const uint32_t filterctl[] = {
13071                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13072                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13073         };
13074         static const uint32_t psctl[] = {
13075                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13076                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13077                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13078                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13079         };
13080         static const uint32_t gainidx[] = {
13081                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13082                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13083                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13084                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13085                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13086                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13087                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13088                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13089                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13090                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13091                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13092                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13093                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13094                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13095                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13096                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13097                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13098                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13099                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13100                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13101                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13102                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13103                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13104                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13105                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13106                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13107                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13108                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13109                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13110                 0x0000001a, 0x64ca55ad, 0x0000001a
13111         };
13112         static const uint16_t auxgainidx[] = {
13113                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13114                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13115                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13116                 0x0004, 0x0016
13117         };
13118         static const uint16_t swctl[] = {
13119                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13120                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13121                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13122                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13123                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13124                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13125                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13126                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13127         };
13128         static const uint8_t hf[] = {
13129                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13130                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13131         };
13132         static const uint32_t gainval[] = {
13133                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13134                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13135                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13136                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13137                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13138                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13139                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13142                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13143                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13144                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13145                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13146                 0x000000f1, 0x00000000, 0x00000000
13147         };
13148         static const uint16_t gain[] = {
13149                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13150                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13151                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13152                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13153                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13154                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13161         };
13162         static const uint32_t papdeps[] = {
13163                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13164                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13165                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13166                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13167                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13168                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13169                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13170                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13171                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13172                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13173                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13174                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13175                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13176         };
13177         static const uint32_t papdmult[] = {
13178                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13179                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13180                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13181                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13182                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13183                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13184                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13185                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13186                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13187                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13188                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13189                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13190                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13191         };
13192         static const uint32_t gainidx_a0[] = {
13193                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13194                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13195                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13196                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13197                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13198                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13199                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13200                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13201                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13202                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13203                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13204                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13205                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13206         };
13207         static const uint16_t auxgainidx_a0[] = {
13208                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13209                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13210                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13211                 0x0002, 0x0014
13212         };
13213         static const uint32_t gainval_a0[] = {
13214                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13215                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13216                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13217                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13218                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13219                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13220                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13221                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13222                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13223                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13224                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13225                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13226                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13227                 0x000000f7, 0x00000000, 0x00000000
13228         };
13229         static const uint16_t gain_a0[] = {
13230                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13231                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13232                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13233                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13234                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13235                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 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                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13242         };
13243
13244         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13245
13246         for (i = 0; i < 704; i++)
13247                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13248
13249         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13250             bwn_tab_sigsq_tbl);
13251         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13252         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13253         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13254         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13255         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13256         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13257         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13258         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13259         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13260         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13261             bwn_tab_pllfrac_tbl);
13262         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13263             bwn_tabl_iqlocal_tbl);
13264         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13265         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13266
13267         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13268             (siba_get_chiprev(sc->sc_dev) == 0)) {
13269                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13270                     gainidx_a0);
13271                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13272                     auxgainidx_a0);
13273                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13274                     gainval_a0);
13275                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13276         }
13277 }
13278
13279 static void
13280 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13281 {
13282         struct bwn_softc *sc = mac->mac_sc;
13283         struct ifnet *ifp = sc->sc_ifp;
13284         struct ieee80211com *ic = ifp->if_l2com;
13285         static struct bwn_txgain_entry txgain_r2[] = {
13286                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13287                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13288                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13289                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13290                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13291                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13292                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13293                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13294                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13295                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13296                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13297                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13298                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13299                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13300                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13301                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13302                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13303                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13304                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13305                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13306                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13307                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13308                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13309                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13310                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13311                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13312                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13313                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13314                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13315                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13316                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13317                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13318                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13319                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13320                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13321                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13322                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13323                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13324                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13325                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13326                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13327                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13328                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13329                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13330                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13331                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13332                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13333                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13334                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13335                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13336                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13337                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13338                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13339                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13340                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13341                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13342                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13343                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13344                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13345                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13346                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13347                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13348                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13349                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13350         };
13351         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13352                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13353                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13354                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13355                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13356                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13357                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13358                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13359                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13360                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13361                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13362                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13363                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13364                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13365                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13366                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13367                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13368                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13369                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13370                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13371                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13372                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13373                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13374                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13375                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13376                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13377                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13378                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13379                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13380                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13381                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13382                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13383                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13384                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13385                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13386                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13387                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13388                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13389                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13390                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13391                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13392                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13393                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13394                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13395                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13396                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13397                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13398                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13399                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13400                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13401                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13402                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13403                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13404                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13405                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13406                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13407                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13408                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13409                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13410                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13411                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13412                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13413                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13414                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13415                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13416         };
13417         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13418                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13419                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13420                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13421                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13422                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13423                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13424                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13425                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13426                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13427                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13428                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13429                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13430                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13431                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13432                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13433                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13434                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13435                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13436                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13437                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13438                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13439                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13440                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13441                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13442                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13443                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13444                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13445                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13446                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13447                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13448                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13449                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13450                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13451                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13452                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13453                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13454                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13455                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13456                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13457                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13458                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13459                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13460                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13461                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13462                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13463                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13464                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13465                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13466                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13467                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13468                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13469                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13470                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13471                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13472                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13473                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13474                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13475                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13476                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13477                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13478                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13479                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13480                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13481                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13482         };
13483         static struct bwn_txgain_entry txgain_r0[] = {
13484                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13485                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13486                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13487                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13488                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13489                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13490                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13491                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13492                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13493                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13494                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13495                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13496                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13497                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13498                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13499                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13500                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13501                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13502                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13503                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13504                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13505                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13506                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13507                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13508                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13509                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13510                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13511                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13512                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13513                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13514                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13515                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13516                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13517                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13518                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13519                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13520                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13521                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13522                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13523                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13524                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13525                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13526                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13527                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13528                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13529                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13530                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13531                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13532                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13533                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13534                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13535                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13536                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13537                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13538                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13539                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13540                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13541                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13542                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13543                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13544                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13545                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13546                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13547                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13548         };
13549         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13550                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13551                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13552                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13553                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13554                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13555                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13556                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13557                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13558                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13559                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13560                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13561                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13562                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13563                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13564                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13565                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13566                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13567                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13568                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13569                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13570                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13571                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13572                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13573                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13574                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13575                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13576                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13577                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13578                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13579                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13580                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13581                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13582                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13583                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13584                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13585                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13586                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13587                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13588                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13589                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13590                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13591                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13592                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13593                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13594                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13595                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13596                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13597                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13598                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13599                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13600                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13601                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13602                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13603                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13604                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13605                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13606                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13607                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13608                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13609                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13610                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13611                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13612                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13613                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13614         };
13615         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13616                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13617                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13618                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13619                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13620                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13621                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13622                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13623                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13624                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13625                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13626                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13627                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13628                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13629                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13630                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13631                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13632                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13633                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13634                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13635                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13636                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13637                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13638                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13639                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13640                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13641                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13642                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13643                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13644                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13645                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13646                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13647                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13648                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13649                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13650                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13651                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13652                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13653                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13654                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13655                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13656                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13657                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13658                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13659                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13660                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13661                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13662                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13663                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13664                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13665                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13666                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13667                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13668                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13669                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13670                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13671                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13672                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13673                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13674                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13675                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13676                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13677                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13678                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13679                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13680         };
13681         static struct bwn_txgain_entry txgain_r1[] = {
13682                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13683                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13684                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13685                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13686                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13687                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13688                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13689                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13690                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13691                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13692                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13693                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13694                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13695                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13696                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13697                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13698                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13699                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13700                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13701                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13702                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13703                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13704                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13705                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13706                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13707                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13708                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13709                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13710                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13711                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13712                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13713                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13714                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13715                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13716                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13717                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13718                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13719                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13720                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13721                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13722                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13723                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13724                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13725                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13726                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13727                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13728                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13729                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13730                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13731                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13732                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13733                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13734                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13735                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13736                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13737                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13738                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13739                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13740                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13741                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13742                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13743                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13744                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13745                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13746                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13747                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13748                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13749                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13750                 { 7, 11, 6, 0, 71 }
13751         };
13752         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13753                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13754                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13755                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13756                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13757                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13758                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13759                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13760                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13761                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13762                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13763                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13764                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13765                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13766                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13767                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13768                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13769                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13770                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13771                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13772                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13773                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13774                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13775                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13776                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13777                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13778                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13779                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13780                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13781                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13782                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13783                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13784                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13785                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13786                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13787                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13788                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13789                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13790                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13791                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13792                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13793                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13794                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13795                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13796                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13797                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13798                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13799                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13800                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13801                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13802                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13803                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13804                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13805                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13806                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13807                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13808                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13809                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13810                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13811                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13812                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13813                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13814                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13815                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13816                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13817         };
13818         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13819                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13820                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13821                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13822                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13823                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13824                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13825                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13826                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13827                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13828                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13829                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13830                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13831                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13832                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13833                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13834                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13835                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13836                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13837                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13838                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13839                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13840                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13841                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13842                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13843                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13844                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13845                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13846                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13847                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13848                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13849                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13850                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13851                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13852                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13853                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13854                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13855                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13856                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13857                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13858                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13859                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13860                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13861                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13862                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13863                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13864                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13865                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13866                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13867                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13868                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13869                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13870                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13871                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13872                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13873                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13874                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13875                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13876                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13877                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13878                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13879                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13880                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13881                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13882                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13883         };
13884
13885         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13886                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13887                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13888                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13889                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13890                             txgain_2ghz_r2);
13891                 else
13892                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13893                             txgain_5ghz_r2);
13894                 return;
13895         }
13896
13897         if (mac->mac_phy.rev == 0) {
13898                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13899                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13900                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13901                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13902                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13903                             txgain_2ghz_r0);
13904                 else
13905                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13906                             txgain_5ghz_r0);
13907                 return;
13908         }
13909
13910         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13911             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13912                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13913         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13914                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13915         else
13916                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13917 }
13918
13919 static void
13920 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13921 {
13922         uint32_t offset, type;
13923
13924         type = BWN_TAB_GETTYPE(typeoffset);
13925         offset = BWN_TAB_GETOFFSET(typeoffset);
13926         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13927
13928         switch (type) {
13929         case BWN_TAB_8BIT:
13930                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13931                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13932                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13933                 break;
13934         case BWN_TAB_16BIT:
13935                 KASSERT(!(value & ~0xffff),
13936                     ("%s:%d: fail", __func__, __LINE__));
13937                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13938                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13939                 break;
13940         case BWN_TAB_32BIT:
13941                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13942                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13943                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13944                 break;
13945         default:
13946                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13947         }
13948 }
13949
13950 static int
13951 bwn_phy_lp_loopback(struct bwn_mac *mac)
13952 {
13953         struct bwn_phy_lp_iq_est ie;
13954         int i, index = -1;
13955         uint32_t tmp;
13956
13957         memset(&ie, 0, sizeof(ie));
13958
13959         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13960         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13961         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13962         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13963         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13964         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13965         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13966         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13967         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13968         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13969         for (i = 0; i < 32; i++) {
13970                 bwn_phy_lp_set_rxgain_idx(mac, i);
13971                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13972                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13973                         continue;
13974                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13975                 if ((tmp > 4000) && (tmp < 10000)) {
13976                         index = i;
13977                         break;
13978                 }
13979         }
13980         bwn_phy_lp_ddfs_turnoff(mac);
13981         return (index);
13982 }
13983
13984 static void
13985 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13986 {
13987
13988         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13989 }
13990
13991 static void
13992 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13993     int incr1, int incr2, int scale_idx)
13994 {
13995
13996         bwn_phy_lp_ddfs_turnoff(mac);
13997         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13998         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13999         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14000         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14001         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14002         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14003         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14004         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14005         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14006         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14007 }
14008
14009 static uint8_t
14010 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14011     struct bwn_phy_lp_iq_est *ie)
14012 {
14013         int i;
14014
14015         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14016         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14017         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14018         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14019         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14020
14021         for (i = 0; i < 500; i++) {
14022                 if (!(BWN_PHY_READ(mac,
14023                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14024                         break;
14025                 DELAY(1000);
14026         }
14027         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14028                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14029                 return 0;
14030         }
14031
14032         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14033         ie->ie_iqprod <<= 16;
14034         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14035         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14036         ie->ie_ipwr <<= 16;
14037         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14038         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14039         ie->ie_qpwr <<= 16;
14040         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14041
14042         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14043         return 1;
14044 }
14045
14046 static uint32_t
14047 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14048 {
14049         uint32_t offset, type, value;
14050
14051         type = BWN_TAB_GETTYPE(typeoffset);
14052         offset = BWN_TAB_GETOFFSET(typeoffset);
14053         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14054
14055         switch (type) {
14056         case BWN_TAB_8BIT:
14057                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14058                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14059                 break;
14060         case BWN_TAB_16BIT:
14061                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14062                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14063                 break;
14064         case BWN_TAB_32BIT:
14065                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14066                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14067                 value <<= 16;
14068                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14069                 break;
14070         default:
14071                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14072                 value = 0;
14073         }
14074
14075         return (value);
14076 }
14077
14078 static void
14079 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14080 {
14081
14082         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14083         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14084 }
14085
14086 static void
14087 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14088 {
14089         uint16_t ctl;
14090
14091         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14092         ctl |= dac << 7;
14093         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14094 }
14095
14096 static void
14097 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14098 {
14099
14100         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14101         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14102 }
14103
14104 static void
14105 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14106 {
14107
14108         if (mac->mac_phy.rev < 2)
14109                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14110         else {
14111                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14112                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14113         }
14114         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14115 }
14116
14117 static uint16_t
14118 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14119 {
14120
14121         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14122 }
14123
14124 static uint8_t
14125 bwn_nbits(int32_t val)
14126 {
14127         uint32_t tmp;
14128         uint8_t nbits = 0;
14129
14130         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14131                 nbits++;
14132         return (nbits);
14133 }
14134
14135 static void
14136 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14137     struct bwn_txgain_entry *table)
14138 {
14139         int i;
14140
14141         for (i = offset; i < count; i++)
14142                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14143 }
14144
14145 static void
14146 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14147     struct bwn_txgain_entry data)
14148 {
14149
14150         if (mac->mac_phy.rev >= 2)
14151                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14152         else
14153                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14154 }
14155
14156 static void
14157 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14158     struct bwn_txgain_entry te)
14159 {
14160         struct bwn_softc *sc = mac->mac_sc;
14161         struct ifnet *ifp = sc->sc_ifp;
14162         struct ieee80211com *ic = ifp->if_l2com;
14163         uint32_t tmp;
14164
14165         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14166
14167         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14168         if (mac->mac_phy.rev >= 3) {
14169                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14170                     (0x10 << 24) : (0x70 << 24));
14171         } else {
14172                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14173                     (0x14 << 24) : (0x7f << 24));
14174         }
14175         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14176         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14177             te.te_bbmult << 20 | te.te_dac << 28);
14178 }
14179
14180 static void
14181 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14182     struct bwn_txgain_entry te)
14183 {
14184
14185         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14186
14187         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14188             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14189             te.te_dac);
14190         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14191 }
14192
14193 static void
14194 bwn_sysctl_node(struct bwn_softc *sc)
14195 {
14196         device_t dev = sc->sc_dev;
14197         struct bwn_mac *mac;
14198         struct bwn_stats *stats;
14199
14200         /* XXX assume that count of MAC is only 1. */
14201
14202         if ((mac = sc->sc_curmac) == NULL)
14203                 return;
14204         stats = &mac->mac_stats;
14205
14206         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14207             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14208             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14209         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14210             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14211             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14212         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14213             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14214             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14215
14216 #ifdef BWN_DEBUG
14217         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14218             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14219             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14220 #endif
14221 }
14222
14223 static device_method_t bwn_methods[] = {
14224         /* Device interface */
14225         DEVMETHOD(device_probe,         bwn_probe),
14226         DEVMETHOD(device_attach,        bwn_attach),
14227         DEVMETHOD(device_detach,        bwn_detach),
14228         DEVMETHOD(device_suspend,       bwn_suspend),
14229         DEVMETHOD(device_resume,        bwn_resume),
14230         DEVMETHOD_END
14231 };
14232 static driver_t bwn_driver = {
14233         "bwn",
14234         bwn_methods,
14235         sizeof(struct bwn_softc)
14236 };
14237 static devclass_t bwn_devclass;
14238 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14239 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14240 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14241 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14242 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);