]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/dev/bwn/if_bwn.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
72
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
75
76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
77
78 /*
79  * Tunable & sysctl variables.
80  */
81
82 #ifdef BWN_DEBUG
83 static  int bwn_debug = 0;
84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
85     "Broadcom debugging printfs");
86 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
87 enum {
88         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
89         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
90         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
91         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
92         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
93         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
94         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
95         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
96         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
97         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
98         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
99         BWN_DEBUG_LED           = 0x00000800,   /* led management */
100         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
101         BWN_DEBUG_LO            = 0x00002000,   /* LO */
102         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
103         BWN_DEBUG_WME           = 0x00008000,   /* WME */
104         BWN_DEBUG_RF            = 0x00010000,   /* RF */
105         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
106         BWN_DEBUG_ANY           = 0xffffffff
107 };
108 #define DPRINTF(sc, m, fmt, ...) do {                   \
109         if (sc->sc_debug & (m))                         \
110                 printf(fmt, __VA_ARGS__);               \
111 } while (0)
112 #else
113 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
114 #endif
115
116 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
118     "uses Bad Frames Preemption");
119 static int      bwn_bluetooth = 1;
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
121     "turns on Bluetooth Coexistence");
122 static int      bwn_hwpctl = 0;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
124     "uses H/W power control");
125 static int      bwn_msi_disable = 0;            /* MSI disabled  */
126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
127 static int      bwn_usedma = 1;
128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
129     "uses DMA");
130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
131 static int      bwn_wme = 1;
132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
133     "uses WME support");
134
135 static int      bwn_attach_pre(struct bwn_softc *);
136 static int      bwn_attach_post(struct bwn_softc *);
137 static void     bwn_sprom_bugfixes(device_t);
138 static void     bwn_init(void *);
139 static int      bwn_init_locked(struct bwn_softc *);
140 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t);
141 static void     bwn_start(struct ifnet *);
142 static int      bwn_attach_core(struct bwn_mac *);
143 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
144 static int      bwn_phy_getinfo(struct bwn_mac *, int);
145 static int      bwn_chiptest(struct bwn_mac *);
146 static int      bwn_setup_channels(struct bwn_mac *, int, int);
147 static int      bwn_phy_g_attach(struct bwn_mac *);
148 static void     bwn_phy_g_detach(struct bwn_mac *);
149 static void     bwn_phy_g_init_pre(struct bwn_mac *);
150 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
151 static int      bwn_phy_g_init(struct bwn_mac *);
152 static void     bwn_phy_g_exit(struct bwn_mac *);
153 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
154 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
155                     uint16_t);
156 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
157 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
158                     uint16_t);
159 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
160 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
161 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
162 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
163 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
164 static int      bwn_phy_g_im(struct bwn_mac *, int);
165 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
166 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
167 static void     bwn_phy_g_task_15s(struct bwn_mac *);
168 static void     bwn_phy_g_task_60s(struct bwn_mac *);
169 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
170 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
171 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
172 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
173                     uint16_t);
174 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
175 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
176                     uint32_t);
177 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
178                     uint16_t);
179 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
180                     const struct bwn_channelinfo *, int);
181 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
182                     const struct ieee80211_bpf_params *);
183 static void     bwn_updateslot(struct ifnet *);
184 static void     bwn_update_promisc(struct ifnet *);
185 static void     bwn_wme_init(struct bwn_mac *);
186 static int      bwn_wme_update(struct ieee80211com *);
187 static void     bwn_wme_clear(struct bwn_softc *);
188 static void     bwn_wme_load(struct bwn_mac *);
189 static void     bwn_wme_loadparams(struct bwn_mac *,
190                     const struct wmeParams *, uint16_t);
191 static void     bwn_scan_start(struct ieee80211com *);
192 static void     bwn_scan_end(struct ieee80211com *);
193 static void     bwn_set_channel(struct ieee80211com *);
194 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
195                     const char [IFNAMSIZ], int, int,
196                     int, const uint8_t [IEEE80211_ADDR_LEN],
197                     const uint8_t [IEEE80211_ADDR_LEN]);
198 static void     bwn_vap_delete(struct ieee80211vap *);
199 static void     bwn_stop(struct bwn_softc *, int);
200 static void     bwn_stop_locked(struct bwn_softc *, int);
201 static int      bwn_core_init(struct bwn_mac *);
202 static void     bwn_core_start(struct bwn_mac *);
203 static void     bwn_core_exit(struct bwn_mac *);
204 static void     bwn_bt_disable(struct bwn_mac *);
205 static int      bwn_chip_init(struct bwn_mac *);
206 static uint64_t bwn_hf_read(struct bwn_mac *);
207 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void     bwn_set_txretry(struct bwn_mac *, int, int);
209 static void     bwn_rate_init(struct bwn_mac *);
210 static void     bwn_set_phytxctl(struct bwn_mac *);
211 static void     bwn_spu_setdelay(struct bwn_mac *, int);
212 static void     bwn_bt_enable(struct bwn_mac *);
213 static void     bwn_set_macaddr(struct bwn_mac *);
214 static void     bwn_crypt_init(struct bwn_mac *);
215 static void     bwn_chip_exit(struct bwn_mac *);
216 static int      bwn_fw_fillinfo(struct bwn_mac *);
217 static int      bwn_fw_loaducode(struct bwn_mac *);
218 static int      bwn_gpio_init(struct bwn_mac *);
219 static int      bwn_fw_loadinitvals(struct bwn_mac *);
220 static int      bwn_phy_init(struct bwn_mac *);
221 static void     bwn_set_txantenna(struct bwn_mac *, int);
222 static void     bwn_set_opmode(struct bwn_mac *);
223 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t  bwn_plcp_getcck(const uint8_t);
225 static uint8_t  bwn_plcp_getofdm(const uint8_t);
226 static void     bwn_pio_init(struct bwn_mac *);
227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
228 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
229                     int);
230 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
231                     struct bwn_pio_rxqueue *, int);
232 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
234                     uint16_t);
235 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void     bwn_pio_handle_txeof(struct bwn_mac *,
239                     const struct bwn_txstatus *);
240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
243                     uint16_t);
244 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
245                     uint32_t);
246 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
247                     struct mbuf *);
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
250                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
252                     uint16_t, uint32_t);
253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
254                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
256                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258                     uint16_t, struct bwn_pio_txpkt **);
259 static void     bwn_dma_init(struct bwn_mac *);
260 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int      bwn_dma_mask2type(uint64_t);
262 static uint64_t bwn_dma_mask(struct bwn_mac *);
263 static uint16_t bwn_dma_base(int, int);
264 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
266                     int, struct bwn_dmadesc_generic **,
267                     struct bwn_dmadesc_meta **);
268 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
269                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
270                     int, int);
271 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
277                     int, struct bwn_dmadesc_generic **,
278                     struct bwn_dmadesc_meta **);
279 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
280                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
281                     int, int);
282 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void     bwn_dma_setup(struct bwn_dma_ring *);
289 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void     bwn_dma_rx(struct bwn_dma_ring *);
294 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
296                     struct bwn_dmadesc_meta *);
297 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int      bwn_dma_gettype(struct bwn_mac *);
299 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
304                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
305                     int);
306 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
307                     bus_size_t, int);
308 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void     bwn_dma_handle_txeof(struct bwn_mac *,
310                     const struct bwn_txstatus *);
311 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
312                     struct mbuf *);
313 static int      bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
315                     uint8_t);
316 static int      bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
318                     int, int, int);
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320                     const struct bwn_txstatus *, uint16_t, int *);
321 static void     bwn_dma_free(struct bwn_mac *);
322 static void     bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
324 static void     bwn_phy_init_b5(struct bwn_mac *);
325 static void     bwn_phy_init_b6(struct bwn_mac *);
326 static void     bwn_phy_init_a(struct bwn_mac *);
327 static void     bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void     bwn_lo_g_init(struct bwn_mac *);
330 static void     bwn_lo_g_adjust(struct bwn_mac *);
331 static void     bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333                     const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338                     const struct bwn_bbatt *, const struct bwn_rfatt *,
339                     uint8_t);
340 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void     bwn_wa_init(struct bwn_mac *);
344 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
345                     uint16_t);
346 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
348                     uint32_t);
349 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
350                     uint16_t);
351 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void     bwn_mac_suspend(struct bwn_mac *);
353 static void     bwn_mac_enable(struct bwn_mac *);
354 static void     bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void     bwn_nrssi_offset(struct bwn_mac *);
357 static void     bwn_nrssi_threshold(struct bwn_mac *);
358 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360                     int16_t);
361 static void     bwn_set_original_gains(struct bwn_mac *);
362 static void     bwn_hwpctl_early_init(struct bwn_mac *);
363 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t bwn_phy_g_chan2freq(uint8_t);
365 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367                     const char *, struct bwn_fwfile *);
368 static void     bwn_release_firmware(struct bwn_mac *);
369 static void     bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371 static int      bwn_fwinitvals_write(struct bwn_mac *,
372                     const struct bwn_fwinitvals *, size_t, size_t);
373 static int      bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t bwn_ant2phy(int);
375 static void     bwn_mac_write_bssid(struct bwn_mac *);
376 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377                     const uint8_t *);
378 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379                     const uint8_t *, size_t, const uint8_t *);
380 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
381                     const uint8_t *);
382 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
383                     const uint8_t *);
384 static void     bwn_phy_exit(struct bwn_mac *);
385 static void     bwn_core_stop(struct bwn_mac *);
386 static int      bwn_switch_band(struct bwn_softc *,
387                     struct ieee80211_channel *);
388 static void     bwn_phy_reset(struct bwn_mac *);
389 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void     bwn_set_pretbtt(struct bwn_mac *);
391 static int      bwn_intr(void *);
392 static void     bwn_intrtask(void *, int);
393 static void     bwn_restart(struct bwn_mac *, const char *);
394 static void     bwn_intr_ucode_debug(struct bwn_mac *);
395 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void     bwn_intr_atim_end(struct bwn_mac *);
397 static void     bwn_intr_beacon(struct bwn_mac *);
398 static void     bwn_intr_pmq(struct bwn_mac *);
399 static void     bwn_intr_noise(struct bwn_mac *);
400 static void     bwn_intr_txeof(struct bwn_mac *);
401 static void     bwn_hwreset(void *, int);
402 static void     bwn_handle_fwpanic(struct bwn_mac *);
403 static void     bwn_load_beacon0(struct bwn_mac *);
404 static void     bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t bwn_jssi_read(struct bwn_mac *);
406 static void     bwn_noise_gensample(struct bwn_mac *);
407 static void     bwn_handle_txeof(struct bwn_mac *,
408                     const struct bwn_txstatus *);
409 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static void     bwn_start_locked(struct ifnet *);
412 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
413                     struct mbuf *);
414 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
415 static int      bwn_set_txhdr(struct bwn_mac *,
416                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
417                     uint16_t);
418 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
419                     const uint8_t);
420 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
421 static uint8_t  bwn_get_fbrate(uint8_t);
422 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
423 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
424 static void     bwn_phy_lock(struct bwn_mac *);
425 static void     bwn_phy_unlock(struct bwn_mac *);
426 static void     bwn_rf_lock(struct bwn_mac *);
427 static void     bwn_rf_unlock(struct bwn_mac *);
428 static void     bwn_txpwr(void *, int);
429 static void     bwn_tasks(void *);
430 static void     bwn_task_15s(struct bwn_mac *);
431 static void     bwn_task_30s(struct bwn_mac *);
432 static void     bwn_task_60s(struct bwn_mac *);
433 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
434                     uint8_t);
435 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
436 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
437                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
438                     int, int);
439 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
440 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
441 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
442 static void     bwn_watchdog(void *);
443 static void     bwn_dma_stop(struct bwn_mac *);
444 static void     bwn_pio_stop(struct bwn_mac *);
445 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
446 static void     bwn_led_attach(struct bwn_mac *);
447 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
448 static void     bwn_led_event(struct bwn_mac *, int);
449 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
450 static void     bwn_led_blink_next(void *);
451 static void     bwn_led_blink_end(void *);
452 static void     bwn_rfswitch(void *);
453 static void     bwn_rf_turnon(struct bwn_mac *);
454 static void     bwn_rf_turnoff(struct bwn_mac *);
455 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
456 static int      bwn_phy_lp_init(struct bwn_mac *);
457 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
458 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
459 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
460                     uint16_t);
461 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
462 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
464 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
465 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
466 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
467 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
468 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
469 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
470 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
471 static void     bwn_phy_lp_calib(struct bwn_mac *);
472 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
473 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
474 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
475 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
476 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
477 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
478 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
479 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
480 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
481 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
482 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
483 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
484 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
485 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
486 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
487 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
488 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
489 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
490 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
491 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
492 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
493 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
494                     const void *);
495 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
496 static struct bwn_txgain
497                 bwn_phy_lp_get_txgain(struct bwn_mac *);
498 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
499 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
500 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
501 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
502 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
503 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
504 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
505 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
506 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
507 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
508 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
509 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
510 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
511 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
512 static int      bwn_phy_lp_loopback(struct bwn_mac *);
513 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
514 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
515                     int);
516 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
517                     struct bwn_phy_lp_iq_est *);
518 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
519 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
520 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
521 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
522 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
523 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
524 static uint8_t  bwn_nbits(int32_t);
525 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
526                     struct bwn_txgain_entry *);
527 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
528                     struct bwn_txgain_entry);
529 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
530                     struct bwn_txgain_entry);
531 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
532                     struct bwn_txgain_entry);
533 static void     bwn_sysctl_node(struct bwn_softc *);
534
535 static struct resource_spec bwn_res_spec_legacy[] = {
536         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
537         { -1,                   0,              0 }
538 };
539
540 static struct resource_spec bwn_res_spec_msi[] = {
541         { SYS_RES_IRQ,          1,              RF_ACTIVE },
542         { -1,                   0,              0 }
543 };
544
545 static const struct bwn_channelinfo bwn_chantable_bg = {
546         .channels = {
547                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
548                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
549                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
550                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
551                 { 2472, 13, 30 }, { 2484, 14, 30 } },
552         .nchannels = 14
553 };
554
555 static const struct bwn_channelinfo bwn_chantable_a = {
556         .channels = {
557                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
558                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
559                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
560                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
561                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
562                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
563                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
564                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
565                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
566                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
567                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
568                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
569                 { 6080, 216, 30 } },
570         .nchannels = 37
571 };
572
573 static const struct bwn_channelinfo bwn_chantable_n = {
574         .channels = {
575                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
576                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
577                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
578                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
579                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
580                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
581                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
582                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
583                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
584                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
585                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
586                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
587                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
588                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
589                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
590                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
591                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
592                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
593                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
594                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
595                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
596                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
597                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
598                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
599                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
600                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
601                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
602                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
603                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
604                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
605                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
606                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
607                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
608                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
609                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
610                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
611                 { 6130, 226, 30 }, { 6140, 228, 30 } },
612         .nchannels = 110
613 };
614
615 static const uint8_t bwn_b2063_chantable_data[33][12] = {
616         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
622         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
623         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
624         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
628         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
629         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
630         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
633         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
634         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
635         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
649 };
650
651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
652         { 1, 2412, bwn_b2063_chantable_data[0] },
653         { 2, 2417, bwn_b2063_chantable_data[0] },
654         { 3, 2422, bwn_b2063_chantable_data[0] },
655         { 4, 2427, bwn_b2063_chantable_data[1] },
656         { 5, 2432, bwn_b2063_chantable_data[1] },
657         { 6, 2437, bwn_b2063_chantable_data[1] },
658         { 7, 2442, bwn_b2063_chantable_data[1] },
659         { 8, 2447, bwn_b2063_chantable_data[1] },
660         { 9, 2452, bwn_b2063_chantable_data[2] },
661         { 10, 2457, bwn_b2063_chantable_data[2] },
662         { 11, 2462, bwn_b2063_chantable_data[3] },
663         { 12, 2467, bwn_b2063_chantable_data[3] },
664         { 13, 2472, bwn_b2063_chantable_data[3] },
665         { 14, 2484, bwn_b2063_chantable_data[4] },
666         { 34, 5170, bwn_b2063_chantable_data[5] },
667         { 36, 5180, bwn_b2063_chantable_data[6] },
668         { 38, 5190, bwn_b2063_chantable_data[7] },
669         { 40, 5200, bwn_b2063_chantable_data[8] },
670         { 42, 5210, bwn_b2063_chantable_data[9] },
671         { 44, 5220, bwn_b2063_chantable_data[10] },
672         { 46, 5230, bwn_b2063_chantable_data[11] },
673         { 48, 5240, bwn_b2063_chantable_data[12] },
674         { 52, 5260, bwn_b2063_chantable_data[13] },
675         { 56, 5280, bwn_b2063_chantable_data[14] },
676         { 60, 5300, bwn_b2063_chantable_data[14] },
677         { 64, 5320, bwn_b2063_chantable_data[15] },
678         { 100, 5500, bwn_b2063_chantable_data[16] },
679         { 104, 5520, bwn_b2063_chantable_data[17] },
680         { 108, 5540, bwn_b2063_chantable_data[18] },
681         { 112, 5560, bwn_b2063_chantable_data[19] },
682         { 116, 5580, bwn_b2063_chantable_data[20] },
683         { 120, 5600, bwn_b2063_chantable_data[21] },
684         { 124, 5620, bwn_b2063_chantable_data[21] },
685         { 128, 5640, bwn_b2063_chantable_data[22] },
686         { 132, 5660, bwn_b2063_chantable_data[22] },
687         { 136, 5680, bwn_b2063_chantable_data[22] },
688         { 140, 5700, bwn_b2063_chantable_data[23] },
689         { 149, 5745, bwn_b2063_chantable_data[23] },
690         { 153, 5765, bwn_b2063_chantable_data[23] },
691         { 157, 5785, bwn_b2063_chantable_data[23] },
692         { 161, 5805, bwn_b2063_chantable_data[23] },
693         { 165, 5825, bwn_b2063_chantable_data[23] },
694         { 184, 4920, bwn_b2063_chantable_data[24] },
695         { 188, 4940, bwn_b2063_chantable_data[25] },
696         { 192, 4960, bwn_b2063_chantable_data[26] },
697         { 196, 4980, bwn_b2063_chantable_data[27] },
698         { 200, 5000, bwn_b2063_chantable_data[28] },
699         { 204, 5020, bwn_b2063_chantable_data[29] },
700         { 208, 5040, bwn_b2063_chantable_data[30] },
701         { 212, 5060, bwn_b2063_chantable_data[31] },
702         { 216, 5080, bwn_b2063_chantable_data[32] }
703 };
704
705 static const uint8_t bwn_b2062_chantable_data[22][12] = {
706         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
707         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
727         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
728 };
729
730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
731         { 1, 2412, bwn_b2062_chantable_data[0] },
732         { 2, 2417, bwn_b2062_chantable_data[0] },
733         { 3, 2422, bwn_b2062_chantable_data[0] },
734         { 4, 2427, bwn_b2062_chantable_data[0] },
735         { 5, 2432, bwn_b2062_chantable_data[0] },
736         { 6, 2437, bwn_b2062_chantable_data[0] },
737         { 7, 2442, bwn_b2062_chantable_data[0] },
738         { 8, 2447, bwn_b2062_chantable_data[0] },
739         { 9, 2452, bwn_b2062_chantable_data[0] },
740         { 10, 2457, bwn_b2062_chantable_data[0] },
741         { 11, 2462, bwn_b2062_chantable_data[0] },
742         { 12, 2467, bwn_b2062_chantable_data[0] },
743         { 13, 2472, bwn_b2062_chantable_data[0] },
744         { 14, 2484, bwn_b2062_chantable_data[0] },
745         { 34, 5170, bwn_b2062_chantable_data[1] },
746         { 38, 5190, bwn_b2062_chantable_data[2] },
747         { 42, 5210, bwn_b2062_chantable_data[2] },
748         { 46, 5230, bwn_b2062_chantable_data[3] },
749         { 36, 5180, bwn_b2062_chantable_data[4] },
750         { 40, 5200, bwn_b2062_chantable_data[5] },
751         { 44, 5220, bwn_b2062_chantable_data[6] },
752         { 48, 5240, bwn_b2062_chantable_data[3] },
753         { 52, 5260, bwn_b2062_chantable_data[3] },
754         { 56, 5280, bwn_b2062_chantable_data[3] },
755         { 60, 5300, bwn_b2062_chantable_data[7] },
756         { 64, 5320, bwn_b2062_chantable_data[8] },
757         { 100, 5500, bwn_b2062_chantable_data[9] },
758         { 104, 5520, bwn_b2062_chantable_data[10] },
759         { 108, 5540, bwn_b2062_chantable_data[10] },
760         { 112, 5560, bwn_b2062_chantable_data[10] },
761         { 116, 5580, bwn_b2062_chantable_data[11] },
762         { 120, 5600, bwn_b2062_chantable_data[12] },
763         { 124, 5620, bwn_b2062_chantable_data[12] },
764         { 128, 5640, bwn_b2062_chantable_data[12] },
765         { 132, 5660, bwn_b2062_chantable_data[12] },
766         { 136, 5680, bwn_b2062_chantable_data[12] },
767         { 140, 5700, bwn_b2062_chantable_data[12] },
768         { 149, 5745, bwn_b2062_chantable_data[12] },
769         { 153, 5765, bwn_b2062_chantable_data[12] },
770         { 157, 5785, bwn_b2062_chantable_data[12] },
771         { 161, 5805, bwn_b2062_chantable_data[12] },
772         { 165, 5825, bwn_b2062_chantable_data[12] },
773         { 184, 4920, bwn_b2062_chantable_data[13] },
774         { 188, 4940, bwn_b2062_chantable_data[14] },
775         { 192, 4960, bwn_b2062_chantable_data[15] },
776         { 196, 4980, bwn_b2062_chantable_data[16] },
777         { 200, 5000, bwn_b2062_chantable_data[17] },
778         { 204, 5020, bwn_b2062_chantable_data[18] },
779         { 208, 5040, bwn_b2062_chantable_data[19] },
780         { 212, 5060, bwn_b2062_chantable_data[20] },
781         { 216, 5080, bwn_b2062_chantable_data[21] }
782 };
783
784 /* for LP PHY */
785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
786         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
787         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
788         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
789         { 13, -66, 13 }, { 14, -66, 13 },
790 };
791
792 /* for LP PHY */
793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
794         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
795         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
796         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
797         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
798         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
799         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
800         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
801         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
802         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
803         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
804         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
805         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
806         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
807 };
808
809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
810
811 static const uint8_t bwn_tab_sigsq_tbl[] = {
812         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
813         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
814         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
816         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
817         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
818 };
819
820 static const uint8_t bwn_tab_pllfrac_tbl[] = {
821         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
822         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
823 };
824
825 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
826         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
827         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
828         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
830         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
831         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
832         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838 };
839
840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
846
847 #define VENDOR_LED_ACT(vendor)                          \
848 {                                                       \
849         .vid = PCI_VENDOR_##vendor,                     \
850         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
851 }
852
853 static const struct {
854         uint16_t        vid;
855         uint8_t         led_act[BWN_LED_MAX];
856 } bwn_vendor_led_act[] = {
857         VENDOR_LED_ACT(COMPAQ),
858         VENDOR_LED_ACT(ASUSTEK)
859 };
860
861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
862         { BWN_VENDOR_LED_ACT_DEFAULT };
863
864 #undef VENDOR_LED_ACT
865
866 static const struct {
867         int             on_dur;
868         int             off_dur;
869 } bwn_led_duration[109] = {
870         [0]     = { 400, 100 },
871         [2]     = { 150, 75 },
872         [4]     = { 90, 45 },
873         [11]    = { 66, 34 },
874         [12]    = { 53, 26 },
875         [18]    = { 42, 21 },
876         [22]    = { 35, 17 },
877         [24]    = { 32, 16 },
878         [36]    = { 21, 10 },
879         [48]    = { 16, 8 },
880         [72]    = { 11, 5 },
881         [96]    = { 9, 4 },
882         [108]   = { 7, 3 }
883 };
884
885 static const uint16_t bwn_wme_shm_offsets[] = {
886         [0] = BWN_WME_BESTEFFORT,
887         [1] = BWN_WME_BACKGROUND,
888         [2] = BWN_WME_VOICE,
889         [3] = BWN_WME_VIDEO,
890 };
891
892 static const struct siba_devid bwn_devs[] = {
893         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
894         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
895         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
896         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
897         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
898         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
899         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
900         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
901         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
902 };
903
904 static int
905 bwn_probe(device_t dev)
906 {
907         int i;
908
909         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
910                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
911                     siba_get_device(dev) == bwn_devs[i].sd_device &&
912                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
913                         return (BUS_PROBE_DEFAULT);
914         }
915
916         return (ENXIO);
917 }
918
919 static int
920 bwn_attach(device_t dev)
921 {
922         struct bwn_mac *mac;
923         struct bwn_softc *sc = device_get_softc(dev);
924         int error, i, msic, reg;
925
926         sc->sc_dev = dev;
927 #ifdef BWN_DEBUG
928         sc->sc_debug = bwn_debug;
929 #endif
930
931         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
932                 error = bwn_attach_pre(sc);
933                 if (error != 0)
934                         return (error);
935                 bwn_sprom_bugfixes(dev);
936                 sc->sc_flags |= BWN_FLAG_ATTACHED;
937         }
938
939         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
940                 if (siba_get_pci_device(dev) != 0x4313 &&
941                     siba_get_pci_device(dev) != 0x431a &&
942                     siba_get_pci_device(dev) != 0x4321) {
943                         device_printf(sc->sc_dev,
944                             "skip 802.11 cores\n");
945                         return (ENODEV);
946                 }
947         }
948
949         mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
950             M_NOWAIT | M_ZERO);
951         if (mac == NULL)
952                 return (ENOMEM);
953         mac->mac_sc = sc;
954         mac->mac_status = BWN_MAC_STATUS_UNINIT;
955         if (bwn_bfp != 0)
956                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
957
958         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
959         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
960         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
961
962         error = bwn_attach_core(mac);
963         if (error)
964                 goto fail0;
965         bwn_led_attach(mac);
966
967         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
968             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
969             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
970             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
971             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
972             mac->mac_phy.rf_rev);
973         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
974                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
975                     mac->mac_method.dma.dmatype);
976         else
977                 device_printf(sc->sc_dev, "PIO\n");
978
979         /*
980          * setup PCI resources and interrupt.
981          */
982         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
983                 msic = pci_msi_count(dev);
984                 if (bootverbose)
985                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
986         } else
987                 msic = 0;
988
989         mac->mac_intr_spec = bwn_res_spec_legacy;
990         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
991                 if (pci_alloc_msi(dev, &msic) == 0) {
992                         device_printf(sc->sc_dev,
993                             "Using %d MSI messages\n", msic);
994                         mac->mac_intr_spec = bwn_res_spec_msi;
995                         mac->mac_msi = 1;
996                 }
997         }
998
999         error = bus_alloc_resources(dev, mac->mac_intr_spec,
1000             mac->mac_res_irq);
1001         if (error) {
1002                 device_printf(sc->sc_dev,
1003                     "couldn't allocate IRQ resources (%d)\n", error);
1004                 goto fail1;
1005         }
1006
1007         if (mac->mac_msi == 0)
1008                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1009                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1010                     &mac->mac_intrhand[0]);
1011         else {
1012                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1013                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1014                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1015                             &mac->mac_intrhand[i]);
1016                         if (error != 0) {
1017                                 device_printf(sc->sc_dev,
1018                                     "couldn't setup interrupt (%d)\n", error);
1019                                 break;
1020                         }
1021                 }
1022         }
1023
1024         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1025
1026         /*
1027          * calls attach-post routine
1028          */
1029         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1030                 bwn_attach_post(sc);
1031
1032         return (0);
1033 fail1:
1034         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1035                 pci_release_msi(dev);
1036 fail0:
1037         free(mac, M_DEVBUF);
1038         return (error);
1039 }
1040
1041 static int
1042 bwn_is_valid_ether_addr(uint8_t *addr)
1043 {
1044         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1045
1046         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1047                 return (FALSE);
1048
1049         return (TRUE);
1050 }
1051
1052 static int
1053 bwn_attach_post(struct bwn_softc *sc)
1054 {
1055         struct ieee80211com *ic;
1056         struct ifnet *ifp = sc->sc_ifp;
1057
1058         ic = ifp->if_l2com;
1059         ic->ic_ifp = ifp;
1060         /* XXX not right but it's not used anywhere important */
1061         ic->ic_phytype = IEEE80211_T_OFDM;
1062         ic->ic_opmode = IEEE80211_M_STA;
1063         ic->ic_caps =
1064                   IEEE80211_C_STA               /* station mode supported */
1065                 | IEEE80211_C_MONITOR           /* monitor mode */
1066                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1067                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1068                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1069                 | IEEE80211_C_WME               /* WME/WMM supported */
1070                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1071                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1072                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1073                 ;
1074
1075         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1076
1077         /* call MI attach routine. */
1078         ieee80211_ifattach(ic,
1079             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1080             siba_sprom_get_mac_80211a(sc->sc_dev) :
1081             siba_sprom_get_mac_80211bg(sc->sc_dev));
1082
1083         ic->ic_headroom = sizeof(struct bwn_txhdr);
1084
1085         /* override default methods */
1086         ic->ic_raw_xmit = bwn_raw_xmit;
1087         ic->ic_updateslot = bwn_updateslot;
1088         ic->ic_update_promisc = bwn_update_promisc;
1089         ic->ic_wme.wme_update = bwn_wme_update;
1090
1091         ic->ic_scan_start = bwn_scan_start;
1092         ic->ic_scan_end = bwn_scan_end;
1093         ic->ic_set_channel = bwn_set_channel;
1094
1095         ic->ic_vap_create = bwn_vap_create;
1096         ic->ic_vap_delete = bwn_vap_delete;
1097
1098         ieee80211_radiotap_attach(ic,
1099             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1100             BWN_TX_RADIOTAP_PRESENT,
1101             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1102             BWN_RX_RADIOTAP_PRESENT);
1103
1104         bwn_sysctl_node(sc);
1105
1106         if (bootverbose)
1107                 ieee80211_announce(ic);
1108         return (0);
1109 }
1110
1111 static void
1112 bwn_phy_detach(struct bwn_mac *mac)
1113 {
1114
1115         if (mac->mac_phy.detach != NULL)
1116                 mac->mac_phy.detach(mac);
1117 }
1118
1119 static int
1120 bwn_detach(device_t dev)
1121 {
1122         struct bwn_softc *sc = device_get_softc(dev);
1123         struct bwn_mac *mac = sc->sc_curmac;
1124         struct ifnet *ifp = sc->sc_ifp;
1125         struct ieee80211com *ic = ifp->if_l2com;
1126         int i;
1127
1128         sc->sc_flags |= BWN_FLAG_INVALID;
1129
1130         if (device_is_attached(sc->sc_dev)) {
1131                 bwn_stop(sc, 1);
1132                 bwn_dma_free(mac);
1133                 callout_drain(&sc->sc_led_blink_ch);
1134                 callout_drain(&sc->sc_rfswitch_ch);
1135                 callout_drain(&sc->sc_task_ch);
1136                 callout_drain(&sc->sc_watchdog_ch);
1137                 bwn_phy_detach(mac);
1138                 if (ifp != NULL) {
1139                         ieee80211_draintask(ic, &mac->mac_hwreset);
1140                         ieee80211_draintask(ic, &mac->mac_txpower);
1141                         ieee80211_ifdetach(ic);
1142                         if_free(ifp);
1143                 }
1144         }
1145         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1146         taskqueue_free(sc->sc_tq);
1147
1148         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1149                 if (mac->mac_intrhand[i] != NULL) {
1150                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1151                             mac->mac_intrhand[i]);
1152                         mac->mac_intrhand[i] = NULL;
1153                 }
1154         }
1155         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1156         if (mac->mac_msi != 0)
1157                 pci_release_msi(dev);
1158
1159         BWN_LOCK_DESTROY(sc);
1160         return (0);
1161 }
1162
1163 static int
1164 bwn_attach_pre(struct bwn_softc *sc)
1165 {
1166         struct ifnet *ifp;
1167         int error = 0;
1168
1169         BWN_LOCK_INIT(sc);
1170         TAILQ_INIT(&sc->sc_maclist);
1171         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1172         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1173         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1174
1175         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1176                 taskqueue_thread_enqueue, &sc->sc_tq);
1177         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1178                 "%s taskq", device_get_nameunit(sc->sc_dev));
1179
1180         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1181         if (ifp == NULL) {
1182                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1183                 error = ENOSPC;
1184                 goto fail;
1185         }
1186
1187         /* set these up early for if_printf use */
1188         if_initname(ifp, device_get_name(sc->sc_dev),
1189             device_get_unit(sc->sc_dev));
1190
1191         ifp->if_softc = sc;
1192         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1193         ifp->if_init = bwn_init;
1194         ifp->if_ioctl = bwn_ioctl;
1195         ifp->if_start = bwn_start;
1196         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1197         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1198         IFQ_SET_READY(&ifp->if_snd);
1199
1200         return (0);
1201
1202 fail:   BWN_LOCK_DESTROY(sc);
1203         return (error);
1204 }
1205
1206 static void
1207 bwn_sprom_bugfixes(device_t dev)
1208 {
1209 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1210         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1211          (siba_get_pci_device(dev) == _device) &&                       \
1212          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1213          (siba_get_pci_subdevice(dev) == _subdevice))
1214
1215         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1216             siba_get_pci_subdevice(dev) == 0x4e &&
1217             siba_get_pci_revid(dev) > 0x40)
1218                 siba_sprom_set_bf_lo(dev,
1219                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1220         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1221             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1222                 siba_sprom_set_bf_lo(dev,
1223                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1224         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1225                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1226                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1227                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1228                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1229                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1230                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1231                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1232                         siba_sprom_set_bf_lo(dev,
1233                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1234         }
1235 #undef  BWN_ISDEV
1236 }
1237
1238 static int
1239 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1240 {
1241 #define IS_RUNNING(ifp) \
1242         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1243         struct bwn_softc *sc = ifp->if_softc;
1244         struct ieee80211com *ic = ifp->if_l2com;
1245         struct ifreq *ifr = (struct ifreq *)data;
1246         int error = 0, startall;
1247
1248         switch (cmd) {
1249         case SIOCSIFFLAGS:
1250                 startall = 0;
1251                 if (IS_RUNNING(ifp)) {
1252                         bwn_update_promisc(ifp);
1253                 } else if (ifp->if_flags & IFF_UP) {
1254                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1255                                 bwn_init(sc);
1256                                 startall = 1;
1257                         }
1258                 } else
1259                         bwn_stop(sc, 1);
1260                 if (startall)
1261                         ieee80211_start_all(ic);
1262                 break;
1263         case SIOCGIFMEDIA:
1264                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1265                 break;
1266         case SIOCGIFADDR:
1267                 error = ether_ioctl(ifp, cmd, data);
1268                 break;
1269         default:
1270                 error = EINVAL;
1271                 break;
1272         }
1273         return (error);
1274 }
1275
1276 static void
1277 bwn_start(struct ifnet *ifp)
1278 {
1279         struct bwn_softc *sc = ifp->if_softc;
1280
1281         BWN_LOCK(sc);
1282         bwn_start_locked(ifp);
1283         BWN_UNLOCK(sc);
1284 }
1285
1286 static void
1287 bwn_start_locked(struct ifnet *ifp)
1288 {
1289         struct bwn_softc *sc = ifp->if_softc;
1290         struct bwn_mac *mac = sc->sc_curmac;
1291         struct ieee80211_frame *wh;
1292         struct ieee80211_node *ni;
1293         struct ieee80211_key *k;
1294         struct mbuf *m;
1295
1296         BWN_ASSERT_LOCKED(sc);
1297
1298         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1299             mac->mac_status < BWN_MAC_STATUS_STARTED)
1300                 return;
1301
1302         for (;;) {
1303                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1304                 if (m == NULL)
1305                         break;
1306
1307                 if (bwn_tx_isfull(sc, m))
1308                         break;
1309                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1310                 if (ni == NULL) {
1311                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1312                         m_freem(m);
1313                         ifp->if_oerrors++;
1314                         continue;
1315                 }
1316                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1317                 wh = mtod(m, struct ieee80211_frame *);
1318                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1319                         k = ieee80211_crypto_encap(ni, m);
1320                         if (k == NULL) {
1321                                 ieee80211_free_node(ni);
1322                                 m_freem(m);
1323                                 ifp->if_oerrors++;
1324                                 continue;
1325                         }
1326                 }
1327                 wh = NULL;      /* Catch any invalid use */
1328
1329                 if (bwn_tx_start(sc, ni, m) != 0) {
1330                         if (ni != NULL)
1331                                 ieee80211_free_node(ni);
1332                         ifp->if_oerrors++;
1333                         continue;
1334                 }
1335
1336                 sc->sc_watchdog_timer = 5;
1337         }
1338 }
1339
1340 static int
1341 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1342 {
1343         struct bwn_dma_ring *dr;
1344         struct bwn_mac *mac = sc->sc_curmac;
1345         struct bwn_pio_txqueue *tq;
1346         struct ifnet *ifp = sc->sc_ifp;
1347         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1348
1349         BWN_ASSERT_LOCKED(sc);
1350
1351         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1352                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1353                 if (dr->dr_stop == 1 ||
1354                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1355                         dr->dr_stop = 1;
1356                         goto full;
1357                 }
1358         } else {
1359                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1360                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1361                     pktlen > (tq->tq_size - tq->tq_used)) {
1362                         tq->tq_stop = 1;
1363                         goto full;
1364                 }
1365         }
1366         return (0);
1367 full:
1368         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1369         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1370         return (1);
1371 }
1372
1373 static int
1374 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1375 {
1376         struct bwn_mac *mac = sc->sc_curmac;
1377         int error;
1378
1379         BWN_ASSERT_LOCKED(sc);
1380
1381         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1382                 m_freem(m);
1383                 return (ENXIO);
1384         }
1385
1386         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1387             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1388         if (error) {
1389                 m_freem(m);
1390                 return (error);
1391         }
1392         return (0);
1393 }
1394
1395 static int
1396 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1397 {
1398         struct bwn_pio_txpkt *tp;
1399         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1400         struct bwn_softc *sc = mac->mac_sc;
1401         struct bwn_txhdr txhdr;
1402         struct mbuf *m_new;
1403         uint32_t ctl32;
1404         int error;
1405         uint16_t ctl16;
1406
1407         BWN_ASSERT_LOCKED(sc);
1408
1409         /* XXX TODO send packets after DTIM */
1410
1411         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1412         tp = TAILQ_FIRST(&tq->tq_pktlist);
1413         tp->tp_ni = ni;
1414         tp->tp_m = m;
1415
1416         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1417         if (error) {
1418                 device_printf(sc->sc_dev, "tx fail\n");
1419                 return (error);
1420         }
1421
1422         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1423         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1424         tq->tq_free--;
1425
1426         if (siba_get_revid(sc->sc_dev) >= 8) {
1427                 /*
1428                  * XXX please removes m_defrag(9)
1429                  */
1430                 m_new = m_defrag(m, M_DONTWAIT);
1431                 if (m_new == NULL) {
1432                         device_printf(sc->sc_dev,
1433                             "%s: can't defrag TX buffer\n",
1434                             __func__);
1435                         return (ENOBUFS);
1436                 }
1437                 if (m_new->m_next != NULL)
1438                         device_printf(sc->sc_dev,
1439                             "TODO: fragmented packets for PIO\n");
1440                 tp->tp_m = m_new;
1441
1442                 /* send HEADER */
1443                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1444                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1445                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1446                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1447                 /* send BODY */
1448                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1449                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1450                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1451                     ctl32 | BWN_PIO8_TXCTL_EOF);
1452         } else {
1453                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1454                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1455                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1456                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1457                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1458                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1459                     ctl16 | BWN_PIO_TXCTL_EOF);
1460         }
1461
1462         return (0);
1463 }
1464
1465 static struct bwn_pio_txqueue *
1466 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1467 {
1468
1469         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1470                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1471
1472         switch (prio) {
1473         case 0:
1474                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1475         case 1:
1476                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1477         case 2:
1478                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1479         case 3:
1480                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1481         }
1482         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1483         return (NULL);
1484 }
1485
1486 static int
1487 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1488 {
1489 #define BWN_GET_TXHDRCACHE(slot)                                        \
1490         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1491         struct bwn_dma *dma = &mac->mac_method.dma;
1492         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1493         struct bwn_dmadesc_generic *desc;
1494         struct bwn_dmadesc_meta *mt;
1495         struct bwn_softc *sc = mac->mac_sc;
1496         struct ifnet *ifp = sc->sc_ifp;
1497         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1498         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1499
1500         BWN_ASSERT_LOCKED(sc);
1501         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1502
1503         /* XXX send after DTIM */
1504
1505         slot = bwn_dma_getslot(dr);
1506         dr->getdesc(dr, slot, &desc, &mt);
1507         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1508             ("%s:%d: fail", __func__, __LINE__));
1509
1510         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1511             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1512             BWN_DMA_COOKIE(dr, slot));
1513         if (error)
1514                 goto fail;
1515         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1516             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1517             &mt->mt_paddr, BUS_DMA_NOWAIT);
1518         if (error) {
1519                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1520                     __func__, error);
1521                 goto fail;
1522         }
1523         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1524             BUS_DMASYNC_PREWRITE);
1525         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1526         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1527             BUS_DMASYNC_PREWRITE);
1528
1529         slot = bwn_dma_getslot(dr);
1530         dr->getdesc(dr, slot, &desc, &mt);
1531         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1532             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1533         mt->mt_m = m;
1534         mt->mt_ni = ni;
1535
1536         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1537             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1538         if (error && error != EFBIG) {
1539                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1540                     __func__, error);
1541                 goto fail;
1542         }
1543         if (error) {    /* error == EFBIG */
1544                 struct mbuf *m_new;
1545
1546                 m_new = m_defrag(m, M_DONTWAIT);
1547                 if (m_new == NULL) {
1548                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1549                             __func__);
1550                         error = ENOBUFS;
1551                         goto fail;
1552                 } else {
1553                         m = m_new;
1554                 }
1555
1556                 mt->mt_m = m;
1557                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1558                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1559                 if (error) {
1560                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1561                             __func__, error);
1562                         goto fail;
1563                 }
1564         }
1565         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1566         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1567         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1568             BUS_DMASYNC_PREWRITE);
1569
1570         /* XXX send after DTIM */
1571
1572         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1573         return (0);
1574 fail:
1575         dr->dr_curslot = backup[0];
1576         dr->dr_usedslot = backup[1];
1577         return (error);
1578 #undef BWN_GET_TXHDRCACHE
1579 }
1580
1581 static void
1582 bwn_watchdog(void *arg)
1583 {
1584         struct bwn_softc *sc = arg;
1585         struct ifnet *ifp = sc->sc_ifp;
1586
1587         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1588                 if_printf(ifp, "device timeout\n");
1589                 ifp->if_oerrors++;
1590         }
1591         callout_schedule(&sc->sc_watchdog_ch, hz);
1592 }
1593
1594 static int
1595 bwn_attach_core(struct bwn_mac *mac)
1596 {
1597         struct bwn_softc *sc = mac->mac_sc;
1598         int error, have_bg = 0, have_a = 0;
1599         uint32_t high;
1600
1601         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1602             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1603
1604         siba_powerup(sc->sc_dev, 0);
1605
1606         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1607         bwn_reset_core(mac,
1608             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1609         error = bwn_phy_getinfo(mac, high);
1610         if (error)
1611                 goto fail;
1612
1613         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1614         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1615         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1616             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1617             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1618                 have_a = have_bg = 0;
1619                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1620                         have_a = 1;
1621                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1622                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1623                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1624                         have_bg = 1;
1625                 else
1626                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1627                             mac->mac_phy.type));
1628         }
1629         /* XXX turns off PHY A because it's not supported */
1630         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1631             mac->mac_phy.type != BWN_PHYTYPE_N) {
1632                 have_a = 0;
1633                 have_bg = 1;
1634         }
1635
1636         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1637                 mac->mac_phy.attach = bwn_phy_g_attach;
1638                 mac->mac_phy.detach = bwn_phy_g_detach;
1639                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1640                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1641                 mac->mac_phy.init = bwn_phy_g_init;
1642                 mac->mac_phy.exit = bwn_phy_g_exit;
1643                 mac->mac_phy.phy_read = bwn_phy_g_read;
1644                 mac->mac_phy.phy_write = bwn_phy_g_write;
1645                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1646                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1647                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1648                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1649                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1650                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1651                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1652                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1653                 mac->mac_phy.set_im = bwn_phy_g_im;
1654                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1655                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1656                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1657                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1658         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1659                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1660                 mac->mac_phy.init = bwn_phy_lp_init;
1661                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1662                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1663                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1664                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1665                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1666                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1667                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1668                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1669                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1670                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1671                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1672         } else {
1673                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1674                     mac->mac_phy.type);
1675                 error = ENXIO;
1676                 goto fail;
1677         }
1678
1679         mac->mac_phy.gmode = have_bg;
1680         if (mac->mac_phy.attach != NULL) {
1681                 error = mac->mac_phy.attach(mac);
1682                 if (error) {
1683                         device_printf(sc->sc_dev, "failed\n");
1684                         goto fail;
1685                 }
1686         }
1687
1688         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1689
1690         error = bwn_chiptest(mac);
1691         if (error)
1692                 goto fail;
1693         error = bwn_setup_channels(mac, have_bg, have_a);
1694         if (error) {
1695                 device_printf(sc->sc_dev, "failed to setup channels\n");
1696                 goto fail;
1697         }
1698
1699         if (sc->sc_curmac == NULL)
1700                 sc->sc_curmac = mac;
1701
1702         error = bwn_dma_attach(mac);
1703         if (error != 0) {
1704                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1705                 goto fail;
1706         }
1707
1708         mac->mac_phy.switch_analog(mac, 0);
1709
1710         siba_dev_down(sc->sc_dev, 0);
1711 fail:
1712         siba_powerdown(sc->sc_dev);
1713         return (error);
1714 }
1715
1716 static void
1717 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1718 {
1719         struct bwn_softc *sc = mac->mac_sc;
1720         uint32_t low, ctl;
1721
1722         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1723
1724         siba_dev_up(sc->sc_dev, flags);
1725         DELAY(2000);
1726
1727         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1728             ~BWN_TGSLOW_PHYRESET;
1729         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1730         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1731         DELAY(1000);
1732         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1733         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1734         DELAY(1000);
1735
1736         if (mac->mac_phy.switch_analog != NULL)
1737                 mac->mac_phy.switch_analog(mac, 1);
1738
1739         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1740         if (flags & BWN_TGSLOW_SUPPORT_G)
1741                 ctl |= BWN_MACCTL_GMODE;
1742         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1743 }
1744
1745 static int
1746 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1747 {
1748         struct bwn_phy *phy = &mac->mac_phy;
1749         struct bwn_softc *sc = mac->mac_sc;
1750         uint32_t tmp;
1751
1752         /* PHY */
1753         tmp = BWN_READ_2(mac, BWN_PHYVER);
1754         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1755         phy->rf_on = 1;
1756         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1757         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1758         phy->rev = (tmp & BWN_PHYVER_VERSION);
1759         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1760             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1761                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1762             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1763             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1764             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1765                 goto unsupphy;
1766
1767         /* RADIO */
1768         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1769                 if (siba_get_chiprev(sc->sc_dev) == 0)
1770                         tmp = 0x3205017f;
1771                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1772                         tmp = 0x4205017f;
1773                 else
1774                         tmp = 0x5205017f;
1775         } else {
1776                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1777                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1778                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1779                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1780         }
1781         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1782         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1783         phy->rf_manuf = (tmp & 0x00000fff);
1784         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1785                 goto unsupradio;
1786         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1787              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1788             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1789             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1790             (phy->type == BWN_PHYTYPE_N &&
1791              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1792             (phy->type == BWN_PHYTYPE_LP &&
1793              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1794                 goto unsupradio;
1795
1796         return (0);
1797 unsupphy:
1798         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1799             "analog %#x)\n",
1800             phy->type, phy->rev, phy->analog);
1801         return (ENXIO);
1802 unsupradio:
1803         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1804             "rev %#x)\n",
1805             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1806         return (ENXIO);
1807 }
1808
1809 static int
1810 bwn_chiptest(struct bwn_mac *mac)
1811 {
1812 #define TESTVAL0        0x55aaaa55
1813 #define TESTVAL1        0xaa5555aa
1814         struct bwn_softc *sc = mac->mac_sc;
1815         uint32_t v, backup;
1816
1817         BWN_LOCK(sc);
1818
1819         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1820
1821         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1822         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1823                 goto error;
1824         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1825         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1826                 goto error;
1827
1828         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1829
1830         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1831             (siba_get_revid(sc->sc_dev) <= 10)) {
1832                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1833                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1834                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1835                         goto error;
1836                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1837                         goto error;
1838         }
1839         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1840
1841         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1842         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1843                 goto error;
1844
1845         BWN_UNLOCK(sc);
1846         return (0);
1847 error:
1848         BWN_UNLOCK(sc);
1849         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1850         return (ENODEV);
1851 }
1852
1853 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1854 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1855
1856 static int
1857 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1858 {
1859         struct bwn_softc *sc = mac->mac_sc;
1860         struct ifnet *ifp = sc->sc_ifp;
1861         struct ieee80211com *ic = ifp->if_l2com;
1862
1863         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1864         ic->ic_nchans = 0;
1865
1866         if (have_bg)
1867                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1868                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1869         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1870                 if (have_a)
1871                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1872                             &ic->ic_nchans, &bwn_chantable_n,
1873                             IEEE80211_CHAN_HTA);
1874         } else {
1875                 if (have_a)
1876                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1877                             &ic->ic_nchans, &bwn_chantable_a,
1878                             IEEE80211_CHAN_A);
1879         }
1880
1881         mac->mac_phy.supports_2ghz = have_bg;
1882         mac->mac_phy.supports_5ghz = have_a;
1883
1884         return (ic->ic_nchans == 0 ? ENXIO : 0);
1885 }
1886
1887 static uint32_t
1888 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1889 {
1890         uint32_t ret;
1891
1892         BWN_ASSERT_LOCKED(mac->mac_sc);
1893
1894         if (way == BWN_SHARED) {
1895                 KASSERT((offset & 0x0001) == 0,
1896                     ("%s:%d warn", __func__, __LINE__));
1897                 if (offset & 0x0003) {
1898                         bwn_shm_ctlword(mac, way, offset >> 2);
1899                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1900                         ret <<= 16;
1901                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1902                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1903                         goto out;
1904                 }
1905                 offset >>= 2;
1906         }
1907         bwn_shm_ctlword(mac, way, offset);
1908         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1909 out:
1910         return (ret);
1911 }
1912
1913 static uint16_t
1914 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1915 {
1916         uint16_t ret;
1917
1918         BWN_ASSERT_LOCKED(mac->mac_sc);
1919
1920         if (way == BWN_SHARED) {
1921                 KASSERT((offset & 0x0001) == 0,
1922                     ("%s:%d warn", __func__, __LINE__));
1923                 if (offset & 0x0003) {
1924                         bwn_shm_ctlword(mac, way, offset >> 2);
1925                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1926                         goto out;
1927                 }
1928                 offset >>= 2;
1929         }
1930         bwn_shm_ctlword(mac, way, offset);
1931         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1932 out:
1933
1934         return (ret);
1935 }
1936
1937 static void
1938 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1939     uint16_t offset)
1940 {
1941         uint32_t control;
1942
1943         control = way;
1944         control <<= 16;
1945         control |= offset;
1946         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1947 }
1948
1949 static void
1950 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1951     uint32_t value)
1952 {
1953         BWN_ASSERT_LOCKED(mac->mac_sc);
1954
1955         if (way == BWN_SHARED) {
1956                 KASSERT((offset & 0x0001) == 0,
1957                     ("%s:%d warn", __func__, __LINE__));
1958                 if (offset & 0x0003) {
1959                         bwn_shm_ctlword(mac, way, offset >> 2);
1960                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1961                                     (value >> 16) & 0xffff);
1962                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1963                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1964                         return;
1965                 }
1966                 offset >>= 2;
1967         }
1968         bwn_shm_ctlword(mac, way, offset);
1969         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1970 }
1971
1972 static void
1973 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1974     uint16_t value)
1975 {
1976         BWN_ASSERT_LOCKED(mac->mac_sc);
1977
1978         if (way == BWN_SHARED) {
1979                 KASSERT((offset & 0x0001) == 0,
1980                     ("%s:%d warn", __func__, __LINE__));
1981                 if (offset & 0x0003) {
1982                         bwn_shm_ctlword(mac, way, offset >> 2);
1983                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1984                         return;
1985                 }
1986                 offset >>= 2;
1987         }
1988         bwn_shm_ctlword(mac, way, offset);
1989         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1990 }
1991
1992 static void
1993 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1994     int txpow)
1995 {
1996
1997         c->ic_freq = freq;
1998         c->ic_flags = flags;
1999         c->ic_ieee = ieee;
2000         c->ic_minpower = 0;
2001         c->ic_maxpower = 2 * txpow;
2002         c->ic_maxregpower = txpow;
2003 }
2004
2005 static void
2006 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2007     const struct bwn_channelinfo *ci, int flags)
2008 {
2009         struct ieee80211_channel *c;
2010         int i;
2011
2012         c = &chans[*nchans];
2013
2014         for (i = 0; i < ci->nchannels; i++) {
2015                 const struct bwn_channel *hc;
2016
2017                 hc = &ci->channels[i];
2018                 if (*nchans >= maxchans)
2019                         break;
2020                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2021                 c++, (*nchans)++;
2022                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2023                         /* g channel have a separate b-only entry */
2024                         if (*nchans >= maxchans)
2025                                 break;
2026                         c[0] = c[-1];
2027                         c[-1].ic_flags = IEEE80211_CHAN_B;
2028                         c++, (*nchans)++;
2029                 }
2030                 if (flags == IEEE80211_CHAN_HTG) {
2031                         /* HT g channel have a separate g-only entry */
2032                         if (*nchans >= maxchans)
2033                                 break;
2034                         c[-1].ic_flags = IEEE80211_CHAN_G;
2035                         c[0] = c[-1];
2036                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2037                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2038                         c++, (*nchans)++;
2039                 }
2040                 if (flags == IEEE80211_CHAN_HTA) {
2041                         /* HT a channel have a separate a-only entry */
2042                         if (*nchans >= maxchans)
2043                                 break;
2044                         c[-1].ic_flags = IEEE80211_CHAN_A;
2045                         c[0] = c[-1];
2046                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2047                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2048                         c++, (*nchans)++;
2049                 }
2050         }
2051 }
2052
2053 static int
2054 bwn_phy_g_attach(struct bwn_mac *mac)
2055 {
2056         struct bwn_softc *sc = mac->mac_sc;
2057         struct bwn_phy *phy = &mac->mac_phy;
2058         struct bwn_phy_g *pg = &phy->phy_g;
2059         unsigned int i;
2060         int16_t pab0, pab1, pab2;
2061         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2062         int8_t bg;
2063
2064         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2065         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2066         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2067         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2068
2069         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2070                 device_printf(sc->sc_dev, "not supported anymore\n");
2071
2072         pg->pg_flags = 0;
2073         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2074             pab2 == -1) {
2075                 pg->pg_idletssi = 52;
2076                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2077                 return (0);
2078         }
2079
2080         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2081         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2082         if (pg->pg_tssi2dbm == NULL) {
2083                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2084                 return (ENOMEM);
2085         }
2086         for (i = 0; i < 64; i++) {
2087                 int32_t m1, m2, f, q, delta;
2088                 int8_t j = 0;
2089
2090                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2091                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2092                 f = 256;
2093
2094                 do {
2095                         if (j > 15) {
2096                                 device_printf(sc->sc_dev,
2097                                     "failed to generate tssi2dBm\n");
2098                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2099                                 return (ENOMEM);
2100                         }
2101                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2102                             f, 2048);
2103                         delta = abs(q - f);
2104                         f = q;
2105                         j++;
2106                 } while (delta >= 2);
2107
2108                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2109                     128);
2110         }
2111
2112         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2113         return (0);
2114 }
2115
2116 static void
2117 bwn_phy_g_detach(struct bwn_mac *mac)
2118 {
2119         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2120
2121         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2122                 free(pg->pg_tssi2dbm, M_DEVBUF);
2123                 pg->pg_tssi2dbm = NULL;
2124         }
2125         pg->pg_flags = 0;
2126 }
2127
2128 static void
2129 bwn_phy_g_init_pre(struct bwn_mac *mac)
2130 {
2131         struct bwn_phy *phy = &mac->mac_phy;
2132         struct bwn_phy_g *pg = &phy->phy_g;
2133         void *tssi2dbm;
2134         int idletssi;
2135         unsigned int i;
2136
2137         tssi2dbm = pg->pg_tssi2dbm;
2138         idletssi = pg->pg_idletssi;
2139
2140         memset(pg, 0, sizeof(*pg));
2141
2142         pg->pg_tssi2dbm = tssi2dbm;
2143         pg->pg_idletssi = idletssi;
2144
2145         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2146
2147         for (i = 0; i < N(pg->pg_nrssi); i++)
2148                 pg->pg_nrssi[i] = -1000;
2149         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2150                 pg->pg_nrssi_lt[i] = i;
2151         pg->pg_lofcal = 0xffff;
2152         pg->pg_initval = 0xffff;
2153         pg->pg_immode = BWN_IMMODE_NONE;
2154         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2155         pg->pg_avgtssi = 0xff;
2156
2157         pg->pg_loctl.tx_bias = 0xff;
2158         TAILQ_INIT(&pg->pg_loctl.calib_list);
2159 }
2160
2161 static int
2162 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2163 {
2164         struct bwn_phy *phy = &mac->mac_phy;
2165         struct bwn_phy_g *pg = &phy->phy_g;
2166         struct bwn_softc *sc = mac->mac_sc;
2167         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2168         static const struct bwn_rfatt rfatt0[] = {
2169                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2170                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2171                 { 3, 1 }, { 4, 1 }
2172         };
2173         static const struct bwn_rfatt rfatt1[] = {
2174                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2175                 { 14, 1 }
2176         };
2177         static const struct bwn_rfatt rfatt2[] = {
2178                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2179                 { 9, 1 }
2180         };
2181         static const struct bwn_bbatt bbatt_0[] = {
2182                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2183         };
2184
2185         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2186
2187         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2188                 pg->pg_bbatt.att = 0;
2189         else
2190                 pg->pg_bbatt.att = 2;
2191
2192         /* prepare Radio Attenuation */
2193         pg->pg_rfatt.padmix = 0;
2194
2195         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2196             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2197                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2198                         pg->pg_rfatt.att = 2;
2199                         goto done;
2200                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2201                         pg->pg_rfatt.att = 3;
2202                         goto done;
2203                 }
2204         }
2205
2206         if (phy->type == BWN_PHYTYPE_A) {
2207                 pg->pg_rfatt.att = 0x60;
2208                 goto done;
2209         }
2210
2211         switch (phy->rf_ver) {
2212         case 0x2050:
2213                 switch (phy->rf_rev) {
2214                 case 0:
2215                         pg->pg_rfatt.att = 5;
2216                         goto done;
2217                 case 1:
2218                         if (phy->type == BWN_PHYTYPE_G) {
2219                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2220                                     SIBA_BOARDVENDOR_BCM &&
2221                                     siba_get_pci_subdevice(sc->sc_dev) ==
2222                                     SIBA_BOARD_BCM4309G &&
2223                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2224                                         pg->pg_rfatt.att = 3;
2225                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2226                                     SIBA_BOARDVENDOR_BCM &&
2227                                     siba_get_pci_subdevice(sc->sc_dev) ==
2228                                     SIBA_BOARD_BU4306)
2229                                         pg->pg_rfatt.att = 3;
2230                                 else
2231                                         pg->pg_rfatt.att = 1;
2232                         } else {
2233                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2234                                     SIBA_BOARDVENDOR_BCM &&
2235                                     siba_get_pci_subdevice(sc->sc_dev) ==
2236                                     SIBA_BOARD_BCM4309G &&
2237                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2238                                         pg->pg_rfatt.att = 7;
2239                                 else
2240                                         pg->pg_rfatt.att = 6;
2241                         }
2242                         goto done;
2243                 case 2:
2244                         if (phy->type == BWN_PHYTYPE_G) {
2245                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2246                                     SIBA_BOARDVENDOR_BCM &&
2247                                     siba_get_pci_subdevice(sc->sc_dev) ==
2248                                     SIBA_BOARD_BCM4309G &&
2249                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2250                                         pg->pg_rfatt.att = 3;
2251                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2252                                     SIBA_BOARDVENDOR_BCM &&
2253                                     siba_get_pci_subdevice(sc->sc_dev) ==
2254                                     SIBA_BOARD_BU4306)
2255                                         pg->pg_rfatt.att = 5;
2256                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2257                                         pg->pg_rfatt.att = 4;
2258                                 else
2259                                         pg->pg_rfatt.att = 3;
2260                         } else
2261                                 pg->pg_rfatt.att = 6;
2262                         goto done;
2263                 case 3:
2264                         pg->pg_rfatt.att = 5;
2265                         goto done;
2266                 case 4:
2267                 case 5:
2268                         pg->pg_rfatt.att = 1;
2269                         goto done;
2270                 case 6:
2271                 case 7:
2272                         pg->pg_rfatt.att = 5;
2273                         goto done;
2274                 case 8:
2275                         pg->pg_rfatt.att = 0xa;
2276                         pg->pg_rfatt.padmix = 1;
2277                         goto done;
2278                 case 9:
2279                 default:
2280                         pg->pg_rfatt.att = 5;
2281                         goto done;
2282                 }
2283                 break;
2284         case 0x2053:
2285                 switch (phy->rf_rev) {
2286                 case 1:
2287                         pg->pg_rfatt.att = 6;
2288                         goto done;
2289                 }
2290                 break;
2291         }
2292         pg->pg_rfatt.att = 5;
2293 done:
2294         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2295
2296         if (!bwn_has_hwpctl(mac)) {
2297                 lo->rfatt.array = rfatt0;
2298                 lo->rfatt.len = N(rfatt0);
2299                 lo->rfatt.min = 0;
2300                 lo->rfatt.max = 9;
2301                 goto genbbatt;
2302         }
2303         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2304                 lo->rfatt.array = rfatt1;
2305                 lo->rfatt.len = N(rfatt1);
2306                 lo->rfatt.min = 0;
2307                 lo->rfatt.max = 14;
2308                 goto genbbatt;
2309         }
2310         lo->rfatt.array = rfatt2;
2311         lo->rfatt.len = N(rfatt2);
2312         lo->rfatt.min = 0;
2313         lo->rfatt.max = 9;
2314 genbbatt:
2315         lo->bbatt.array = bbatt_0;
2316         lo->bbatt.len = N(bbatt_0);
2317         lo->bbatt.min = 0;
2318         lo->bbatt.max = 8;
2319
2320         BWN_READ_4(mac, BWN_MACCTL);
2321         if (phy->rev == 1) {
2322                 phy->gmode = 0;
2323                 bwn_reset_core(mac, 0);
2324                 bwn_phy_g_init_sub(mac);
2325                 phy->gmode = 1;
2326                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2327         }
2328         return (0);
2329 }
2330
2331 static uint16_t
2332 bwn_phy_g_txctl(struct bwn_mac *mac)
2333 {
2334         struct bwn_phy *phy = &mac->mac_phy;
2335
2336         if (phy->rf_ver != 0x2050)
2337                 return (0);
2338         if (phy->rf_rev == 1)
2339                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2340         if (phy->rf_rev < 6)
2341                 return (BWN_TXCTL_PA2DB);
2342         if (phy->rf_rev == 8)
2343                 return (BWN_TXCTL_TXMIX);
2344         return (0);
2345 }
2346
2347 static int
2348 bwn_phy_g_init(struct bwn_mac *mac)
2349 {
2350
2351         bwn_phy_g_init_sub(mac);
2352         return (0);
2353 }
2354
2355 static void
2356 bwn_phy_g_exit(struct bwn_mac *mac)
2357 {
2358         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2359         struct bwn_lo_calib *cal, *tmp;
2360
2361         if (lo == NULL)
2362                 return;
2363         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2364                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2365                 free(cal, M_DEVBUF);
2366         }
2367 }
2368
2369 static uint16_t
2370 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2371 {
2372
2373         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2374         return (BWN_READ_2(mac, BWN_PHYDATA));
2375 }
2376
2377 static void
2378 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2379 {
2380
2381         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2382         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2383 }
2384
2385 static uint16_t
2386 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2387 {
2388
2389         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2390         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2391         return (BWN_READ_2(mac, BWN_RFDATALO));
2392 }
2393
2394 static void
2395 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2396 {
2397
2398         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2399         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2400         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2401 }
2402
2403 static int
2404 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2405 {
2406
2407         return (mac->mac_phy.rev >= 6);
2408 }
2409
2410 static void
2411 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2412 {
2413         struct bwn_phy *phy = &mac->mac_phy;
2414         struct bwn_phy_g *pg = &phy->phy_g;
2415         unsigned int channel;
2416         uint16_t rfover, rfoverval;
2417
2418         if (on) {
2419                 if (phy->rf_on)
2420                         return;
2421
2422                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2423                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2424                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2425                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2426                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2427                             pg->pg_radioctx_over);
2428                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2429                             pg->pg_radioctx_overval);
2430                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2431                 }
2432                 channel = phy->chan;
2433                 bwn_phy_g_switch_chan(mac, 6, 1);
2434                 bwn_phy_g_switch_chan(mac, channel, 0);
2435                 return;
2436         }
2437
2438         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2439         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2440         pg->pg_radioctx_over = rfover;
2441         pg->pg_radioctx_overval = rfoverval;
2442         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2443         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2444         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2445 }
2446
2447 static int
2448 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2449 {
2450
2451         if ((newchan < 1) || (newchan > 14))
2452                 return (EINVAL);
2453         bwn_phy_g_switch_chan(mac, newchan, 0);
2454
2455         return (0);
2456 }
2457
2458 static uint32_t
2459 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2460 {
2461
2462         return (1);
2463 }
2464
2465 static void
2466 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2467 {
2468         struct bwn_phy *phy = &mac->mac_phy;
2469         uint64_t hf;
2470         int autodiv = 0;
2471         uint16_t tmp;
2472
2473         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2474                 autodiv = 1;
2475
2476         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2477         bwn_hf_write(mac, hf);
2478
2479         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2480             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2481             ((autodiv ? BWN_ANTAUTO1 : antenna)
2482                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2483
2484         if (autodiv) {
2485                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2486                 if (antenna == BWN_ANTAUTO1)
2487                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2488                 else
2489                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2490                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2491         }
2492         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2493         if (autodiv)
2494                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2495         else
2496                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2497         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2498         if (phy->rev >= 2) {
2499                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2500                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2501                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2502                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2503                     0x15);
2504                 if (phy->rev == 2)
2505                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2506                 else
2507                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2508                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2509                             8);
2510         }
2511         if (phy->rev >= 6)
2512                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2513
2514         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2515         bwn_hf_write(mac, hf);
2516 }
2517
2518 static int
2519 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2520 {
2521         struct bwn_phy *phy = &mac->mac_phy;
2522         struct bwn_phy_g *pg = &phy->phy_g;
2523
2524         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2525         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2526
2527         if (phy->rev == 0 || !phy->gmode)
2528                 return (ENODEV);
2529
2530         pg->pg_aci_wlan_automatic = 0;
2531         return (0);
2532 }
2533
2534 static int
2535 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2536 {
2537         struct bwn_phy *phy = &mac->mac_phy;
2538         struct bwn_phy_g *pg = &phy->phy_g;
2539         struct bwn_softc *sc = mac->mac_sc;
2540         unsigned int tssi;
2541         int cck, ofdm;
2542         int power;
2543         int rfatt, bbatt;
2544         unsigned int max;
2545
2546         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2547
2548         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2549         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2550         if (cck < 0 && ofdm < 0) {
2551                 if (ignore_tssi == 0)
2552                         return (BWN_TXPWR_RES_DONE);
2553                 cck = 0;
2554                 ofdm = 0;
2555         }
2556         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2557         if (pg->pg_avgtssi != 0xff)
2558                 tssi = (tssi + pg->pg_avgtssi) / 2;
2559         pg->pg_avgtssi = tssi;
2560         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2561
2562         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2563         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2564                 max -= 3;
2565         if (max >= 120) {
2566                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2567                 max = 80;
2568                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2569         }
2570
2571         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2572             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2573              tssi, 0x00), 0x3f)]);
2574         if (power == 0)
2575                 return (BWN_TXPWR_RES_DONE);
2576
2577         rfatt = -((power + 7) / 8);
2578         bbatt = (-(power / 2)) - (4 * rfatt);
2579         if ((rfatt == 0) && (bbatt == 0))
2580                 return (BWN_TXPWR_RES_DONE);
2581         pg->pg_bbatt_delta = bbatt;
2582         pg->pg_rfatt_delta = rfatt;
2583         return (BWN_TXPWR_RES_NEED_ADJUST);
2584 }
2585
2586 static void
2587 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2588 {
2589         struct bwn_phy *phy = &mac->mac_phy;
2590         struct bwn_phy_g *pg = &phy->phy_g;
2591         struct bwn_softc *sc = mac->mac_sc;
2592         int rfatt, bbatt;
2593         uint8_t txctl;
2594
2595         bwn_mac_suspend(mac);
2596
2597         BWN_ASSERT_LOCKED(sc);
2598
2599         bbatt = pg->pg_bbatt.att;
2600         bbatt += pg->pg_bbatt_delta;
2601         rfatt = pg->pg_rfatt.att;
2602         rfatt += pg->pg_rfatt_delta;
2603
2604         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2605         txctl = pg->pg_txctl;
2606         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2607                 if (rfatt <= 1) {
2608                         if (txctl == 0) {
2609                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2610                                 rfatt += 2;
2611                                 bbatt += 2;
2612                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2613                             BWN_BFL_PACTRL) {
2614                                 bbatt += 4 * (rfatt - 2);
2615                                 rfatt = 2;
2616                         }
2617                 } else if (rfatt > 4 && txctl) {
2618                         txctl = 0;
2619                         if (bbatt < 3) {
2620                                 rfatt -= 3;
2621                                 bbatt += 2;
2622                         } else {
2623                                 rfatt -= 2;
2624                                 bbatt -= 2;
2625                         }
2626                 }
2627         }
2628         pg->pg_txctl = txctl;
2629         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2630         pg->pg_rfatt.att = rfatt;
2631         pg->pg_bbatt.att = bbatt;
2632
2633         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2634
2635         bwn_phy_lock(mac);
2636         bwn_rf_lock(mac);
2637         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2638             pg->pg_txctl);
2639         bwn_rf_unlock(mac);
2640         bwn_phy_unlock(mac);
2641
2642         bwn_mac_enable(mac);
2643 }
2644
2645 static void
2646 bwn_phy_g_task_15s(struct bwn_mac *mac)
2647 {
2648         struct bwn_phy *phy = &mac->mac_phy;
2649         struct bwn_phy_g *pg = &phy->phy_g;
2650         struct bwn_softc *sc = mac->mac_sc;
2651         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2652         unsigned long expire, now;
2653         struct bwn_lo_calib *cal, *tmp;
2654         uint8_t expired = 0;
2655
2656         bwn_mac_suspend(mac);
2657
2658         if (lo == NULL)
2659                 goto fail;
2660
2661         BWN_GETTIME(now);
2662         if (bwn_has_hwpctl(mac)) {
2663                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2664                 if (time_before(lo->pwr_vec_read_time, expire)) {
2665                         bwn_lo_get_powervector(mac);
2666                         bwn_phy_g_dc_lookup_init(mac, 0);
2667                 }
2668                 goto fail;
2669         }
2670
2671         expire = now - BWN_LO_CALIB_EXPIRE;
2672         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2673                 if (!time_before(cal->calib_time, expire))
2674                         continue;
2675                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2676                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2677                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2678                         expired = 1;
2679                 }
2680
2681                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2682                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2683                     cal->ctl.i, cal->ctl.q);
2684
2685                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2686                 free(cal, M_DEVBUF);
2687         }
2688         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2689                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2690                     &pg->pg_rfatt);
2691                 if (cal == NULL) {
2692                         device_printf(sc->sc_dev,
2693                             "failed to recalibrate LO\n");
2694                         goto fail;
2695                 }
2696                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2697                 bwn_lo_write(mac, &cal->ctl);
2698         }
2699
2700 fail:
2701         bwn_mac_enable(mac);
2702 }
2703
2704 static void
2705 bwn_phy_g_task_60s(struct bwn_mac *mac)
2706 {
2707         struct bwn_phy *phy = &mac->mac_phy;
2708         struct bwn_softc *sc = mac->mac_sc;
2709         uint8_t old = phy->chan;
2710
2711         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2712                 return;
2713
2714         bwn_mac_suspend(mac);
2715         bwn_nrssi_slope_11g(mac);
2716         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2717                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2718                 bwn_switch_channel(mac, old);
2719         }
2720         bwn_mac_enable(mac);
2721 }
2722
2723 static void
2724 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2725 {
2726
2727         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2728 }
2729
2730 static int
2731 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2732         const struct ieee80211_bpf_params *params)
2733 {
2734         struct ieee80211com *ic = ni->ni_ic;
2735         struct ifnet *ifp = ic->ic_ifp;
2736         struct bwn_softc *sc = ifp->if_softc;
2737         struct bwn_mac *mac = sc->sc_curmac;
2738
2739         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2740             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2741                 ieee80211_free_node(ni);
2742                 m_freem(m);
2743                 return (ENETDOWN);
2744         }
2745
2746         BWN_LOCK(sc);
2747         if (bwn_tx_isfull(sc, m)) {
2748                 ieee80211_free_node(ni);
2749                 m_freem(m);
2750                 ifp->if_oerrors++;
2751                 BWN_UNLOCK(sc);
2752                 return (ENOBUFS);
2753         }
2754
2755         if (bwn_tx_start(sc, ni, m) != 0) {
2756                 if (ni != NULL)
2757                         ieee80211_free_node(ni);
2758                 ifp->if_oerrors++;
2759         }
2760         sc->sc_watchdog_timer = 5;
2761         BWN_UNLOCK(sc);
2762         return (0);
2763 }
2764
2765 /*
2766  * Callback from the 802.11 layer to update the slot time
2767  * based on the current setting.  We use it to notify the
2768  * firmware of ERP changes and the f/w takes care of things
2769  * like slot time and preamble.
2770  */
2771 static void
2772 bwn_updateslot(struct ifnet *ifp)
2773 {
2774         struct bwn_softc *sc = ifp->if_softc;
2775         struct ieee80211com *ic = ifp->if_l2com;
2776         struct bwn_mac *mac;
2777
2778         BWN_LOCK(sc);
2779         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2780                 mac = (struct bwn_mac *)sc->sc_curmac;
2781                 bwn_set_slot_time(mac,
2782                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2783         }
2784         BWN_UNLOCK(sc);
2785 }
2786
2787 /*
2788  * Callback from the 802.11 layer after a promiscuous mode change.
2789  * Note this interface does not check the operating mode as this
2790  * is an internal callback and we are expected to honor the current
2791  * state (e.g. this is used for setting the interface in promiscuous
2792  * mode when operating in hostap mode to do ACS).
2793  */
2794 static void
2795 bwn_update_promisc(struct ifnet *ifp)
2796 {
2797         struct bwn_softc *sc = ifp->if_softc;
2798         struct bwn_mac *mac = sc->sc_curmac;
2799
2800         BWN_LOCK(sc);
2801         mac = sc->sc_curmac;
2802         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2803                 if (ifp->if_flags & IFF_PROMISC)
2804                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2805                 else
2806                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2807                 bwn_set_opmode(mac);
2808         }
2809         BWN_UNLOCK(sc);
2810 }
2811
2812 /*
2813  * Callback from the 802.11 layer to update WME parameters.
2814  */
2815 static int
2816 bwn_wme_update(struct ieee80211com *ic)
2817 {
2818         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2819         struct bwn_mac *mac = sc->sc_curmac;
2820         struct wmeParams *wmep;
2821         int i;
2822
2823         BWN_LOCK(sc);
2824         mac = sc->sc_curmac;
2825         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2826                 bwn_mac_suspend(mac);
2827                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2828                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2829                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2830                 }
2831                 bwn_mac_enable(mac);
2832         }
2833         BWN_UNLOCK(sc);
2834         return (0);
2835 }
2836
2837 static void
2838 bwn_scan_start(struct ieee80211com *ic)
2839 {
2840         struct ifnet *ifp = ic->ic_ifp;
2841         struct bwn_softc *sc = ifp->if_softc;
2842         struct bwn_mac *mac;
2843
2844         BWN_LOCK(sc);
2845         mac = sc->sc_curmac;
2846         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2848                 bwn_set_opmode(mac);
2849                 /* disable CFP update during scan */
2850                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2851         }
2852         BWN_UNLOCK(sc);
2853 }
2854
2855 static void
2856 bwn_scan_end(struct ieee80211com *ic)
2857 {
2858         struct ifnet *ifp = ic->ic_ifp;
2859         struct bwn_softc *sc = ifp->if_softc;
2860         struct bwn_mac *mac;
2861
2862         BWN_LOCK(sc);
2863         mac = sc->sc_curmac;
2864         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2865                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2866                 bwn_set_opmode(mac);
2867                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2868         }
2869         BWN_UNLOCK(sc);
2870 }
2871
2872 static void
2873 bwn_set_channel(struct ieee80211com *ic)
2874 {
2875         struct ifnet *ifp = ic->ic_ifp;
2876         struct bwn_softc *sc = ifp->if_softc;
2877         struct bwn_mac *mac = sc->sc_curmac;
2878         struct bwn_phy *phy = &mac->mac_phy;
2879         int chan, error;
2880
2881         BWN_LOCK(sc);
2882
2883         error = bwn_switch_band(sc, ic->ic_curchan);
2884         if (error)
2885                 goto fail;
2886         bwn_mac_suspend(mac);
2887         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2888         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2889         if (chan != phy->chan)
2890                 bwn_switch_channel(mac, chan);
2891
2892         /* TX power level */
2893         if (ic->ic_curchan->ic_maxpower != 0 &&
2894             ic->ic_curchan->ic_maxpower != phy->txpower) {
2895                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2896                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2897                     BWN_TXPWR_IGNORE_TSSI);
2898         }
2899
2900         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2901         if (phy->set_antenna)
2902                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2903
2904         if (sc->sc_rf_enabled != phy->rf_on) {
2905                 if (sc->sc_rf_enabled) {
2906                         bwn_rf_turnon(mac);
2907                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2908                                 device_printf(sc->sc_dev,
2909                                     "please turn on the RF switch\n");
2910                 } else
2911                         bwn_rf_turnoff(mac);
2912         }
2913
2914         bwn_mac_enable(mac);
2915
2916 fail:
2917         /*
2918          * Setup radio tap channel freq and flags
2919          */
2920         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2921                 htole16(ic->ic_curchan->ic_freq);
2922         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2923                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2924
2925         BWN_UNLOCK(sc);
2926 }
2927
2928 static struct ieee80211vap *
2929 bwn_vap_create(struct ieee80211com *ic,
2930         const char name[IFNAMSIZ], int unit, int opmode, int flags,
2931         const uint8_t bssid[IEEE80211_ADDR_LEN],
2932         const uint8_t mac0[IEEE80211_ADDR_LEN])
2933 {
2934         struct ifnet *ifp = ic->ic_ifp;
2935         struct bwn_softc *sc = ifp->if_softc;
2936         struct ieee80211vap *vap;
2937         struct bwn_vap *bvp;
2938         uint8_t mac[IEEE80211_ADDR_LEN];
2939
2940         IEEE80211_ADDR_COPY(mac, mac0);
2941         switch (opmode) {
2942         case IEEE80211_M_HOSTAP:
2943         case IEEE80211_M_MBSS:
2944         case IEEE80211_M_STA:
2945         case IEEE80211_M_WDS:
2946         case IEEE80211_M_MONITOR:
2947         case IEEE80211_M_IBSS:
2948         case IEEE80211_M_AHDEMO:
2949                 break;
2950         default:
2951                 return (NULL);
2952         }
2953
2954         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2955
2956         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2957             M_80211_VAP, M_NOWAIT | M_ZERO);
2958         if (bvp == NULL) {
2959                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2960                 return (NULL);
2961         }
2962         vap = &bvp->bv_vap;
2963         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2964         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2965         /* override with driver methods */
2966         bvp->bv_newstate = vap->iv_newstate;
2967         vap->iv_newstate = bwn_newstate;
2968
2969         /* override max aid so sta's cannot assoc when we're out of sta id's */
2970         vap->iv_max_aid = BWN_STAID_MAX;
2971
2972         ieee80211_ratectl_init(vap);
2973
2974         /* complete setup */
2975         ieee80211_vap_attach(vap, ieee80211_media_change,
2976             ieee80211_media_status);
2977         return (vap);
2978 }
2979
2980 static void
2981 bwn_vap_delete(struct ieee80211vap *vap)
2982 {
2983         struct bwn_vap *bvp = BWN_VAP(vap);
2984
2985         ieee80211_ratectl_deinit(vap);
2986         ieee80211_vap_detach(vap);
2987         free(bvp, M_80211_VAP);
2988 }
2989
2990 static void
2991 bwn_init(void *arg)
2992 {
2993         struct bwn_softc *sc = arg;
2994         struct ifnet *ifp = sc->sc_ifp;
2995         struct ieee80211com *ic = ifp->if_l2com;
2996         int error = 0;
2997
2998         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2999                 __func__, ifp->if_flags);
3000
3001         BWN_LOCK(sc);
3002         error = bwn_init_locked(sc);
3003         BWN_UNLOCK(sc);
3004
3005         if (error == 0)
3006                 ieee80211_start_all(ic);        /* start all vap's */
3007 }
3008
3009 static int
3010 bwn_init_locked(struct bwn_softc *sc)
3011 {
3012         struct bwn_mac *mac;
3013         struct ifnet *ifp = sc->sc_ifp;
3014         int error;
3015
3016         BWN_ASSERT_LOCKED(sc);
3017
3018         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3019         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3020         sc->sc_filters = 0;
3021         bwn_wme_clear(sc);
3022         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3023         sc->sc_rf_enabled = 1;
3024
3025         mac = sc->sc_curmac;
3026         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3027                 error = bwn_core_init(mac);
3028                 if (error != 0)
3029                         return (error);
3030         }
3031         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3032                 bwn_core_start(mac);
3033
3034         bwn_set_opmode(mac);
3035         bwn_set_pretbtt(mac);
3036         bwn_spu_setdelay(mac, 0);
3037         bwn_set_macaddr(mac);
3038
3039         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3040         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3041         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3042
3043         return (0);
3044 }
3045
3046 static void
3047 bwn_stop(struct bwn_softc *sc, int statechg)
3048 {
3049
3050         BWN_LOCK(sc);
3051         bwn_stop_locked(sc, statechg);
3052         BWN_UNLOCK(sc);
3053 }
3054
3055 static void
3056 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3057 {
3058         struct bwn_mac *mac = sc->sc_curmac;
3059         struct ifnet *ifp = sc->sc_ifp;
3060
3061         BWN_ASSERT_LOCKED(sc);
3062
3063         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3064                 /* XXX FIXME opmode not based on VAP */
3065                 bwn_set_opmode(mac);
3066                 bwn_set_macaddr(mac);
3067         }
3068
3069         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3070                 bwn_core_stop(mac);
3071
3072         callout_stop(&sc->sc_led_blink_ch);
3073         sc->sc_led_blinking = 0;
3074
3075         bwn_core_exit(mac);
3076         sc->sc_rf_enabled = 0;
3077
3078         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3079 }
3080
3081 static void
3082 bwn_wme_clear(struct bwn_softc *sc)
3083 {
3084 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3085         struct wmeParams *p;
3086         unsigned int i;
3087
3088         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3089             ("%s:%d: fail", __func__, __LINE__));
3090
3091         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3092                 p = &(sc->sc_wmeParams[i]);
3093
3094                 switch (bwn_wme_shm_offsets[i]) {
3095                 case BWN_WME_VOICE:
3096                         p->wmep_txopLimit = 0;
3097                         p->wmep_aifsn = 2;
3098                         /* XXX FIXME: log2(cwmin) */
3099                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3100                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3101                         break;
3102                 case BWN_WME_VIDEO:
3103                         p->wmep_txopLimit = 0;
3104                         p->wmep_aifsn = 2;
3105                         /* XXX FIXME: log2(cwmin) */
3106                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3107                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3108                         break;
3109                 case BWN_WME_BESTEFFORT:
3110                         p->wmep_txopLimit = 0;
3111                         p->wmep_aifsn = 3;
3112                         /* XXX FIXME: log2(cwmin) */
3113                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3114                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3115                         break;
3116                 case BWN_WME_BACKGROUND:
3117                         p->wmep_txopLimit = 0;
3118                         p->wmep_aifsn = 7;
3119                         /* XXX FIXME: log2(cwmin) */
3120                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3121                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3122                         break;
3123                 default:
3124                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3125                 }
3126         }
3127 }
3128
3129 static int
3130 bwn_core_init(struct bwn_mac *mac)
3131 {
3132         struct bwn_softc *sc = mac->mac_sc;
3133         uint64_t hf;
3134         int error;
3135
3136         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3137             ("%s:%d: fail", __func__, __LINE__));
3138
3139         siba_powerup(sc->sc_dev, 0);
3140         if (!siba_dev_isup(sc->sc_dev))
3141                 bwn_reset_core(mac,
3142                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3143
3144         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3145         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3146         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3147         BWN_GETTIME(mac->mac_phy.nexttime);
3148         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3149         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3150         mac->mac_stats.link_noise = -95;
3151         mac->mac_reason_intr = 0;
3152         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3153         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3154 #ifdef BWN_DEBUG
3155         if (sc->sc_debug & BWN_DEBUG_XMIT)
3156                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3157 #endif
3158         mac->mac_suspended = 1;
3159         mac->mac_task_state = 0;
3160         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3161
3162         mac->mac_phy.init_pre(mac);
3163
3164         siba_pcicore_intr(sc->sc_dev);
3165
3166         siba_fix_imcfglobug(sc->sc_dev);
3167         bwn_bt_disable(mac);
3168         if (mac->mac_phy.prepare_hw) {
3169                 error = mac->mac_phy.prepare_hw(mac);
3170                 if (error)
3171                         goto fail0;
3172         }
3173         error = bwn_chip_init(mac);
3174         if (error)
3175                 goto fail0;
3176         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3177             siba_get_revid(sc->sc_dev));
3178         hf = bwn_hf_read(mac);
3179         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3180                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3181                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3182                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3183                 if (mac->mac_phy.rev == 1)
3184                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3185         }
3186         if (mac->mac_phy.rf_ver == 0x2050) {
3187                 if (mac->mac_phy.rf_rev < 6)
3188                         hf |= BWN_HF_FORCE_VCO_RECALC;
3189                 if (mac->mac_phy.rf_rev == 6)
3190                         hf |= BWN_HF_4318_TSSI;
3191         }
3192         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3193                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3194         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3195             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3196                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3197         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3198         bwn_hf_write(mac, hf);
3199
3200         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3201         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3202         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3203         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3204
3205         bwn_rate_init(mac);
3206         bwn_set_phytxctl(mac);
3207
3208         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3209             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3210         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3211
3212         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3213                 bwn_pio_init(mac);
3214         else
3215                 bwn_dma_init(mac);
3216         bwn_wme_init(mac);
3217         bwn_spu_setdelay(mac, 1);
3218         bwn_bt_enable(mac);
3219
3220         siba_powerup(sc->sc_dev,
3221             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3222         bwn_set_macaddr(mac);
3223         bwn_crypt_init(mac);
3224
3225         /* XXX LED initializatin */
3226
3227         mac->mac_status = BWN_MAC_STATUS_INITED;
3228
3229         return (error);
3230
3231 fail0:
3232         siba_powerdown(sc->sc_dev);
3233         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3234             ("%s:%d: fail", __func__, __LINE__));
3235         return (error);
3236 }
3237
3238 static void
3239 bwn_core_start(struct bwn_mac *mac)
3240 {
3241         struct bwn_softc *sc = mac->mac_sc;
3242         uint32_t tmp;
3243
3244         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3245             ("%s:%d: fail", __func__, __LINE__));
3246
3247         if (siba_get_revid(sc->sc_dev) < 5)
3248                 return;
3249
3250         while (1) {
3251                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3252                 if (!(tmp & 0x00000001))
3253                         break;
3254                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3255         }
3256
3257         bwn_mac_enable(mac);
3258         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3259         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3260
3261         mac->mac_status = BWN_MAC_STATUS_STARTED;
3262 }
3263
3264 static void
3265 bwn_core_exit(struct bwn_mac *mac)
3266 {
3267         struct bwn_softc *sc = mac->mac_sc;
3268         uint32_t macctl;
3269
3270         BWN_ASSERT_LOCKED(mac->mac_sc);
3271
3272         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3273             ("%s:%d: fail", __func__, __LINE__));
3274
3275         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3276                 return;
3277         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3278
3279         macctl = BWN_READ_4(mac, BWN_MACCTL);
3280         macctl &= ~BWN_MACCTL_MCODE_RUN;
3281         macctl |= BWN_MACCTL_MCODE_JMP0;
3282         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3283
3284         bwn_dma_stop(mac);
3285         bwn_pio_stop(mac);
3286         bwn_chip_exit(mac);
3287         mac->mac_phy.switch_analog(mac, 0);
3288         siba_dev_down(sc->sc_dev, 0);
3289         siba_powerdown(sc->sc_dev);
3290 }
3291
3292 static void
3293 bwn_bt_disable(struct bwn_mac *mac)
3294 {
3295         struct bwn_softc *sc = mac->mac_sc;
3296
3297         (void)sc;
3298         /* XXX do nothing yet */
3299 }
3300
3301 static int
3302 bwn_chip_init(struct bwn_mac *mac)
3303 {
3304         struct bwn_softc *sc = mac->mac_sc;
3305         struct bwn_phy *phy = &mac->mac_phy;
3306         uint32_t macctl;
3307         int error;
3308
3309         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3310         if (phy->gmode)
3311                 macctl |= BWN_MACCTL_GMODE;
3312         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3313
3314         error = bwn_fw_fillinfo(mac);
3315         if (error)
3316                 return (error);
3317         error = bwn_fw_loaducode(mac);
3318         if (error)
3319                 return (error);
3320
3321         error = bwn_gpio_init(mac);
3322         if (error)
3323                 return (error);
3324
3325         error = bwn_fw_loadinitvals(mac);
3326         if (error) {
3327                 siba_gpio_set(sc->sc_dev, 0);
3328                 return (error);
3329         }
3330         phy->switch_analog(mac, 1);
3331         error = bwn_phy_init(mac);
3332         if (error) {
3333                 siba_gpio_set(sc->sc_dev, 0);
3334                 return (error);
3335         }
3336         if (phy->set_im)
3337                 phy->set_im(mac, BWN_IMMODE_NONE);
3338         if (phy->set_antenna)
3339                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3340         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3341
3342         if (phy->type == BWN_PHYTYPE_B)
3343                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3344         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3345         if (siba_get_revid(sc->sc_dev) < 5)
3346                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3347
3348         BWN_WRITE_4(mac, BWN_MACCTL,
3349             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3350         BWN_WRITE_4(mac, BWN_MACCTL,
3351             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3352         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3353
3354         bwn_set_opmode(mac);
3355         if (siba_get_revid(sc->sc_dev) < 3) {
3356                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3357                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3358                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3359                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3360         } else {
3361                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3362                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3363         }
3364         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3365         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3366         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3367         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3368         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3369         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3370         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3371         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3372             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3373         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3374         return (error);
3375 }
3376
3377 /* read hostflags */
3378 static uint64_t
3379 bwn_hf_read(struct bwn_mac *mac)
3380 {
3381         uint64_t ret;
3382
3383         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3384         ret <<= 16;
3385         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3386         ret <<= 16;
3387         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3388         return (ret);
3389 }
3390
3391 static void
3392 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3393 {
3394
3395         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3396             (value & 0x00000000ffffull));
3397         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3398             (value & 0x0000ffff0000ull) >> 16);
3399         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3400             (value & 0xffff00000000ULL) >> 32);
3401 }
3402
3403 static void
3404 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3405 {
3406
3407         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3408         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3409 }
3410
3411 static void
3412 bwn_rate_init(struct bwn_mac *mac)
3413 {
3414
3415         switch (mac->mac_phy.type) {
3416         case BWN_PHYTYPE_A:
3417         case BWN_PHYTYPE_G:
3418         case BWN_PHYTYPE_LP:
3419         case BWN_PHYTYPE_N:
3420                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3421                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3422                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3423                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3424                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3425                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3426                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3427                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3428                         break;
3429                 /* FALLTHROUGH */
3430         case BWN_PHYTYPE_B:
3431                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3432                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3433                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3434                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3435                 break;
3436         default:
3437                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3438         }
3439 }
3440
3441 static void
3442 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3443 {
3444         uint16_t offset;
3445
3446         if (ofdm) {
3447                 offset = 0x480;
3448                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3449         } else {
3450                 offset = 0x4c0;
3451                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3452         }
3453         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3454             bwn_shm_read_2(mac, BWN_SHARED, offset));
3455 }
3456
3457 static uint8_t
3458 bwn_plcp_getcck(const uint8_t bitrate)
3459 {
3460
3461         switch (bitrate) {
3462         case BWN_CCK_RATE_1MB:
3463                 return (0x0a);
3464         case BWN_CCK_RATE_2MB:
3465                 return (0x14);
3466         case BWN_CCK_RATE_5MB:
3467                 return (0x37);
3468         case BWN_CCK_RATE_11MB:
3469                 return (0x6e);
3470         }
3471         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3472         return (0);
3473 }
3474
3475 static uint8_t
3476 bwn_plcp_getofdm(const uint8_t bitrate)
3477 {
3478
3479         switch (bitrate) {
3480         case BWN_OFDM_RATE_6MB:
3481                 return (0xb);
3482         case BWN_OFDM_RATE_9MB:
3483                 return (0xf);
3484         case BWN_OFDM_RATE_12MB:
3485                 return (0xa);
3486         case BWN_OFDM_RATE_18MB:
3487                 return (0xe);
3488         case BWN_OFDM_RATE_24MB:
3489                 return (0x9);
3490         case BWN_OFDM_RATE_36MB:
3491                 return (0xd);
3492         case BWN_OFDM_RATE_48MB:
3493                 return (0x8);
3494         case BWN_OFDM_RATE_54MB:
3495                 return (0xc);
3496         }
3497         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3498         return (0);
3499 }
3500
3501 static void
3502 bwn_set_phytxctl(struct bwn_mac *mac)
3503 {
3504         uint16_t ctl;
3505
3506         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3507             BWN_TX_PHY_TXPWR);
3508         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3509         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3510         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3511 }
3512
3513 static void
3514 bwn_pio_init(struct bwn_mac *mac)
3515 {
3516         struct bwn_pio *pio = &mac->mac_method.pio;
3517
3518         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3519             & ~BWN_MACCTL_BIGENDIAN);
3520         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3521
3522         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3523         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3524         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3525         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3526         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3527         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3528 }
3529
3530 static void
3531 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3532     int index)
3533 {
3534         struct bwn_pio_txpkt *tp;
3535         struct bwn_softc *sc = mac->mac_sc;
3536         unsigned int i;
3537
3538         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3539         tq->tq_index = index;
3540
3541         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3542         if (siba_get_revid(sc->sc_dev) >= 8)
3543                 tq->tq_size = 1920;
3544         else {
3545                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3546                 tq->tq_size -= 80;
3547         }
3548
3549         TAILQ_INIT(&tq->tq_pktlist);
3550         for (i = 0; i < N(tq->tq_pkts); i++) {
3551                 tp = &(tq->tq_pkts[i]);
3552                 tp->tp_index = i;
3553                 tp->tp_queue = tq;
3554                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3555         }
3556 }
3557
3558 static uint16_t
3559 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3560 {
3561         struct bwn_softc *sc = mac->mac_sc;
3562         static const uint16_t bases[] = {
3563                 BWN_PIO_BASE0,
3564                 BWN_PIO_BASE1,
3565                 BWN_PIO_BASE2,
3566                 BWN_PIO_BASE3,
3567                 BWN_PIO_BASE4,
3568                 BWN_PIO_BASE5,
3569                 BWN_PIO_BASE6,
3570                 BWN_PIO_BASE7,
3571         };
3572         static const uint16_t bases_rev11[] = {
3573                 BWN_PIO11_BASE0,
3574                 BWN_PIO11_BASE1,
3575                 BWN_PIO11_BASE2,
3576                 BWN_PIO11_BASE3,
3577                 BWN_PIO11_BASE4,
3578                 BWN_PIO11_BASE5,
3579         };
3580
3581         if (siba_get_revid(sc->sc_dev) >= 11) {
3582                 if (index >= N(bases_rev11))
3583                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3584                 return (bases_rev11[index]);
3585         }
3586         if (index >= N(bases))
3587                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3588         return (bases[index]);
3589 }
3590
3591 static void
3592 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3593     int index)
3594 {
3595         struct bwn_softc *sc = mac->mac_sc;
3596
3597         prq->prq_mac = mac;
3598         prq->prq_rev = siba_get_revid(sc->sc_dev);
3599         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3600         bwn_dma_rxdirectfifo(mac, index, 1);
3601 }
3602
3603 static void
3604 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3605 {
3606         if (tq == NULL)
3607                 return;
3608         bwn_pio_cancel_tx_packets(tq);
3609 }
3610
3611 static void
3612 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3613 {
3614
3615         bwn_destroy_pioqueue_tx(pio);
3616 }
3617
3618 static uint16_t
3619 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3620     uint16_t offset)
3621 {
3622
3623         return (BWN_READ_2(mac, tq->tq_base + offset));
3624 }
3625
3626 static void
3627 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3628 {
3629         uint32_t ctl;
3630         int type;
3631         uint16_t base;
3632
3633         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3634         base = bwn_dma_base(type, idx);
3635         if (type == BWN_DMA_64BIT) {
3636                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3637                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3638                 if (enable)
3639                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3640                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3641         } else {
3642                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3643                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3644                 if (enable)
3645                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3646                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3647         }
3648 }
3649
3650 static uint64_t
3651 bwn_dma_mask(struct bwn_mac *mac)
3652 {
3653         uint32_t tmp;
3654         uint16_t base;
3655
3656         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3657         if (tmp & SIBA_TGSHIGH_DMA64)
3658                 return (BWN_DMA_BIT_MASK(64));
3659         base = bwn_dma_base(0, 0);
3660         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3661         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3662         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3663                 return (BWN_DMA_BIT_MASK(32));
3664
3665         return (BWN_DMA_BIT_MASK(30));
3666 }
3667
3668 static int
3669 bwn_dma_mask2type(uint64_t dmamask)
3670 {
3671
3672         if (dmamask == BWN_DMA_BIT_MASK(30))
3673                 return (BWN_DMA_30BIT);
3674         if (dmamask == BWN_DMA_BIT_MASK(32))
3675                 return (BWN_DMA_32BIT);
3676         if (dmamask == BWN_DMA_BIT_MASK(64))
3677                 return (BWN_DMA_64BIT);
3678         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3679         return (BWN_DMA_30BIT);
3680 }
3681
3682 static void
3683 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3684 {
3685         struct bwn_pio_txpkt *tp;
3686         unsigned int i;
3687
3688         for (i = 0; i < N(tq->tq_pkts); i++) {
3689                 tp = &(tq->tq_pkts[i]);
3690                 if (tp->tp_m) {
3691                         m_freem(tp->tp_m);
3692                         tp->tp_m = NULL;
3693                 }
3694         }
3695 }
3696
3697 static uint16_t
3698 bwn_dma_base(int type, int controller_idx)
3699 {
3700         static const uint16_t map64[] = {
3701                 BWN_DMA64_BASE0,
3702                 BWN_DMA64_BASE1,
3703                 BWN_DMA64_BASE2,
3704                 BWN_DMA64_BASE3,
3705                 BWN_DMA64_BASE4,
3706                 BWN_DMA64_BASE5,
3707         };
3708         static const uint16_t map32[] = {
3709                 BWN_DMA32_BASE0,
3710                 BWN_DMA32_BASE1,
3711                 BWN_DMA32_BASE2,
3712                 BWN_DMA32_BASE3,
3713                 BWN_DMA32_BASE4,
3714                 BWN_DMA32_BASE5,
3715         };
3716
3717         if (type == BWN_DMA_64BIT) {
3718                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3719                     ("%s:%d: fail", __func__, __LINE__));
3720                 return (map64[controller_idx]);
3721         }
3722         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3723             ("%s:%d: fail", __func__, __LINE__));
3724         return (map32[controller_idx]);
3725 }
3726
3727 static void
3728 bwn_dma_init(struct bwn_mac *mac)
3729 {
3730         struct bwn_dma *dma = &mac->mac_method.dma;
3731
3732         /* setup TX DMA channels. */
3733         bwn_dma_setup(dma->wme[WME_AC_BK]);
3734         bwn_dma_setup(dma->wme[WME_AC_BE]);
3735         bwn_dma_setup(dma->wme[WME_AC_VI]);
3736         bwn_dma_setup(dma->wme[WME_AC_VO]);
3737         bwn_dma_setup(dma->mcast);
3738         /* setup RX DMA channel. */
3739         bwn_dma_setup(dma->rx);
3740 }
3741
3742 static struct bwn_dma_ring *
3743 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3744     int for_tx, int type)
3745 {
3746         struct bwn_dma *dma = &mac->mac_method.dma;
3747         struct bwn_dma_ring *dr;
3748         struct bwn_dmadesc_generic *desc;
3749         struct bwn_dmadesc_meta *mt;
3750         struct bwn_softc *sc = mac->mac_sc;
3751         int error, i;
3752
3753         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3754         if (dr == NULL)
3755                 goto out;
3756         dr->dr_numslots = BWN_RXRING_SLOTS;
3757         if (for_tx)
3758                 dr->dr_numslots = BWN_TXRING_SLOTS;
3759
3760         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3761             M_DEVBUF, M_NOWAIT | M_ZERO);
3762         if (dr->dr_meta == NULL)
3763                 goto fail0;
3764
3765         dr->dr_type = type;
3766         dr->dr_mac = mac;
3767         dr->dr_base = bwn_dma_base(type, controller_index);
3768         dr->dr_index = controller_index;
3769         if (type == BWN_DMA_64BIT) {
3770                 dr->getdesc = bwn_dma_64_getdesc;
3771                 dr->setdesc = bwn_dma_64_setdesc;
3772                 dr->start_transfer = bwn_dma_64_start_transfer;
3773                 dr->suspend = bwn_dma_64_suspend;
3774                 dr->resume = bwn_dma_64_resume;
3775                 dr->get_curslot = bwn_dma_64_get_curslot;
3776                 dr->set_curslot = bwn_dma_64_set_curslot;
3777         } else {
3778                 dr->getdesc = bwn_dma_32_getdesc;
3779                 dr->setdesc = bwn_dma_32_setdesc;
3780                 dr->start_transfer = bwn_dma_32_start_transfer;
3781                 dr->suspend = bwn_dma_32_suspend;
3782                 dr->resume = bwn_dma_32_resume;
3783                 dr->get_curslot = bwn_dma_32_get_curslot;
3784                 dr->set_curslot = bwn_dma_32_set_curslot;
3785         }
3786         if (for_tx) {
3787                 dr->dr_tx = 1;
3788                 dr->dr_curslot = -1;
3789         } else {
3790                 if (dr->dr_index == 0) {
3791                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3792                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3793                 } else
3794                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3795         }
3796
3797         error = bwn_dma_allocringmemory(dr);
3798         if (error)
3799                 goto fail2;
3800
3801         if (for_tx) {
3802                 /*
3803                  * Assumption: BWN_TXRING_SLOTS can be divided by
3804                  * BWN_TX_SLOTS_PER_FRAME
3805                  */
3806                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3807                     ("%s:%d: fail", __func__, __LINE__));
3808
3809                 dr->dr_txhdr_cache =
3810                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3811                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3812                 KASSERT(dr->dr_txhdr_cache != NULL,
3813                     ("%s:%d: fail", __func__, __LINE__));
3814
3815                 /*
3816                  * Create TX ring DMA stuffs
3817                  */
3818                 error = bus_dma_tag_create(dma->parent_dtag,
3819                                     BWN_ALIGN, 0,
3820                                     BUS_SPACE_MAXADDR,
3821                                     BUS_SPACE_MAXADDR,
3822                                     NULL, NULL,
3823                                     BWN_HDRSIZE(mac),
3824                                     1,
3825                                     BUS_SPACE_MAXSIZE_32BIT,
3826                                     0,
3827                                     NULL, NULL,
3828                                     &dr->dr_txring_dtag);
3829                 if (error) {
3830                         device_printf(sc->sc_dev,
3831                             "can't create TX ring DMA tag: TODO frees\n");
3832                         goto fail1;
3833                 }
3834
3835                 for (i = 0; i < dr->dr_numslots; i += 2) {
3836                         dr->getdesc(dr, i, &desc, &mt);
3837
3838                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3839                         mt->mt_m = NULL;
3840                         mt->mt_ni = NULL;
3841                         mt->mt_islast = 0;
3842                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3843                             &mt->mt_dmap);
3844                         if (error) {
3845                                 device_printf(sc->sc_dev,
3846                                      "can't create RX buf DMA map\n");
3847                                 goto fail1;
3848                         }
3849
3850                         dr->getdesc(dr, i + 1, &desc, &mt);
3851
3852                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3853                         mt->mt_m = NULL;
3854                         mt->mt_ni = NULL;
3855                         mt->mt_islast = 1;
3856                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3857                             &mt->mt_dmap);
3858                         if (error) {
3859                                 device_printf(sc->sc_dev,
3860                                      "can't create RX buf DMA map\n");
3861                                 goto fail1;
3862                         }
3863                 }
3864         } else {
3865                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3866                     &dr->dr_spare_dmap);
3867                 if (error) {
3868                         device_printf(sc->sc_dev,
3869                             "can't create RX buf DMA map\n");
3870                         goto out;               /* XXX wrong! */
3871                 }
3872
3873                 for (i = 0; i < dr->dr_numslots; i++) {
3874                         dr->getdesc(dr, i, &desc, &mt);
3875
3876                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3877                             &mt->mt_dmap);
3878                         if (error) {
3879                                 device_printf(sc->sc_dev,
3880                                     "can't create RX buf DMA map\n");
3881                                 goto out;       /* XXX wrong! */
3882                         }
3883                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3884                         if (error) {
3885                                 device_printf(sc->sc_dev,
3886                                     "failed to allocate RX buf\n");
3887                                 goto out;       /* XXX wrong! */
3888                         }
3889                 }
3890
3891                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3892                     BUS_DMASYNC_PREWRITE);
3893
3894                 dr->dr_usedslot = dr->dr_numslots;
3895         }
3896
3897       out:
3898         return (dr);
3899
3900 fail2:
3901         free(dr->dr_txhdr_cache, M_DEVBUF);
3902 fail1:
3903         free(dr->dr_meta, M_DEVBUF);
3904 fail0:
3905         free(dr, M_DEVBUF);
3906         return (NULL);
3907 }
3908
3909 static void
3910 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3911 {
3912
3913         if (dr == NULL)
3914                 return;
3915
3916         bwn_dma_free_descbufs(*dr);
3917         bwn_dma_free_ringmemory(*dr);
3918
3919         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3920         free((*dr)->dr_meta, M_DEVBUF);
3921         free(*dr, M_DEVBUF);
3922
3923         *dr = NULL;
3924 }
3925
3926 static void
3927 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3928     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3929 {
3930         struct bwn_dmadesc32 *desc;
3931
3932         *meta = &(dr->dr_meta[slot]);
3933         desc = dr->dr_ring_descbase;
3934         desc = &(desc[slot]);
3935
3936         *gdesc = (struct bwn_dmadesc_generic *)desc;
3937 }
3938
3939 static void
3940 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3941     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3942     int start, int end, int irq)
3943 {
3944         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3945         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3946         uint32_t addr, addrext, ctl;
3947         int slot;
3948
3949         slot = (int)(&(desc->dma.dma32) - descbase);
3950         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3951             ("%s:%d: fail", __func__, __LINE__));
3952
3953         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3954         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3955         addr |= siba_dma_translation(sc->sc_dev);
3956         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3957         if (slot == dr->dr_numslots - 1)
3958                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3959         if (start)
3960                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3961         if (end)
3962                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3963         if (irq)
3964                 ctl |= BWN_DMA32_DCTL_IRQ;
3965         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3966             & BWN_DMA32_DCTL_ADDREXT_MASK;
3967
3968         desc->dma.dma32.control = htole32(ctl);
3969         desc->dma.dma32.address = htole32(addr);
3970 }
3971
3972 static void
3973 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3974 {
3975
3976         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3977             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3978 }
3979
3980 static void
3981 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3982 {
3983
3984         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3985             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3986 }
3987
3988 static void
3989 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3990 {
3991
3992         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3993             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3994 }
3995
3996 static int
3997 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3998 {
3999         uint32_t val;
4000
4001         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4002         val &= BWN_DMA32_RXDPTR;
4003
4004         return (val / sizeof(struct bwn_dmadesc32));
4005 }
4006
4007 static void
4008 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4009 {
4010
4011         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4012             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4013 }
4014
4015 static void
4016 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4017     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4018 {
4019         struct bwn_dmadesc64 *desc;
4020
4021         *meta = &(dr->dr_meta[slot]);
4022         desc = dr->dr_ring_descbase;
4023         desc = &(desc[slot]);
4024
4025         *gdesc = (struct bwn_dmadesc_generic *)desc;
4026 }
4027
4028 static void
4029 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4030     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4031     int start, int end, int irq)
4032 {
4033         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4034         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4035         int slot;
4036         uint32_t ctl0 = 0, ctl1 = 0;
4037         uint32_t addrlo, addrhi;
4038         uint32_t addrext;
4039
4040         slot = (int)(&(desc->dma.dma64) - descbase);
4041         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4042             ("%s:%d: fail", __func__, __LINE__));
4043
4044         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4045         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4046         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4047             30;
4048         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4049         if (slot == dr->dr_numslots - 1)
4050                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4051         if (start)
4052                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4053         if (end)
4054                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4055         if (irq)
4056                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4057         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4058         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4059             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4060
4061         desc->dma.dma64.control0 = htole32(ctl0);
4062         desc->dma.dma64.control1 = htole32(ctl1);
4063         desc->dma.dma64.address_low = htole32(addrlo);
4064         desc->dma.dma64.address_high = htole32(addrhi);
4065 }
4066
4067 static void
4068 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4069 {
4070
4071         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4072             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4073 }
4074
4075 static void
4076 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4077 {
4078
4079         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4080             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4081 }
4082
4083 static void
4084 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4085 {
4086
4087         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4088             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4089 }
4090
4091 static int
4092 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4093 {
4094         uint32_t val;
4095
4096         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4097         val &= BWN_DMA64_RXSTATDPTR;
4098
4099         return (val / sizeof(struct bwn_dmadesc64));
4100 }
4101
4102 static void
4103 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4104 {
4105
4106         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4107             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4108 }
4109
4110 static int
4111 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4112 {
4113         struct bwn_mac *mac = dr->dr_mac;
4114         struct bwn_dma *dma = &mac->mac_method.dma;
4115         struct bwn_softc *sc = mac->mac_sc;
4116         int error;
4117
4118         error = bus_dma_tag_create(dma->parent_dtag,
4119                             BWN_ALIGN, 0,
4120                             BUS_SPACE_MAXADDR,
4121                             BUS_SPACE_MAXADDR,
4122                             NULL, NULL,
4123                             BWN_DMA_RINGMEMSIZE,
4124                             1,
4125                             BUS_SPACE_MAXSIZE_32BIT,
4126                             0,
4127                             NULL, NULL,
4128                             &dr->dr_ring_dtag);
4129         if (error) {
4130                 device_printf(sc->sc_dev,
4131                     "can't create TX ring DMA tag: TODO frees\n");
4132                 return (-1);
4133         }
4134
4135         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4136             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4137             &dr->dr_ring_dmap);
4138         if (error) {
4139                 device_printf(sc->sc_dev,
4140                     "can't allocate DMA mem: TODO frees\n");
4141                 return (-1);
4142         }
4143         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4144             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4145             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4146         if (error) {
4147                 device_printf(sc->sc_dev,
4148                     "can't load DMA mem: TODO free\n");
4149                 return (-1);
4150         }
4151
4152         return (0);
4153 }
4154
4155 static void
4156 bwn_dma_setup(struct bwn_dma_ring *dr)
4157 {
4158         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4159         uint64_t ring64;
4160         uint32_t addrext, ring32, value;
4161         uint32_t trans = siba_dma_translation(sc->sc_dev);
4162
4163         if (dr->dr_tx) {
4164                 dr->dr_curslot = -1;
4165
4166                 if (dr->dr_type == BWN_DMA_64BIT) {
4167                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4168                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4169                             >> 30;
4170                         value = BWN_DMA64_TXENABLE;
4171                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4172                             & BWN_DMA64_TXADDREXT_MASK;
4173                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4174                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4175                             (ring64 & 0xffffffff));
4176                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4177                             ((ring64 >> 32) &
4178                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4179                 } else {
4180                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4181                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4182                         value = BWN_DMA32_TXENABLE;
4183                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4184                             & BWN_DMA32_TXADDREXT_MASK;
4185                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4186                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4187                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4188                 }
4189                 return;
4190         }
4191
4192         /*
4193          * set for RX
4194          */
4195         dr->dr_usedslot = dr->dr_numslots;
4196
4197         if (dr->dr_type == BWN_DMA_64BIT) {
4198                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4199                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4200                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4201                 value |= BWN_DMA64_RXENABLE;
4202                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4203                     & BWN_DMA64_RXADDREXT_MASK;
4204                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4205                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4206                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4207                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4208                     | (trans << 1));
4209                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4210                     sizeof(struct bwn_dmadesc64));
4211         } else {
4212                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4213                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4214                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4215                 value |= BWN_DMA32_RXENABLE;
4216                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4217                     & BWN_DMA32_RXADDREXT_MASK;
4218                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4219                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4220                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4221                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4222                     sizeof(struct bwn_dmadesc32));
4223         }
4224 }
4225
4226 static void
4227 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4228 {
4229
4230         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4231         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4232             dr->dr_ring_dmap);
4233 }
4234
4235 static void
4236 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4237 {
4238
4239         if (dr->dr_tx) {
4240                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4241                 if (dr->dr_type == BWN_DMA_64BIT) {
4242                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4243                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4244                 } else
4245                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4246         } else {
4247                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4248                 if (dr->dr_type == BWN_DMA_64BIT) {
4249                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4250                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4251                 } else
4252                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4253         }
4254 }
4255
4256 static void
4257 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4258 {
4259         struct bwn_dmadesc_generic *desc;
4260         struct bwn_dmadesc_meta *meta;
4261         struct bwn_mac *mac = dr->dr_mac;
4262         struct bwn_dma *dma = &mac->mac_method.dma;
4263         struct bwn_softc *sc = mac->mac_sc;
4264         int i;
4265
4266         if (!dr->dr_usedslot)
4267                 return;
4268         for (i = 0; i < dr->dr_numslots; i++) {
4269                 dr->getdesc(dr, i, &desc, &meta);
4270
4271                 if (meta->mt_m == NULL) {
4272                         if (!dr->dr_tx)
4273                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4274                                     __func__);
4275                         continue;
4276                 }
4277                 if (dr->dr_tx) {
4278                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4279                                 bus_dmamap_unload(dr->dr_txring_dtag,
4280                                     meta->mt_dmap);
4281                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4282                                 bus_dmamap_unload(dma->txbuf_dtag,
4283                                     meta->mt_dmap);
4284                 } else
4285                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4286                 bwn_dma_free_descbuf(dr, meta);
4287         }
4288 }
4289
4290 static int
4291 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4292     int type)
4293 {
4294         struct bwn_softc *sc = mac->mac_sc;
4295         uint32_t value;
4296         int i;
4297         uint16_t offset;
4298
4299         for (i = 0; i < 10; i++) {
4300                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4301                     BWN_DMA32_TXSTATUS;
4302                 value = BWN_READ_4(mac, base + offset);
4303                 if (type == BWN_DMA_64BIT) {
4304                         value &= BWN_DMA64_TXSTAT;
4305                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4306                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4307                             value == BWN_DMA64_TXSTAT_STOPPED)
4308                                 break;
4309                 } else {
4310                         value &= BWN_DMA32_TXSTATE;
4311                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4312                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4313                             value == BWN_DMA32_TXSTAT_STOPPED)
4314                                 break;
4315                 }
4316                 DELAY(1000);
4317         }
4318         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4319         BWN_WRITE_4(mac, base + offset, 0);
4320         for (i = 0; i < 10; i++) {
4321                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4322                                                    BWN_DMA32_TXSTATUS;
4323                 value = BWN_READ_4(mac, base + offset);
4324                 if (type == BWN_DMA_64BIT) {
4325                         value &= BWN_DMA64_TXSTAT;
4326                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4327                                 i = -1;
4328                                 break;
4329                         }
4330                 } else {
4331                         value &= BWN_DMA32_TXSTATE;
4332                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4333                                 i = -1;
4334                                 break;
4335                         }
4336                 }
4337                 DELAY(1000);
4338         }
4339         if (i != -1) {
4340                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4341                 return (ENODEV);
4342         }
4343         DELAY(1000);
4344
4345         return (0);
4346 }
4347
4348 static int
4349 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4350     int type)
4351 {
4352         struct bwn_softc *sc = mac->mac_sc;
4353         uint32_t value;
4354         int i;
4355         uint16_t offset;
4356
4357         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4358         BWN_WRITE_4(mac, base + offset, 0);
4359         for (i = 0; i < 10; i++) {
4360                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4361                     BWN_DMA32_RXSTATUS;
4362                 value = BWN_READ_4(mac, base + offset);
4363                 if (type == BWN_DMA_64BIT) {
4364                         value &= BWN_DMA64_RXSTAT;
4365                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4366                                 i = -1;
4367                                 break;
4368                         }
4369                 } else {
4370                         value &= BWN_DMA32_RXSTATE;
4371                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4372                                 i = -1;
4373                                 break;
4374                         }
4375                 }
4376                 DELAY(1000);
4377         }
4378         if (i != -1) {
4379                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4380                 return (ENODEV);
4381         }
4382
4383         return (0);
4384 }
4385
4386 static void
4387 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4388     struct bwn_dmadesc_meta *meta)
4389 {
4390
4391         if (meta->mt_m != NULL) {
4392                 m_freem(meta->mt_m);
4393                 meta->mt_m = NULL;
4394         }
4395         if (meta->mt_ni != NULL) {
4396                 ieee80211_free_node(meta->mt_ni);
4397                 meta->mt_ni = NULL;
4398         }
4399 }
4400
4401 static void
4402 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4403 {
4404         struct bwn_rxhdr4 *rxhdr;
4405         unsigned char *frame;
4406
4407         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4408         rxhdr->frame_len = 0;
4409
4410         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4411             sizeof(struct bwn_plcp6) + 2,
4412             ("%s:%d: fail", __func__, __LINE__));
4413         frame = mtod(m, char *) + dr->dr_frameoffset;
4414         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4415 }
4416
4417 static uint8_t
4418 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4419 {
4420         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4421
4422         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4423             == 0xff);
4424 }
4425
4426 static void
4427 bwn_wme_init(struct bwn_mac *mac)
4428 {
4429
4430         bwn_wme_load(mac);
4431
4432         /* enable WME support. */
4433         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4434         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4435             BWN_IFSCTL_USE_EDCF);
4436 }
4437
4438 static void
4439 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4440 {
4441         struct bwn_softc *sc = mac->mac_sc;
4442         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4443         uint16_t delay; /* microsec */
4444
4445         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4446         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4447                 delay = 500;
4448         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4449                 delay = max(delay, (uint16_t)2400);
4450
4451         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4452 }
4453
4454 static void
4455 bwn_bt_enable(struct bwn_mac *mac)
4456 {
4457         struct bwn_softc *sc = mac->mac_sc;
4458         uint64_t hf;
4459
4460         if (bwn_bluetooth == 0)
4461                 return;
4462         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4463                 return;
4464         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4465                 return;
4466
4467         hf = bwn_hf_read(mac);
4468         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4469                 hf |= BWN_HF_BT_COEXISTALT;
4470         else
4471                 hf |= BWN_HF_BT_COEXIST;
4472         bwn_hf_write(mac, hf);
4473 }
4474
4475 static void
4476 bwn_set_macaddr(struct bwn_mac *mac)
4477 {
4478
4479         bwn_mac_write_bssid(mac);
4480         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4481 }
4482
4483 static void
4484 bwn_clear_keys(struct bwn_mac *mac)
4485 {
4486         int i;
4487
4488         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4489                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4490                     ("%s:%d: fail", __func__, __LINE__));
4491
4492                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4493                     NULL, BWN_SEC_KEYSIZE, NULL);
4494                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4495                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4496                             NULL, BWN_SEC_KEYSIZE, NULL);
4497                 }
4498                 mac->mac_key[i].keyconf = NULL;
4499         }
4500 }
4501
4502 static void
4503 bwn_crypt_init(struct bwn_mac *mac)
4504 {
4505         struct bwn_softc *sc = mac->mac_sc;
4506
4507         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4508         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4509             ("%s:%d: fail", __func__, __LINE__));
4510         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4511         mac->mac_ktp *= 2;
4512         if (siba_get_revid(sc->sc_dev) >= 5)
4513                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4514         bwn_clear_keys(mac);
4515 }
4516
4517 static void
4518 bwn_chip_exit(struct bwn_mac *mac)
4519 {
4520         struct bwn_softc *sc = mac->mac_sc;
4521
4522         bwn_phy_exit(mac);
4523         siba_gpio_set(sc->sc_dev, 0);
4524 }
4525
4526 static int
4527 bwn_fw_fillinfo(struct bwn_mac *mac)
4528 {
4529         int error;
4530
4531         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4532         if (error == 0)
4533                 return (0);
4534         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4535         if (error == 0)
4536                 return (0);
4537         return (error);
4538 }
4539
4540 static int
4541 bwn_gpio_init(struct bwn_mac *mac)
4542 {
4543         struct bwn_softc *sc = mac->mac_sc;
4544         uint32_t mask = 0x1f, set = 0xf, value;
4545
4546         BWN_WRITE_4(mac, BWN_MACCTL,
4547             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4548         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4549             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4550
4551         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4552                 mask |= 0x0060;
4553                 set |= 0x0060;
4554         }
4555         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4556                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4557                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4558                 mask |= 0x0200;
4559                 set |= 0x0200;
4560         }
4561         if (siba_get_revid(sc->sc_dev) >= 2)
4562                 mask |= 0x0010;
4563
4564         value = siba_gpio_get(sc->sc_dev);
4565         if (value == -1)
4566                 return (0);
4567         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4568
4569         return (0);
4570 }
4571
4572 static int
4573 bwn_fw_loadinitvals(struct bwn_mac *mac)
4574 {
4575 #define GETFWOFFSET(fwp, offset)                                \
4576         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4577         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4578         const struct bwn_fwhdr *hdr;
4579         struct bwn_fw *fw = &mac->mac_fw;
4580         int error;
4581
4582         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4583         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4584             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4585         if (error)
4586                 return (error);
4587         if (fw->initvals_band.fw) {
4588                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4589                 error = bwn_fwinitvals_write(mac,
4590                     GETFWOFFSET(fw->initvals_band, hdr_len),
4591                     be32toh(hdr->size),
4592                     fw->initvals_band.fw->datasize - hdr_len);
4593         }
4594         return (error);
4595 #undef GETFWOFFSET
4596 }
4597
4598 static int
4599 bwn_phy_init(struct bwn_mac *mac)
4600 {
4601         struct bwn_softc *sc = mac->mac_sc;
4602         int error;
4603
4604         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4605         mac->mac_phy.rf_onoff(mac, 1);
4606         error = mac->mac_phy.init(mac);
4607         if (error) {
4608                 device_printf(sc->sc_dev, "PHY init failed\n");
4609                 goto fail0;
4610         }
4611         error = bwn_switch_channel(mac,
4612             mac->mac_phy.get_default_chan(mac));
4613         if (error) {
4614                 device_printf(sc->sc_dev,
4615                     "failed to switch default channel\n");
4616                 goto fail1;
4617         }
4618         return (0);
4619 fail1:
4620         if (mac->mac_phy.exit)
4621                 mac->mac_phy.exit(mac);
4622 fail0:
4623         mac->mac_phy.rf_onoff(mac, 0);
4624
4625         return (error);
4626 }
4627
4628 static void
4629 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4630 {
4631         uint16_t ant;
4632         uint16_t tmp;
4633
4634         ant = bwn_ant2phy(antenna);
4635
4636         /* For ACK/CTS */
4637         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4638         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4639         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4640         /* For Probe Resposes */
4641         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4642         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4643         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4644 }
4645
4646 static void
4647 bwn_set_opmode(struct bwn_mac *mac)
4648 {
4649         struct bwn_softc *sc = mac->mac_sc;
4650         struct ifnet *ifp = sc->sc_ifp;
4651         struct ieee80211com *ic = ifp->if_l2com;
4652         uint32_t ctl;
4653         uint16_t cfp_pretbtt;
4654
4655         ctl = BWN_READ_4(mac, BWN_MACCTL);
4656         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4657             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4658             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4659         ctl |= BWN_MACCTL_STA;
4660
4661         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4662             ic->ic_opmode == IEEE80211_M_MBSS)
4663                 ctl |= BWN_MACCTL_HOSTAP;
4664         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4665                 ctl &= ~BWN_MACCTL_STA;
4666         ctl |= sc->sc_filters;
4667
4668         if (siba_get_revid(sc->sc_dev) <= 4)
4669                 ctl |= BWN_MACCTL_PROMISC;
4670
4671         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4672
4673         cfp_pretbtt = 2;
4674         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4675                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4676                     siba_get_chiprev(sc->sc_dev) == 3)
4677                         cfp_pretbtt = 100;
4678                 else
4679                         cfp_pretbtt = 50;
4680         }
4681         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4682 }
4683
4684 static int
4685 bwn_dma_gettype(struct bwn_mac *mac)
4686 {
4687         uint32_t tmp;
4688         uint16_t base;
4689
4690         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4691         if (tmp & SIBA_TGSHIGH_DMA64)
4692                 return (BWN_DMA_64BIT);
4693         base = bwn_dma_base(0, 0);
4694         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4695         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4696         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4697                 return (BWN_DMA_32BIT);
4698
4699         return (BWN_DMA_30BIT);
4700 }
4701
4702 static void
4703 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4704 {
4705         if (!error) {
4706                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4707                 *((bus_addr_t *)arg) = seg->ds_addr;
4708         }
4709 }
4710
4711 static void
4712 bwn_phy_g_init_sub(struct bwn_mac *mac)
4713 {
4714         struct bwn_phy *phy = &mac->mac_phy;
4715         struct bwn_phy_g *pg = &phy->phy_g;
4716         struct bwn_softc *sc = mac->mac_sc;
4717         uint16_t i, tmp;
4718
4719         if (phy->rev == 1)
4720                 bwn_phy_init_b5(mac);
4721         else
4722                 bwn_phy_init_b6(mac);
4723
4724         if (phy->rev >= 2 || phy->gmode)
4725                 bwn_phy_init_a(mac);
4726
4727         if (phy->rev >= 2) {
4728                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4729                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4730         }
4731         if (phy->rev == 2) {
4732                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4733                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4734         }
4735         if (phy->rev > 5) {
4736                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4737                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4738         }
4739         if (phy->gmode || phy->rev >= 2) {
4740                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4741                 tmp &= BWN_PHYVER_VERSION;
4742                 if (tmp == 3 || tmp == 5) {
4743                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4744                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4745                 }
4746                 if (tmp == 5) {
4747                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4748                             0x1f00);
4749                 }
4750         }
4751         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4752                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4753         if (phy->rf_rev == 8) {
4754                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4755                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4756         }
4757         if (BWN_HAS_LOOPBACK(phy))
4758                 bwn_loopback_calcgain(mac);
4759
4760         if (phy->rf_rev != 8) {
4761                 if (pg->pg_initval == 0xffff)
4762                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4763                 else
4764                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4765         }
4766         bwn_lo_g_init(mac);
4767         if (BWN_HAS_TXMAG(phy)) {
4768                 BWN_RF_WRITE(mac, 0x52,
4769                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4770                     | pg->pg_loctl.tx_bias |
4771                     pg->pg_loctl.tx_magn);
4772         } else {
4773                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4774         }
4775         if (phy->rev >= 6) {
4776                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4777                     (pg->pg_loctl.tx_bias << 12));
4778         }
4779         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4780                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4781         else
4782                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4783         if (phy->rev < 2)
4784                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4785         else
4786                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4787         if (phy->gmode || phy->rev >= 2) {
4788                 bwn_lo_g_adjust(mac);
4789                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4790         }
4791
4792         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4793                 for (i = 0; i < 64; i++) {
4794                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4795                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4796                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4797                             -32), 31));
4798                 }
4799                 bwn_nrssi_threshold(mac);
4800         } else if (phy->gmode || phy->rev >= 2) {
4801                 if (pg->pg_nrssi[0] == -1000) {
4802                         KASSERT(pg->pg_nrssi[1] == -1000,
4803                             ("%s:%d: fail", __func__, __LINE__));
4804                         bwn_nrssi_slope_11g(mac);
4805                 } else
4806                         bwn_nrssi_threshold(mac);
4807         }
4808         if (phy->rf_rev == 8)
4809                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4810         bwn_phy_hwpctl_init(mac);
4811         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4812              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4813                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4814                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4815         }
4816 }
4817
4818 static uint8_t
4819 bwn_has_hwpctl(struct bwn_mac *mac)
4820 {
4821
4822         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4823                 return (0);
4824         return (mac->mac_phy.use_hwpctl(mac));
4825 }
4826
4827 static void
4828 bwn_phy_init_b5(struct bwn_mac *mac)
4829 {
4830         struct bwn_phy *phy = &mac->mac_phy;
4831         struct bwn_phy_g *pg = &phy->phy_g;
4832         struct bwn_softc *sc = mac->mac_sc;
4833         uint16_t offset, value;
4834         uint8_t old_channel;
4835
4836         if (phy->analog == 1)
4837                 BWN_RF_SET(mac, 0x007a, 0x0050);
4838         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4839             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4840                 value = 0x2120;
4841                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4842                         BWN_PHY_WRITE(mac, offset, value);
4843                         value += 0x202;
4844                 }
4845         }
4846         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4847         if (phy->rf_ver == 0x2050)
4848                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4849
4850         if (phy->gmode || phy->rev >= 2) {
4851                 if (phy->rf_ver == 0x2050) {
4852                         BWN_RF_SET(mac, 0x007a, 0x0020);
4853                         BWN_RF_SET(mac, 0x0051, 0x0004);
4854                 }
4855                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4856
4857                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4858                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4859
4860                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4861
4862                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4863                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4864                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4865         }
4866
4867         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4868                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4869
4870         if (phy->analog == 1) {
4871                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4872                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4873                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4874                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4875                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4876         } else
4877                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4878         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4879         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4880
4881         if (phy->analog == 1)
4882                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4883         else
4884                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4885
4886         if (phy->analog == 0)
4887                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4888
4889         old_channel = phy->chan;
4890         bwn_phy_g_switch_chan(mac, 7, 0);
4891
4892         if (phy->rf_ver != 0x2050) {
4893                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4894                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4895         }
4896
4897         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4898         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4899
4900         if (phy->rf_ver == 0x2050) {
4901                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4902                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4903         }
4904
4905         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4906         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4907         BWN_RF_SET(mac, 0x007a, 0x0007);
4908
4909         bwn_phy_g_switch_chan(mac, old_channel, 0);
4910         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4911         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4912         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4913
4914         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4915             pg->pg_txctl);
4916
4917         if (phy->rf_ver == 0x2050)
4918                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4919
4920         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4921 }
4922
4923 static void
4924 bwn_loopback_calcgain(struct bwn_mac *mac)
4925 {
4926         struct bwn_phy *phy = &mac->mac_phy;
4927         struct bwn_phy_g *pg = &phy->phy_g;
4928         struct bwn_softc *sc = mac->mac_sc;
4929         uint16_t backup_phy[16] = { 0 };
4930         uint16_t backup_radio[3];
4931         uint16_t backup_bband;
4932         uint16_t i, j, loop_i_max;
4933         uint16_t trsw_rx;
4934         uint16_t loop1_outer_done, loop1_inner_done;
4935
4936         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4937         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4938         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4939         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4940         if (phy->rev != 1) {
4941                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4942                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4943         }
4944         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4945         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4946         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4947         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4948         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4949         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4950         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4951         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4952         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4953         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4954         backup_bband = pg->pg_bbatt.att;
4955         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4956         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4957         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4958
4959         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4960         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4961         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4962         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4963         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4964         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4965         if (phy->rev != 1) {
4966                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4967                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4968                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4969                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4970         }
4971         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4972         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4973         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4974         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4975
4976         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4977         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4978         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4979
4980         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4981         if (phy->rev != 1) {
4982                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4983                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4984         }
4985         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4986
4987         if (phy->rf_rev == 8)
4988                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4989         else {
4990                 BWN_RF_WRITE(mac, 0x52, 0);
4991                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4992         }
4993         bwn_phy_g_set_bbatt(mac, 11);
4994
4995         if (phy->rev >= 3)
4996                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4997         else
4998                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4999         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5000
5001         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5002         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5003
5004         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5005         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5006
5007         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5008                 if (phy->rev >= 7) {
5009                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5010                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5011                 }
5012         }
5013         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5014
5015         j = 0;
5016         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5017         for (i = 0; i < loop_i_max; i++) {
5018                 for (j = 0; j < 16; j++) {
5019                         BWN_RF_WRITE(mac, 0x43, i);
5020                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5021                             (j << 8));
5022                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5023                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5024                         DELAY(20);
5025                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5026                                 goto done0;
5027                 }
5028         }
5029 done0:
5030         loop1_outer_done = i;
5031         loop1_inner_done = j;
5032         if (j >= 8) {
5033                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5034                 trsw_rx = 0x1b;
5035                 for (j = j - 8; j < 16; j++) {
5036                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5037                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5038                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5039                         DELAY(20);
5040                         trsw_rx -= 3;
5041                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5042                                 goto done1;
5043                 }
5044         } else
5045                 trsw_rx = 0x18;
5046 done1:
5047
5048         if (phy->rev != 1) {
5049                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5050                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5051         }
5052         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5053         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5054         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5055         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5056         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5057         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5058         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5059         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5060         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5061
5062         bwn_phy_g_set_bbatt(mac, backup_bband);
5063
5064         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5065         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5066         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5067
5068         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5069         DELAY(10);
5070         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5071         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5072         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5073         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5074
5075         pg->pg_max_lb_gain =
5076             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5077         pg->pg_trsw_rx_gain = trsw_rx * 2;
5078 }
5079
5080 static uint16_t
5081 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5082 {
5083         struct bwn_phy *phy = &mac->mac_phy;
5084         uint32_t tmp1 = 0, tmp2 = 0;
5085         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5086             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5087             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5088         static const uint8_t rcc_table[] = {
5089                 0x02, 0x03, 0x01, 0x0f,
5090                 0x06, 0x07, 0x05, 0x0f,
5091                 0x0a, 0x0b, 0x09, 0x0f,
5092                 0x0e, 0x0f, 0x0d, 0x0f,
5093         };
5094
5095         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5096             rfoverval = rfover = cck3 = 0;
5097         radio0 = BWN_RF_READ(mac, 0x43);
5098         radio1 = BWN_RF_READ(mac, 0x51);
5099         radio2 = BWN_RF_READ(mac, 0x52);
5100         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5101         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5102         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5103         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5104
5105         if (phy->type == BWN_PHYTYPE_B) {
5106                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5107                 reg0 = BWN_READ_2(mac, 0x3ec);
5108
5109                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5110                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5111         } else if (phy->gmode || phy->rev >= 2) {
5112                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5113                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5114                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5115                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5116                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5117                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5118
5119                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5120                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5121                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5122                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5123                 if (BWN_HAS_LOOPBACK(phy)) {
5124                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5125                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5126                         if (phy->rev >= 3)
5127                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5128                         else
5129                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5130                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5131                 }
5132
5133                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5134                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5135                         BWN_LPD(0, 1, 1)));
5136                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5137                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5138         }
5139         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5140
5141         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5142         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5143         reg1 = BWN_READ_2(mac, 0x3e6);
5144         reg2 = BWN_READ_2(mac, 0x3f4);
5145
5146         if (phy->analog == 0)
5147                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5148         else {
5149                 if (phy->analog >= 2)
5150                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5151                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5152                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5153         }
5154
5155         reg = BWN_RF_READ(mac, 0x60);
5156         index = (reg & 0x001e) >> 1;
5157         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5158
5159         if (phy->type == BWN_PHYTYPE_B)
5160                 BWN_RF_WRITE(mac, 0x78, 0x26);
5161         if (phy->gmode || phy->rev >= 2) {
5162                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5163                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5164                         BWN_LPD(0, 1, 1)));
5165         }
5166         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5167         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5168         if (phy->gmode || phy->rev >= 2) {
5169                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5170                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5171                         BWN_LPD(0, 0, 1)));
5172         }
5173         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5174         BWN_RF_SET(mac, 0x51, 0x0004);
5175         if (phy->rf_rev == 8)
5176                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5177         else {
5178                 BWN_RF_WRITE(mac, 0x52, 0);
5179                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5180         }
5181         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5182
5183         for (i = 0; i < 16; i++) {
5184                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5185                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5186                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5187                 if (phy->gmode || phy->rev >= 2) {
5188                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5189                             bwn_rf_2050_rfoverval(mac,
5190                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5191                 }
5192                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5193                 DELAY(10);
5194                 if (phy->gmode || phy->rev >= 2) {
5195                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5196                             bwn_rf_2050_rfoverval(mac,
5197                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5198                 }
5199                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5200                 DELAY(10);
5201                 if (phy->gmode || phy->rev >= 2) {
5202                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5203                             bwn_rf_2050_rfoverval(mac,
5204                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5205                 }
5206                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5207                 DELAY(20);
5208                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5209                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5210                 if (phy->gmode || phy->rev >= 2) {
5211                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5212                             bwn_rf_2050_rfoverval(mac,
5213                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5214                 }
5215                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5216         }
5217         DELAY(10);
5218
5219         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5220         tmp1++;
5221         tmp1 >>= 9;
5222
5223         for (i = 0; i < 16; i++) {
5224                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5225                 BWN_RF_WRITE(mac, 0x78, radio78);
5226                 DELAY(10);
5227                 for (j = 0; j < 16; j++) {
5228                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5229                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5230                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5231                         if (phy->gmode || phy->rev >= 2) {
5232                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5233                                     bwn_rf_2050_rfoverval(mac,
5234                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5235                         }
5236                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5237                         DELAY(10);
5238                         if (phy->gmode || phy->rev >= 2) {
5239                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5240                                     bwn_rf_2050_rfoverval(mac,
5241                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5242                         }
5243                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5244                         DELAY(10);
5245                         if (phy->gmode || phy->rev >= 2) {
5246                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5247                                     bwn_rf_2050_rfoverval(mac,
5248                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5249                         }
5250                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5251                         DELAY(10);
5252                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5253                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5254                         if (phy->gmode || phy->rev >= 2) {
5255                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5256                                     bwn_rf_2050_rfoverval(mac,
5257                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5258                         }
5259                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5260                 }
5261                 tmp2++;
5262                 tmp2 >>= 8;
5263                 if (tmp1 < tmp2)
5264                         break;
5265         }
5266
5267         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5268         BWN_RF_WRITE(mac, 0x51, radio1);
5269         BWN_RF_WRITE(mac, 0x52, radio2);
5270         BWN_RF_WRITE(mac, 0x43, radio0);
5271         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5272         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5273         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5274         BWN_WRITE_2(mac, 0x3e6, reg1);
5275         if (phy->analog != 0)
5276                 BWN_WRITE_2(mac, 0x3f4, reg2);
5277         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5278         bwn_spu_workaround(mac, phy->chan);
5279         if (phy->type == BWN_PHYTYPE_B) {
5280                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5281                 BWN_WRITE_2(mac, 0x3ec, reg0);
5282         } else if (phy->gmode) {
5283                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5284                             BWN_READ_2(mac, BWN_PHY_RADIO)
5285                             & 0x7fff);
5286                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5287                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5288                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5289                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5290                               analogoverval);
5291                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5292                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5293                 if (BWN_HAS_LOOPBACK(phy)) {
5294                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5295                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5296                 }
5297         }
5298
5299         return ((i > 15) ? radio78 : rcc);
5300 }
5301
5302 static void
5303 bwn_phy_init_b6(struct bwn_mac *mac)
5304 {
5305         struct bwn_phy *phy = &mac->mac_phy;
5306         struct bwn_phy_g *pg = &phy->phy_g;
5307         struct bwn_softc *sc = mac->mac_sc;
5308         uint16_t offset, val;
5309         uint8_t old_channel;
5310
5311         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5312             ("%s:%d: fail", __func__, __LINE__));
5313
5314         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5315         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5316         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5317                 BWN_RF_WRITE(mac, 0x51, 0x37);
5318                 BWN_RF_WRITE(mac, 0x52, 0x70);
5319                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5320                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5321                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5322                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5323                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5324                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5325                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5326                 bwn_hf_write(mac,
5327                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5328         }
5329         if (phy->rf_rev == 8) {
5330                 BWN_RF_WRITE(mac, 0x51, 0);
5331                 BWN_RF_WRITE(mac, 0x52, 0x40);
5332                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5333                 BWN_RF_WRITE(mac, 0x54, 0x98);
5334                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5335                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5336                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5337                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5338                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5339                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5340                 } else {
5341                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5342                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5343                 }
5344                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5345                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5346                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5347                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5348         }
5349         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5350                 BWN_PHY_WRITE(mac, offset, val);
5351                 val -= 0x0202;
5352         }
5353         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5354                 BWN_PHY_WRITE(mac, offset, val);
5355                 val -= 0x0202;
5356         }
5357         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5358                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5359                 val += 0x0202;
5360         }
5361         if (phy->type == BWN_PHYTYPE_G) {
5362                 BWN_RF_SET(mac, 0x007a, 0x0020);
5363                 BWN_RF_SET(mac, 0x0051, 0x0004);
5364                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5365                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5366                 BWN_PHY_WRITE(mac, 0x5b, 0);
5367                 BWN_PHY_WRITE(mac, 0x5c, 0);
5368         }
5369
5370         old_channel = phy->chan;
5371         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5372
5373         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5374         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5375         DELAY(40);
5376         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5377                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5378                 BWN_RF_WRITE(mac, 0x50, 0x20);
5379         }
5380         if (phy->rf_rev <= 2) {
5381                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5382                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5383                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5384                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5385         }
5386         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5387
5388         bwn_phy_g_switch_chan(mac, old_channel, 0);
5389
5390         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5391         if (phy->rf_rev >= 6)
5392                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5393         else
5394                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5395         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5396         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5397             pg->pg_txctl);
5398         if (phy->rf_rev <= 5)
5399                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5400         if (phy->rf_rev <= 2)
5401                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5402
5403         if (phy->analog == 4) {
5404                 BWN_WRITE_2(mac, 0x3e4, 9);
5405                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5406         } else
5407                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5408         if (phy->type == BWN_PHYTYPE_B)
5409                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5410         else if (phy->type == BWN_PHYTYPE_G)
5411                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5412 }
5413
5414 static void
5415 bwn_phy_init_a(struct bwn_mac *mac)
5416 {
5417         struct bwn_phy *phy = &mac->mac_phy;
5418         struct bwn_softc *sc = mac->mac_sc;
5419
5420         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5421             ("%s:%d: fail", __func__, __LINE__));
5422
5423         if (phy->rev >= 6) {
5424                 if (phy->type == BWN_PHYTYPE_A)
5425                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5426                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5427                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5428                 else
5429                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5430         }
5431
5432         bwn_wa_init(mac);
5433
5434         if (phy->type == BWN_PHYTYPE_G &&
5435             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5436                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5437 }
5438
5439 static void
5440 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5441 {
5442         int i;
5443
5444         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5445                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5446 }
5447
5448 static void
5449 bwn_wa_agc(struct bwn_mac *mac)
5450 {
5451         struct bwn_phy *phy = &mac->mac_phy;
5452
5453         if (phy->rev == 1) {
5454                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5455                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5456                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5457                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5458                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5460                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5461                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5462                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5463         } else {
5464                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5465                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5466                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5467                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5468         }
5469
5470         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5471             0x5700);
5472         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5473         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5474         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5475         BWN_RF_SET(mac, 0x7a, 0x0008);
5476         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5477         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5478         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5479         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5480         if (phy->rev == 1)
5481                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5482         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5483         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5484         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5485         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5486         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5487         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5488         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5491         if (phy->rev == 1) {
5492                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5493                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5494         } else {
5495                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5496                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5497                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5498                 if (phy->rev >= 6) {
5499                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5500                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5501                             (uint16_t)~0xf000, 0x3000);
5502                 }
5503         }
5504         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5505         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5506         if (phy->rev == 1) {
5507                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5508                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5509                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5510                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5511                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5512                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5513                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5514                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5515         } else {
5516                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5517                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5518                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5519                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5520         }
5521         if (phy->rev >= 6) {
5522                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5523                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5524         }
5525         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5526 }
5527
5528 static void
5529 bwn_wa_grev1(struct bwn_mac *mac)
5530 {
5531         struct bwn_phy *phy = &mac->mac_phy;
5532         int i;
5533         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5534         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5535         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5536
5537         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5538
5539         /* init CRSTHRES and ANTDWELL */
5540         if (phy->rev == 1) {
5541                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5542         } else if (phy->rev == 2) {
5543                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5544                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5545                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5546         } else {
5547                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5548                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5549                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5550                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5551         }
5552         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5553         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5554         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5555
5556         /* XXX support PHY-A??? */
5557         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5558                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5559                     bwn_tab_finefreqg[i]);
5560
5561         /* XXX support PHY-A??? */
5562         if (phy->rev == 1)
5563                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5564                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5565                             bwn_tab_noise_g1[i]);
5566         else
5567                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5568                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5569                             bwn_tab_noise_g2[i]);
5570
5571
5572         for (i = 0; i < N(bwn_tab_rotor); i++)
5573                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5574                     bwn_tab_rotor[i]);
5575
5576         /* XXX support PHY-A??? */
5577         if (phy->rev >= 6) {
5578                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5579                     BWN_PHY_ENCORE_EN)
5580                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5581                 else
5582                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5583         } else
5584                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5585
5586         for (i = 0; i < N(bwn_tab_retard); i++)
5587                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5588                     bwn_tab_retard[i]);
5589
5590         if (phy->rev == 1) {
5591                 for (i = 0; i < 16; i++)
5592                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5593                             i, 0x0020);
5594         } else {
5595                 for (i = 0; i < 32; i++)
5596                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5597         }
5598
5599         bwn_wa_agc(mac);
5600 }
5601
5602 static void
5603 bwn_wa_grev26789(struct bwn_mac *mac)
5604 {
5605         struct bwn_phy *phy = &mac->mac_phy;
5606         int i;
5607         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5608         uint16_t ofdmrev;
5609
5610         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5611
5612         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5613
5614         /* init CRSTHRES and ANTDWELL */
5615         if (phy->rev == 1)
5616                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5617         else if (phy->rev == 2) {
5618                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5619                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5620                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5621         } else {
5622                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5623                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5624                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5625                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5626         }
5627
5628         for (i = 0; i < 64; i++)
5629                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5630
5631         /* XXX support PHY-A??? */
5632         if (phy->rev == 1)
5633                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5634                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5635                             bwn_tab_noise_g1[i]);
5636         else
5637                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5638                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5639                             bwn_tab_noise_g2[i]);
5640
5641         /* XXX support PHY-A??? */
5642         if (phy->rev >= 6) {
5643                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5644                     BWN_PHY_ENCORE_EN)
5645                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5646                 else
5647                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5648         } else
5649                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5650
5651         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5652                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5653                     bwn_tab_sigmasqr2[i]);
5654
5655         if (phy->rev == 1) {
5656                 for (i = 0; i < 16; i++)
5657                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5658                             0x0020);
5659         } else {
5660                 for (i = 0; i < 32; i++)
5661                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5662         }
5663
5664         bwn_wa_agc(mac);
5665
5666         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5667         if (ofdmrev > 2) {
5668                 if (phy->type == BWN_PHYTYPE_A)
5669                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5670                 else
5671                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5672         } else {
5673                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5674                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5675                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5676         }
5677
5678         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5679         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5680 }
5681
5682 static void
5683 bwn_wa_init(struct bwn_mac *mac)
5684 {
5685         struct bwn_phy *phy = &mac->mac_phy;
5686         struct bwn_softc *sc = mac->mac_sc;
5687
5688         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5689
5690         switch (phy->rev) {
5691         case 1:
5692                 bwn_wa_grev1(mac);
5693                 break;
5694         case 2:
5695         case 6:
5696         case 7:
5697         case 8:
5698         case 9:
5699                 bwn_wa_grev26789(mac);
5700                 break;
5701         default:
5702                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5703         }
5704
5705         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5706             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5707             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5708                 if (phy->rev < 2) {
5709                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5710                             0x0002);
5711                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5712                             0x0001);
5713                 } else {
5714                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5715                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5716                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5717                              BWN_BFL_EXTLNA) &&
5718                             (phy->rev >= 7)) {
5719                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5720                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5721                                     0x0020, 0x0001);
5722                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5723                                     0x0021, 0x0001);
5724                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5725                                     0x0022, 0x0001);
5726                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5727                                     0x0023, 0x0000);
5728                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5729                                     0x0000, 0x0000);
5730                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5731                                     0x0003, 0x0002);
5732                         }
5733                 }
5734         }
5735         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5736                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5737                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5738         }
5739
5740         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5741         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5742 }
5743
5744 static void
5745 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5746     uint16_t value)
5747 {
5748         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5749         uint16_t addr;
5750
5751         addr = table + offset;
5752         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5753             (addr - 1 != pg->pg_ofdmtab_addr)) {
5754                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5755                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5756         }
5757         pg->pg_ofdmtab_addr = addr;
5758         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5759 }
5760
5761 static void
5762 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5763     uint32_t value)
5764 {
5765         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5766         uint16_t addr;
5767
5768         addr = table + offset;
5769         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5770             (addr - 1 != pg->pg_ofdmtab_addr)) {
5771                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5772                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5773         }
5774         pg->pg_ofdmtab_addr = addr;
5775
5776         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5777         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5778 }
5779
5780 static void
5781 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5782     uint16_t value)
5783 {
5784
5785         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5786         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5787 }
5788
5789 static void
5790 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5791 {
5792         struct bwn_phy *phy = &mac->mac_phy;
5793         struct bwn_softc *sc = mac->mac_sc;
5794         unsigned int i, max_loop;
5795         uint16_t value;
5796         uint32_t buffer[5] = {
5797                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5798         };
5799
5800         if (ofdm) {
5801                 max_loop = 0x1e;
5802                 buffer[0] = 0x000201cc;
5803         } else {
5804                 max_loop = 0xfa;
5805                 buffer[0] = 0x000b846e;
5806         }
5807
5808         BWN_ASSERT_LOCKED(mac->mac_sc);
5809
5810         for (i = 0; i < 5; i++)
5811                 bwn_ram_write(mac, i * 4, buffer[i]);
5812
5813         BWN_WRITE_2(mac, 0x0568, 0x0000);
5814         BWN_WRITE_2(mac, 0x07c0,
5815             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5816         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5817         BWN_WRITE_2(mac, 0x050c, value);
5818         if (phy->type == BWN_PHYTYPE_LP)
5819                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5820         BWN_WRITE_2(mac, 0x0508, 0x0000);
5821         BWN_WRITE_2(mac, 0x050a, 0x0000);
5822         BWN_WRITE_2(mac, 0x054c, 0x0000);
5823         BWN_WRITE_2(mac, 0x056a, 0x0014);
5824         BWN_WRITE_2(mac, 0x0568, 0x0826);
5825         BWN_WRITE_2(mac, 0x0500, 0x0000);
5826         if (phy->type == BWN_PHYTYPE_LP)
5827                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5828         else
5829                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5830
5831         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5832                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5833         for (i = 0x00; i < max_loop; i++) {
5834                 value = BWN_READ_2(mac, 0x050e);
5835                 if (value & 0x0080)
5836                         break;
5837                 DELAY(10);
5838         }
5839         for (i = 0x00; i < 0x0a; i++) {
5840                 value = BWN_READ_2(mac, 0x050e);
5841                 if (value & 0x0400)
5842                         break;
5843                 DELAY(10);
5844         }
5845         for (i = 0x00; i < 0x19; i++) {
5846                 value = BWN_READ_2(mac, 0x0690);
5847                 if (!(value & 0x0100))
5848                         break;
5849                 DELAY(10);
5850         }
5851         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5852                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5853 }
5854
5855 static void
5856 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5857 {
5858         uint32_t macctl;
5859
5860         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5861
5862         macctl = BWN_READ_4(mac, BWN_MACCTL);
5863         if (macctl & BWN_MACCTL_BIGENDIAN)
5864                 printf("TODO: need swap\n");
5865
5866         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5867         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5868         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5869 }
5870
5871 static void
5872 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5873 {
5874         uint16_t value;
5875
5876         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5877             ("%s:%d: fail", __func__, __LINE__));
5878
5879         value = (uint8_t) (ctl->q);
5880         value |= ((uint8_t) (ctl->i)) << 8;
5881         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5882 }
5883
5884 static uint16_t
5885 bwn_lo_calcfeed(struct bwn_mac *mac,
5886     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5887 {
5888         struct bwn_phy *phy = &mac->mac_phy;
5889         struct bwn_softc *sc = mac->mac_sc;
5890         uint16_t rfover;
5891         uint16_t feedthrough;
5892
5893         if (phy->gmode) {
5894                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5895                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5896
5897                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5898                     ("%s:%d: fail", __func__, __LINE__));
5899                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5900                     ("%s:%d: fail", __func__, __LINE__));
5901
5902                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5903
5904                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5905                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5906                     phy->rev > 6)
5907                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5908
5909                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5910                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5911                 DELAY(10);
5912                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5913                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5914                 DELAY(10);
5915                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5916                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5917                 DELAY(10);
5918                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5919         } else {
5920                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5921                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5922                 DELAY(10);
5923                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5924                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5925                 DELAY(10);
5926                 pga |= BWN_PHY_PGACTL_LPF;
5927                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5928         }
5929         DELAY(21);
5930         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5931
5932         return (feedthrough);
5933 }
5934
5935 static uint16_t
5936 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5937     uint16_t *value, uint16_t *pad_mix_gain)
5938 {
5939         struct bwn_phy *phy = &mac->mac_phy;
5940         uint16_t reg, v, padmix;
5941
5942         if (phy->type == BWN_PHYTYPE_B) {
5943                 v = 0x30;
5944                 if (phy->rf_rev <= 5) {
5945                         reg = 0x43;
5946                         padmix = 0;
5947                 } else {
5948                         reg = 0x52;
5949                         padmix = 5;
5950                 }
5951         } else {
5952                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5953                         reg = 0x43;
5954                         v = 0x10;
5955                         padmix = 2;
5956                 } else {
5957                         reg = 0x52;
5958                         v = 0x30;
5959                         padmix = 5;
5960                 }
5961         }
5962         if (value)
5963                 *value = v;
5964         if (pad_mix_gain)
5965                 *pad_mix_gain = padmix;
5966
5967         return (reg);
5968 }
5969
5970 static void
5971 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5972 {
5973         struct bwn_phy *phy = &mac->mac_phy;
5974         struct bwn_phy_g *pg = &phy->phy_g;
5975         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5976         uint16_t reg, mask;
5977         uint16_t trsw_rx, pga;
5978         uint16_t rf_pctl_reg;
5979
5980         static const uint8_t tx_bias_values[] = {
5981                 0x09, 0x08, 0x0a, 0x01, 0x00,
5982                 0x02, 0x05, 0x04, 0x06,
5983         };
5984         static const uint8_t tx_magn_values[] = {
5985                 0x70, 0x40,
5986         };
5987
5988         if (!BWN_HAS_LOOPBACK(phy)) {
5989                 rf_pctl_reg = 6;
5990                 trsw_rx = 2;
5991                 pga = 0;
5992         } else {
5993                 int lb_gain;
5994
5995                 trsw_rx = 0;
5996                 lb_gain = pg->pg_max_lb_gain / 2;
5997                 if (lb_gain > 10) {
5998                         rf_pctl_reg = 0;
5999                         pga = abs(10 - lb_gain) / 6;
6000                         pga = MIN(MAX(pga, 0), 15);
6001                 } else {
6002                         int cmp_val;
6003                         int tmp;
6004
6005                         pga = 0;
6006                         cmp_val = 0x24;
6007                         if ((phy->rev >= 2) &&
6008                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6009                                 cmp_val = 0x3c;
6010                         tmp = lb_gain;
6011                         if ((10 - lb_gain) < cmp_val)
6012                                 tmp = (10 - lb_gain);
6013                         if (tmp < 0)
6014                                 tmp += 6;
6015                         else
6016                                 tmp += 3;
6017                         cmp_val /= 4;
6018                         tmp /= 4;
6019                         if (tmp >= cmp_val)
6020                                 rf_pctl_reg = cmp_val;
6021                         else
6022                                 rf_pctl_reg = tmp;
6023                 }
6024         }
6025         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6026         bwn_phy_g_set_bbatt(mac, 2);
6027
6028         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6029         mask = ~mask;
6030         BWN_RF_MASK(mac, reg, mask);
6031
6032         if (BWN_HAS_TXMAG(phy)) {
6033                 int i, j;
6034                 int feedthrough;
6035                 int min_feedth = 0xffff;
6036                 uint8_t tx_magn, tx_bias;
6037
6038                 for (i = 0; i < N(tx_magn_values); i++) {
6039                         tx_magn = tx_magn_values[i];
6040                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6041                         for (j = 0; j < N(tx_bias_values); j++) {
6042                                 tx_bias = tx_bias_values[j];
6043                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6044                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6045                                     trsw_rx);
6046                                 if (feedthrough < min_feedth) {
6047                                         lo->tx_bias = tx_bias;
6048                                         lo->tx_magn = tx_magn;
6049                                         min_feedth = feedthrough;
6050                                 }
6051                                 if (lo->tx_bias == 0)
6052                                         break;
6053                         }
6054                         BWN_RF_WRITE(mac, 0x52,
6055                                           (BWN_RF_READ(mac, 0x52)
6056                                            & 0xff00) | lo->tx_bias | lo->
6057                                           tx_magn);
6058                 }
6059         } else {
6060                 lo->tx_magn = 0;
6061                 lo->tx_bias = 0;
6062                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6063         }
6064
6065         BWN_GETTIME(lo->txctl_measured_time);
6066 }
6067
6068 static void
6069 bwn_lo_get_powervector(struct bwn_mac *mac)
6070 {
6071         struct bwn_phy *phy = &mac->mac_phy;
6072         struct bwn_phy_g *pg = &phy->phy_g;
6073         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6074         int i;
6075         uint64_t tmp;
6076         uint64_t power_vector = 0;
6077
6078         for (i = 0; i < 8; i += 2) {
6079                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6080                 power_vector |= (tmp << (i * 8));
6081                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6082         }
6083         if (power_vector)
6084                 lo->power_vector = power_vector;
6085
6086         BWN_GETTIME(lo->pwr_vec_read_time);
6087 }
6088
6089 static void
6090 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6091     int use_trsw_rx)
6092 {
6093         struct bwn_phy *phy = &mac->mac_phy;
6094         struct bwn_phy_g *pg = &phy->phy_g;
6095         uint16_t tmp;
6096
6097         if (max_rx_gain < 0)
6098                 max_rx_gain = 0;
6099
6100         if (BWN_HAS_LOOPBACK(phy)) {
6101                 int trsw_rx = 0;
6102                 int trsw_rx_gain;
6103
6104                 if (use_trsw_rx) {
6105                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6106                         if (max_rx_gain >= trsw_rx_gain) {
6107                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6108                                 trsw_rx = 0x20;
6109                         }
6110                 } else
6111                         trsw_rx_gain = max_rx_gain;
6112                 if (trsw_rx_gain < 9) {
6113                         pg->pg_lna_lod_gain = 0;
6114                 } else {
6115                         pg->pg_lna_lod_gain = 1;
6116                         trsw_rx_gain -= 8;
6117                 }
6118                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6119                 pg->pg_pga_gain = trsw_rx_gain / 3;
6120                 if (pg->pg_pga_gain >= 5) {
6121                         pg->pg_pga_gain -= 5;
6122                         pg->pg_lna_gain = 2;
6123                 } else
6124                         pg->pg_lna_gain = 0;
6125         } else {
6126                 pg->pg_lna_gain = 0;
6127                 pg->pg_trsw_rx_gain = 0x20;
6128                 if (max_rx_gain >= 0x14) {
6129                         pg->pg_lna_lod_gain = 1;
6130                         pg->pg_pga_gain = 2;
6131                 } else if (max_rx_gain >= 0x12) {
6132                         pg->pg_lna_lod_gain = 1;
6133                         pg->pg_pga_gain = 1;
6134                 } else if (max_rx_gain >= 0xf) {
6135                         pg->pg_lna_lod_gain = 1;
6136                         pg->pg_pga_gain = 0;
6137                 } else {
6138                         pg->pg_lna_lod_gain = 0;
6139                         pg->pg_pga_gain = 0;
6140                 }
6141         }
6142
6143         tmp = BWN_RF_READ(mac, 0x7a);
6144         if (pg->pg_lna_lod_gain == 0)
6145                 tmp &= ~0x0008;
6146         else
6147                 tmp |= 0x0008;
6148         BWN_RF_WRITE(mac, 0x7a, tmp);
6149 }
6150
6151 static void
6152 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6153 {
6154         struct bwn_phy *phy = &mac->mac_phy;
6155         struct bwn_phy_g *pg = &phy->phy_g;
6156         struct bwn_softc *sc = mac->mac_sc;
6157         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6158         struct timespec ts;
6159         uint16_t tmp;
6160
6161         if (bwn_has_hwpctl(mac)) {
6162                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6163                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6164                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6165                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6166                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6167
6168                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6169                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6170                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6171                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6172         }
6173         if (phy->type == BWN_PHYTYPE_B &&
6174             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6175                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6176                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6177         }
6178         if (phy->rev >= 2) {
6179                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6180                 sav->phy_analogoverval =
6181                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6182                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6183                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6184                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6185                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6186                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6187
6188                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6189                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6190                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6191                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6192                 if (phy->type == BWN_PHYTYPE_G) {
6193                         if ((phy->rev >= 7) &&
6194                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6195                              BWN_BFL_EXTLNA)) {
6196                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6197                         } else {
6198                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6199                         }
6200                 } else {
6201                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6202                 }
6203                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6204         }
6205         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6206         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6207         sav->rf0 = BWN_RF_READ(mac, 0x43);
6208         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6209         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6210         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6211         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6212         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6213
6214         if (!BWN_HAS_TXMAG(phy)) {
6215                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6216                 sav->rf2 &= 0x00f0;
6217         }
6218         if (phy->type == BWN_PHYTYPE_B) {
6219                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6220                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6221                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6222                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6223         } else {
6224                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6225                             | 0x8000);
6226         }
6227         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6228                     & 0xf000);
6229
6230         tmp =
6231             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6232         BWN_PHY_WRITE(mac, tmp, 0x007f);
6233
6234         tmp = sav->phy_syncctl;
6235         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6236         tmp = sav->rf1;
6237         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6238
6239         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6240         if (phy->type == BWN_PHYTYPE_G ||
6241             (phy->type == BWN_PHYTYPE_B &&
6242              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6243                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6244         } else
6245                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6246         if (phy->rev >= 2)
6247                 bwn_dummy_transmission(mac, 0, 1);
6248         bwn_phy_g_switch_chan(mac, 6, 0);
6249         BWN_RF_READ(mac, 0x51);
6250         if (phy->type == BWN_PHYTYPE_G)
6251                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6252
6253         nanouptime(&ts);
6254         if (time_before(lo->txctl_measured_time,
6255             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6256                 bwn_lo_measure_txctl_values(mac);
6257
6258         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6259                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6260         else {
6261                 if (phy->type == BWN_PHYTYPE_B)
6262                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6263                 else
6264                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6265         }
6266 }
6267
6268 static void
6269 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6270 {
6271         struct bwn_phy *phy = &mac->mac_phy;
6272         struct bwn_phy_g *pg = &phy->phy_g;
6273         uint16_t tmp;
6274
6275         if (phy->rev >= 2) {
6276                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6277                 tmp = (pg->pg_pga_gain << 8);
6278                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6279                 DELAY(5);
6280                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6281                 DELAY(2);
6282                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6283         } else {
6284                 tmp = (pg->pg_pga_gain | 0xefa0);
6285                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6286         }
6287         if (phy->type == BWN_PHYTYPE_G) {
6288                 if (phy->rev >= 3)
6289                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6290                 else
6291                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6292                 if (phy->rev >= 2)
6293                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6294                 else
6295                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6296         }
6297         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6298         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6299         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6300         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6301         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6302         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6303         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6304         if (!BWN_HAS_TXMAG(phy)) {
6305                 tmp = sav->rf2;
6306                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6307         }
6308         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6309         if (phy->type == BWN_PHYTYPE_B &&
6310             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6311                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6312                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6313         }
6314         if (phy->rev >= 2) {
6315                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6316                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6317                               sav->phy_analogoverval);
6318                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6319                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6320                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6321                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6322                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6323         }
6324         if (bwn_has_hwpctl(mac)) {
6325                 tmp = (sav->phy_lomask & 0xbfff);
6326                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6327                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6328                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6329                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6330                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6331         }
6332         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6333 }
6334
6335 static int
6336 bwn_lo_probe_loctl(struct bwn_mac *mac,
6337     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6338 {
6339         struct bwn_phy *phy = &mac->mac_phy;
6340         struct bwn_phy_g *pg = &phy->phy_g;
6341         struct bwn_loctl orig, test;
6342         struct bwn_loctl prev = { -100, -100 };
6343         static const struct bwn_loctl modifiers[] = {
6344                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6345                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6346         };
6347         int begin, end, lower = 0, i;
6348         uint16_t feedth;
6349
6350         if (d->curstate == 0) {
6351                 begin = 1;
6352                 end = 8;
6353         } else if (d->curstate % 2 == 0) {
6354                 begin = d->curstate - 1;
6355                 end = d->curstate + 1;
6356         } else {
6357                 begin = d->curstate - 2;
6358                 end = d->curstate + 2;
6359         }
6360         if (begin < 1)
6361                 begin += 8;
6362         if (end > 8)
6363                 end -= 8;
6364
6365         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6366         i = begin;
6367         d->curstate = i;
6368         while (1) {
6369                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6370                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6371                 test.i += modifiers[i - 1].i * d->multipler;
6372                 test.q += modifiers[i - 1].q * d->multipler;
6373                 if ((test.i != prev.i || test.q != prev.q) &&
6374                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6375                         bwn_lo_write(mac, &test);
6376                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6377                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6378                         if (feedth < d->feedth) {
6379                                 memcpy(probe, &test,
6380                                     sizeof(struct bwn_loctl));
6381                                 lower = 1;
6382                                 d->feedth = feedth;
6383                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6384                                         break;
6385                         }
6386                 }
6387                 memcpy(&prev, &test, sizeof(prev));
6388                 if (i == end)
6389                         break;
6390                 if (i == 8)
6391                         i = 1;
6392                 else
6393                         i++;
6394                 d->curstate = i;
6395         }
6396
6397         return (lower);
6398 }
6399
6400 static void
6401 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6402 {
6403         struct bwn_phy *phy = &mac->mac_phy;
6404         struct bwn_phy_g *pg = &phy->phy_g;
6405         struct bwn_lo_g_sm d;
6406         struct bwn_loctl probe;
6407         int lower, repeat, cnt = 0;
6408         uint16_t feedth;
6409
6410         d.nmeasure = 0;
6411         d.multipler = 1;
6412         if (BWN_HAS_LOOPBACK(phy))
6413                 d.multipler = 3;
6414
6415         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6416         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6417
6418         do {
6419                 bwn_lo_write(mac, &d.loctl);
6420                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6421                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6422                 if (feedth < 0x258) {
6423                         if (feedth >= 0x12c)
6424                                 *rxgain += 6;
6425                         else
6426                                 *rxgain += 3;
6427                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6428                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6429                 }
6430                 d.feedth = feedth;
6431                 d.curstate = 0;
6432                 do {
6433                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6434                             ("%s:%d: fail", __func__, __LINE__));
6435                         memcpy(&probe, &d.loctl,
6436                                sizeof(struct bwn_loctl));
6437                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6438                         if (!lower)
6439                                 break;
6440                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6441                                 break;
6442                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6443                         d.nmeasure++;
6444                 } while (d.nmeasure < 24);
6445                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6446
6447                 if (BWN_HAS_LOOPBACK(phy)) {
6448                         if (d.feedth > 0x1194)
6449                                 *rxgain -= 6;
6450                         else if (d.feedth < 0x5dc)
6451                                 *rxgain += 3;
6452                         if (cnt == 0) {
6453                                 if (d.feedth <= 0x5dc) {
6454                                         d.multipler = 1;
6455                                         cnt++;
6456                                 } else
6457                                         d.multipler = 2;
6458                         } else if (cnt == 2)
6459                                 d.multipler = 1;
6460                 }
6461                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6462         } while (++cnt < repeat);
6463 }
6464
6465 static struct bwn_lo_calib *
6466 bwn_lo_calibset(struct bwn_mac *mac,
6467     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6468 {
6469         struct bwn_phy *phy = &mac->mac_phy;
6470         struct bwn_phy_g *pg = &phy->phy_g;
6471         struct bwn_loctl loctl = { 0, 0 };
6472         struct bwn_lo_calib *cal;
6473         struct bwn_lo_g_value sval = { 0 };
6474         int rxgain;
6475         uint16_t pad, reg, value;
6476
6477         sval.old_channel = phy->chan;
6478         bwn_mac_suspend(mac);
6479         bwn_lo_save(mac, &sval);
6480
6481         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6482         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6483         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6484
6485         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6486         if (rfatt->padmix)
6487                 rxgain -= pad;
6488         if (BWN_HAS_LOOPBACK(phy))
6489                 rxgain += pg->pg_max_lb_gain;
6490         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6491         bwn_phy_g_set_bbatt(mac, bbatt->att);
6492         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6493
6494         bwn_lo_restore(mac, &sval);
6495         bwn_mac_enable(mac);
6496
6497         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6498         if (!cal) {
6499                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6500                 return (NULL);
6501         }
6502         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6503         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6504         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6505
6506         BWN_GETTIME(cal->calib_time);
6507
6508         return (cal);
6509 }
6510
6511 static struct bwn_lo_calib *
6512 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6513     const struct bwn_rfatt *rfatt)
6514 {
6515         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6516         struct bwn_lo_calib *c;
6517
6518         TAILQ_FOREACH(c, &lo->calib_list, list) {
6519                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6520                         continue;
6521                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6522                         continue;
6523                 return (c);
6524         }
6525
6526         c = bwn_lo_calibset(mac, bbatt, rfatt);
6527         if (!c)
6528                 return (NULL);
6529         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6530
6531         return (c);
6532 }
6533
6534 static void
6535 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6536 {
6537         struct bwn_phy *phy = &mac->mac_phy;
6538         struct bwn_phy_g *pg = &phy->phy_g;
6539         struct bwn_softc *sc = mac->mac_sc;
6540         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6541         const struct bwn_rfatt *rfatt;
6542         const struct bwn_bbatt *bbatt;
6543         uint64_t pvector;
6544         int i;
6545         int rf_offset, bb_offset;
6546         uint8_t changed = 0;
6547
6548         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6549         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6550             ("%s:%d: fail", __func__, __LINE__));
6551
6552         pvector = lo->power_vector;
6553         if (!update && !pvector)
6554                 return;
6555
6556         bwn_mac_suspend(mac);
6557
6558         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6559                 struct bwn_lo_calib *cal;
6560                 int idx;
6561                 uint16_t val;
6562
6563                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6564                         continue;
6565                 bb_offset = i / lo->rfatt.len;
6566                 rf_offset = i % lo->rfatt.len;
6567                 bbatt = &(lo->bbatt.array[bb_offset]);
6568                 rfatt = &(lo->rfatt.array[rf_offset]);
6569
6570                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6571                 if (!cal) {
6572                         device_printf(sc->sc_dev, "LO: Could not "
6573                             "calibrate DC table entry\n");
6574                         continue;
6575                 }
6576                 val = (uint8_t)(cal->ctl.q);
6577                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6578                 free(cal, M_DEVBUF);
6579
6580                 idx = i / 2;
6581                 if (i % 2)
6582                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6583                             | ((val & 0x00ff) << 8);
6584                 else
6585                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6586                             | (val & 0x00ff);
6587                 changed = 1;
6588         }
6589         if (changed) {
6590                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6591                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6592         }
6593         bwn_mac_enable(mac);
6594 }
6595
6596 static void
6597 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6598 {
6599
6600         if (!rf->padmix)
6601                 return;
6602         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6603                 rf->att = 4;
6604 }
6605
6606 static void
6607 bwn_lo_g_adjust(struct bwn_mac *mac)
6608 {
6609         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6610         struct bwn_lo_calib *cal;
6611         struct bwn_rfatt rf;
6612
6613         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6614         bwn_lo_fixup_rfatt(&rf);
6615
6616         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6617         if (!cal)
6618                 return;
6619         bwn_lo_write(mac, &cal->ctl);
6620 }
6621
6622 static void
6623 bwn_lo_g_init(struct bwn_mac *mac)
6624 {
6625
6626         if (!bwn_has_hwpctl(mac))
6627                 return;
6628
6629         bwn_lo_get_powervector(mac);
6630         bwn_phy_g_dc_lookup_init(mac, 1);
6631 }
6632
6633 static void
6634 bwn_mac_suspend(struct bwn_mac *mac)
6635 {
6636         struct bwn_softc *sc = mac->mac_sc;
6637         int i;
6638         uint32_t tmp;
6639
6640         KASSERT(mac->mac_suspended >= 0,
6641             ("%s:%d: fail", __func__, __LINE__));
6642
6643         if (mac->mac_suspended == 0) {
6644                 bwn_psctl(mac, BWN_PS_AWAKE);
6645                 BWN_WRITE_4(mac, BWN_MACCTL,
6646                             BWN_READ_4(mac, BWN_MACCTL)
6647                             & ~BWN_MACCTL_ON);
6648                 BWN_READ_4(mac, BWN_MACCTL);
6649                 for (i = 35; i; i--) {
6650                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6651                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6652                                 goto out;
6653                         DELAY(10);
6654                 }
6655                 for (i = 40; i; i--) {
6656                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6657                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6658                                 goto out;
6659                         DELAY(1000);
6660                 }
6661                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6662         }
6663 out:
6664         mac->mac_suspended++;
6665 }
6666
6667 static void
6668 bwn_mac_enable(struct bwn_mac *mac)
6669 {
6670         struct bwn_softc *sc = mac->mac_sc;
6671         uint16_t state;
6672
6673         state = bwn_shm_read_2(mac, BWN_SHARED,
6674             BWN_SHARED_UCODESTAT);
6675         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6676             state != BWN_SHARED_UCODESTAT_SLEEP)
6677                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6678
6679         mac->mac_suspended--;
6680         KASSERT(mac->mac_suspended >= 0,
6681             ("%s:%d: fail", __func__, __LINE__));
6682         if (mac->mac_suspended == 0) {
6683                 BWN_WRITE_4(mac, BWN_MACCTL,
6684                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6685                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6686                 BWN_READ_4(mac, BWN_MACCTL);
6687                 BWN_READ_4(mac, BWN_INTR_REASON);
6688                 bwn_psctl(mac, 0);
6689         }
6690 }
6691
6692 static void
6693 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6694 {
6695         struct bwn_softc *sc = mac->mac_sc;
6696         int i;
6697         uint16_t ucstat;
6698
6699         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6700             ("%s:%d: fail", __func__, __LINE__));
6701         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6702             ("%s:%d: fail", __func__, __LINE__));
6703
6704         /* XXX forcibly awake and hwps-off */
6705
6706         BWN_WRITE_4(mac, BWN_MACCTL,
6707             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6708             ~BWN_MACCTL_HWPS);
6709         BWN_READ_4(mac, BWN_MACCTL);
6710         if (siba_get_revid(sc->sc_dev) >= 5) {
6711                 for (i = 0; i < 100; i++) {
6712                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6713                             BWN_SHARED_UCODESTAT);
6714                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6715                                 break;
6716                         DELAY(10);
6717                 }
6718         }
6719 }
6720
6721 static int16_t
6722 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6723 {
6724
6725         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6726         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6727 }
6728
6729 static void
6730 bwn_nrssi_threshold(struct bwn_mac *mac)
6731 {
6732         struct bwn_phy *phy = &mac->mac_phy;
6733         struct bwn_phy_g *pg = &phy->phy_g;
6734         struct bwn_softc *sc = mac->mac_sc;
6735         int32_t a, b;
6736         int16_t tmp16;
6737         uint16_t tmpu16;
6738
6739         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6740
6741         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6742                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6743                         a = 0x13;
6744                         b = 0x12;
6745                 } else {
6746                         a = 0xe;
6747                         b = 0x11;
6748                 }
6749
6750                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6751                 a += (pg->pg_nrssi[0] << 6);
6752                 a += (a < 32) ? 31 : 32;
6753                 a = a >> 6;
6754                 a = MIN(MAX(a, -31), 31);
6755
6756                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6757                 b += (pg->pg_nrssi[0] << 6);
6758                 if (b < 32)
6759                         b += 31;
6760                 else
6761                         b += 32;
6762                 b = b >> 6;
6763                 b = MIN(MAX(b, -31), 31);
6764
6765                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6766                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6767                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6768                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6769                 return;
6770         }
6771
6772         tmp16 = bwn_nrssi_read(mac, 0x20);
6773         if (tmp16 >= 0x20)
6774                 tmp16 -= 0x40;
6775         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6776 }
6777
6778 static void
6779 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6780 {
6781 #define SAVE_RF_MAX             3
6782 #define SAVE_PHY_COMM_MAX       4
6783 #define SAVE_PHY3_MAX           8
6784         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6785                 { 0x7a, 0x52, 0x43 };
6786         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6787                 { 0x15, 0x5a, 0x59, 0x58 };
6788         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6789                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6790                 0x0801, 0x0060, 0x0014, 0x0478
6791         };
6792         struct bwn_phy *phy = &mac->mac_phy;
6793         struct bwn_phy_g *pg = &phy->phy_g;
6794         int32_t i, tmp32, phy3_idx = 0;
6795         uint16_t delta, tmp;
6796         uint16_t save_rf[SAVE_RF_MAX];
6797         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6798         uint16_t save_phy3[SAVE_PHY3_MAX];
6799         uint16_t ant_div, phy0, chan_ex;
6800         int16_t nrssi0, nrssi1;
6801
6802         KASSERT(phy->type == BWN_PHYTYPE_G,
6803             ("%s:%d: fail", __func__, __LINE__));
6804
6805         if (phy->rf_rev >= 9)
6806                 return;
6807         if (phy->rf_rev == 8)
6808                 bwn_nrssi_offset(mac);
6809
6810         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6811         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6812
6813         /*
6814          * Save RF/PHY registers for later restoration
6815          */
6816         ant_div = BWN_READ_2(mac, 0x03e2);
6817         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6818         for (i = 0; i < SAVE_RF_MAX; ++i)
6819                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6820         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6821                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6822
6823         phy0 = BWN_READ_2(mac, BWN_PHY0);
6824         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6825         if (phy->rev >= 3) {
6826                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6827                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6828                 BWN_PHY_WRITE(mac, 0x002e, 0);
6829                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6830                 switch (phy->rev) {
6831                 case 4:
6832                 case 6:
6833                 case 7:
6834                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6835                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6836                         break;
6837                 case 3:
6838                 case 5:
6839                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6840                         break;
6841                 }
6842                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6843                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6844         }
6845         /*
6846          * Calculate nrssi0
6847          */
6848         BWN_RF_SET(mac, 0x007a, 0x0070);
6849         bwn_set_all_gains(mac, 0, 8, 0);
6850         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6851         if (phy->rev >= 2) {
6852                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6853                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6854         }
6855         BWN_RF_SET(mac, 0x007a, 0x0080);
6856         DELAY(20);
6857
6858         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6859         if (nrssi0 >= 0x0020)
6860                 nrssi0 -= 0x0040;
6861
6862         /*
6863          * Calculate nrssi1
6864          */
6865         BWN_RF_MASK(mac, 0x007a, 0x007f);
6866         if (phy->rev >= 2)
6867                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6868
6869         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6870             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6871         BWN_RF_SET(mac, 0x007a, 0x000f);
6872         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6873         if (phy->rev >= 2) {
6874                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6875                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6876         }
6877
6878         bwn_set_all_gains(mac, 3, 0, 1);
6879         if (phy->rf_rev == 8) {
6880                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6881         } else {
6882                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6883                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6884                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6885                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6886         }
6887         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6888         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6889         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6890         DELAY(20);
6891         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6892
6893         /*
6894          * Install calculated narrow RSSI values
6895          */
6896         if (nrssi1 >= 0x0020)
6897                 nrssi1 -= 0x0040;
6898         if (nrssi0 == nrssi1)
6899                 pg->pg_nrssi_slope = 0x00010000;
6900         else
6901                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6902         if (nrssi0 >= -4) {
6903                 pg->pg_nrssi[0] = nrssi1;
6904                 pg->pg_nrssi[1] = nrssi0;
6905         }
6906
6907         /*
6908          * Restore saved RF/PHY registers
6909          */
6910         if (phy->rev >= 3) {
6911                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6912                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6913                             save_phy3[phy3_idx]);
6914                 }
6915         }
6916         if (phy->rev >= 2) {
6917                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6918                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6919         }
6920
6921         for (i = 0; i < SAVE_RF_MAX; ++i)
6922                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6923
6924         BWN_WRITE_2(mac, 0x03e2, ant_div);
6925         BWN_WRITE_2(mac, 0x03e6, phy0);
6926         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6927
6928         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6929                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6930
6931         bwn_spu_workaround(mac, phy->chan);
6932         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6933         bwn_set_original_gains(mac);
6934         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6935         if (phy->rev >= 3) {
6936                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6937                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6938                             save_phy3[phy3_idx]);
6939                 }
6940         }
6941
6942         delta = 0x1f - pg->pg_nrssi[0];
6943         for (i = 0; i < 64; i++) {
6944                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6945                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6946                 pg->pg_nrssi_lt[i] = tmp32;
6947         }
6948
6949         bwn_nrssi_threshold(mac);
6950 #undef SAVE_RF_MAX
6951 #undef SAVE_PHY_COMM_MAX
6952 #undef SAVE_PHY3_MAX
6953 }
6954
6955 static void
6956 bwn_nrssi_offset(struct bwn_mac *mac)
6957 {
6958 #define SAVE_RF_MAX             2
6959 #define SAVE_PHY_COMM_MAX       10
6960 #define SAVE_PHY6_MAX           8
6961         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6962                 { 0x7a, 0x43 };
6963         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6964                 0x0001, 0x0811, 0x0812, 0x0814,
6965                 0x0815, 0x005a, 0x0059, 0x0058,
6966                 0x000a, 0x0003
6967         };
6968         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6969                 0x002e, 0x002f, 0x080f, 0x0810,
6970                 0x0801, 0x0060, 0x0014, 0x0478
6971         };
6972         struct bwn_phy *phy = &mac->mac_phy;
6973         int i, phy6_idx = 0;
6974         uint16_t save_rf[SAVE_RF_MAX];
6975         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6976         uint16_t save_phy6[SAVE_PHY6_MAX];
6977         int16_t nrssi;
6978         uint16_t saved = 0xffff;
6979
6980         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6981                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6982         for (i = 0; i < SAVE_RF_MAX; ++i)
6983                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6984
6985         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6986         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6987         BWN_PHY_SET(mac, 0x0811, 0x000c);
6988         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6989         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6990         if (phy->rev >= 6) {
6991                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6992                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6993
6994                 BWN_PHY_WRITE(mac, 0x002e, 0);
6995                 BWN_PHY_WRITE(mac, 0x002f, 0);
6996                 BWN_PHY_WRITE(mac, 0x080f, 0);
6997                 BWN_PHY_WRITE(mac, 0x0810, 0);
6998                 BWN_PHY_SET(mac, 0x0478, 0x0100);
6999                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7000                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7001                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7002         }
7003         BWN_RF_SET(mac, 0x007a, 0x0070);
7004         BWN_RF_SET(mac, 0x007a, 0x0080);
7005         DELAY(30);
7006
7007         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7008         if (nrssi >= 0x20)
7009                 nrssi -= 0x40;
7010         if (nrssi == 31) {
7011                 for (i = 7; i >= 4; i--) {
7012                         BWN_RF_WRITE(mac, 0x007b, i);
7013                         DELAY(20);
7014                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7015                             0x003f);
7016                         if (nrssi >= 0x20)
7017                                 nrssi -= 0x40;
7018                         if (nrssi < 31 && saved == 0xffff)
7019                                 saved = i;
7020                 }
7021                 if (saved == 0xffff)
7022                         saved = 4;
7023         } else {
7024                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7025                 if (phy->rev != 1) {
7026                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7027                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7028                 }
7029                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7030                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7031                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7032                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7033                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7034                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7035                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7036                 if (phy->rev == 0)
7037                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7038                 else
7039                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7040                 if (phy->rev != 1) {
7041                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7042                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7043                 }
7044                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7045                 BWN_RF_SET(mac, 0x007a, 0x000f);
7046                 bwn_set_all_gains(mac, 3, 0, 1);
7047                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7048                 DELAY(30);
7049                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7050                 if (nrssi >= 0x20)
7051                         nrssi -= 0x40;
7052                 if (nrssi == -32) {
7053                         for (i = 0; i < 4; i++) {
7054                                 BWN_RF_WRITE(mac, 0x007b, i);
7055                                 DELAY(20);
7056                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7057                                     0x047f) >> 8) & 0x003f);
7058                                 if (nrssi >= 0x20)
7059                                         nrssi -= 0x40;
7060                                 if (nrssi > -31 && saved == 0xffff)
7061                                         saved = i;
7062                         }
7063                         if (saved == 0xffff)
7064                                 saved = 3;
7065                 } else
7066                         saved = 0;
7067         }
7068         BWN_RF_WRITE(mac, 0x007b, saved);
7069
7070         /*
7071          * Restore saved RF/PHY registers
7072          */
7073         if (phy->rev >= 6) {
7074                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7075                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7076                             save_phy6[phy6_idx]);
7077                 }
7078         }
7079         if (phy->rev != 1) {
7080                 for (i = 3; i < 5; i++)
7081                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7082                             save_phy_comm[i]);
7083         }
7084         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7085                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7086
7087         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7088                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7089
7090         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7091         BWN_PHY_SET(mac, 0x0429, 0x8000);
7092         bwn_set_original_gains(mac);
7093         if (phy->rev >= 6) {
7094                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7095                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7096                             save_phy6[phy6_idx]);
7097                 }
7098         }
7099
7100         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7101         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7102         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7103 }
7104
7105 static void
7106 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7107     int16_t third)
7108 {
7109         struct bwn_phy *phy = &mac->mac_phy;
7110         uint16_t i;
7111         uint16_t start = 0x08, end = 0x18;
7112         uint16_t tmp;
7113         uint16_t table;
7114
7115         if (phy->rev <= 1) {
7116                 start = 0x10;
7117                 end = 0x20;
7118         }
7119
7120         table = BWN_OFDMTAB_GAINX;
7121         if (phy->rev <= 1)
7122                 table = BWN_OFDMTAB_GAINX_R1;
7123         for (i = 0; i < 4; i++)
7124                 bwn_ofdmtab_write_2(mac, table, i, first);
7125
7126         for (i = start; i < end; i++)
7127                 bwn_ofdmtab_write_2(mac, table, i, second);
7128
7129         if (third != -1) {
7130                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7131                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7132                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7133                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7134         }
7135         bwn_dummy_transmission(mac, 0, 1);
7136 }
7137
7138 static void
7139 bwn_set_original_gains(struct bwn_mac *mac)
7140 {
7141         struct bwn_phy *phy = &mac->mac_phy;
7142         uint16_t i, tmp;
7143         uint16_t table;
7144         uint16_t start = 0x0008, end = 0x0018;
7145
7146         if (phy->rev <= 1) {
7147                 start = 0x0010;
7148                 end = 0x0020;
7149         }
7150
7151         table = BWN_OFDMTAB_GAINX;
7152         if (phy->rev <= 1)
7153                 table = BWN_OFDMTAB_GAINX_R1;
7154         for (i = 0; i < 4; i++) {
7155                 tmp = (i & 0xfffc);
7156                 tmp |= (i & 0x0001) << 1;
7157                 tmp |= (i & 0x0002) >> 1;
7158
7159                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7160         }
7161
7162         for (i = start; i < end; i++)
7163                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7164
7165         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7166         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7167         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7168         bwn_dummy_transmission(mac, 0, 1);
7169 }
7170
7171 static void
7172 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7173 {
7174         struct bwn_phy *phy = &mac->mac_phy;
7175         struct bwn_phy_g *pg = &phy->phy_g;
7176         struct bwn_rfatt old_rfatt, rfatt;
7177         struct bwn_bbatt old_bbatt, bbatt;
7178         struct bwn_softc *sc = mac->mac_sc;
7179         uint8_t old_txctl = 0;
7180
7181         KASSERT(phy->type == BWN_PHYTYPE_G,
7182             ("%s:%d: fail", __func__, __LINE__));
7183
7184         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7185             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7186                 return;
7187
7188         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7189
7190         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7191
7192         if (!phy->gmode)
7193                 return;
7194         bwn_hwpctl_early_init(mac);
7195         if (pg->pg_curtssi == 0) {
7196                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7197                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7198                 } else {
7199                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7200                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7201                         old_txctl = pg->pg_txctl;
7202
7203                         bbatt.att = 11;
7204                         if (phy->rf_rev == 8) {
7205                                 rfatt.att = 15;
7206                                 rfatt.padmix = 1;
7207                         } else {
7208                                 rfatt.att = 9;
7209                                 rfatt.padmix = 0;
7210                         }
7211                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7212                 }
7213                 bwn_dummy_transmission(mac, 0, 1);
7214                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7215                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7216                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7217                 else
7218                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7219                             &old_rfatt, old_txctl);
7220         }
7221         bwn_hwpctl_init_gphy(mac);
7222
7223         /* clear TSSI */
7224         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7225         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7226         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7227         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7228 }
7229
7230 static void
7231 bwn_hwpctl_early_init(struct bwn_mac *mac)
7232 {
7233         struct bwn_phy *phy = &mac->mac_phy;
7234
7235         if (!bwn_has_hwpctl(mac)) {
7236                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7237                 return;
7238         }
7239
7240         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7241         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7242         BWN_PHY_SET(mac, 0x047c, 0x0002);
7243         BWN_PHY_SET(mac, 0x047a, 0xf000);
7244         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7245                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7246                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7247                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7248                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7249                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7250         } else {
7251                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7252                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7253                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7254                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7255                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7256                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7257                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7258         }
7259 }
7260
7261 static void
7262 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7263 {
7264         struct bwn_phy *phy = &mac->mac_phy;
7265         struct bwn_phy_g *pg = &phy->phy_g;
7266         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7267         int i;
7268         uint16_t nr_written = 0, tmp, value;
7269         uint8_t rf, bb;
7270
7271         if (!bwn_has_hwpctl(mac)) {
7272                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7273                 return;
7274         }
7275
7276         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7277             (pg->pg_idletssi - pg->pg_curtssi));
7278         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7279             (pg->pg_idletssi - pg->pg_curtssi));
7280
7281         for (i = 0; i < 32; i++)
7282                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7283         for (i = 32; i < 64; i++)
7284                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7285         for (i = 0; i < 64; i += 2) {
7286                 value = (uint16_t) pg->pg_tssi2dbm[i];
7287                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7288                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7289         }
7290
7291         for (rf = 0; rf < lo->rfatt.len; rf++) {
7292                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7293                         if (nr_written >= 0x40)
7294                                 return;
7295                         tmp = lo->bbatt.array[bb].att;
7296                         tmp <<= 8;
7297                         if (phy->rf_rev == 8)
7298                                 tmp |= 0x50;
7299                         else
7300                                 tmp |= 0x40;
7301                         tmp |= lo->rfatt.array[rf].att;
7302                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7303                         nr_written++;
7304                 }
7305         }
7306
7307         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7308         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7309
7310         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7311         BWN_PHY_SET(mac, 0x0478, 0x0800);
7312         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7313         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7314
7315         bwn_phy_g_dc_lookup_init(mac, 1);
7316         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7317 }
7318
7319 static void
7320 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7321 {
7322         struct bwn_softc *sc = mac->mac_sc;
7323
7324         if (spu != 0)
7325                 bwn_spu_workaround(mac, channel);
7326
7327         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7328
7329         if (channel == 14) {
7330                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7331                         bwn_hf_write(mac,
7332                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7333                 else
7334                         bwn_hf_write(mac,
7335                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7336                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7337                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7338                 return;
7339         }
7340
7341         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7342             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7343 }
7344
7345 static uint16_t
7346 bwn_phy_g_chan2freq(uint8_t channel)
7347 {
7348         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7349
7350         KASSERT(channel >= 1 && channel <= 14,
7351             ("%s:%d: fail", __func__, __LINE__));
7352
7353         return (bwn_phy_g_rf_channels[channel - 1]);
7354 }
7355
7356 static void
7357 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7358     const struct bwn_rfatt *rfatt, uint8_t txctl)
7359 {
7360         struct bwn_phy *phy = &mac->mac_phy;
7361         struct bwn_phy_g *pg = &phy->phy_g;
7362         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7363         uint16_t bb, rf;
7364         uint16_t tx_bias, tx_magn;
7365
7366         bb = bbatt->att;
7367         rf = rfatt->att;
7368         tx_bias = lo->tx_bias;
7369         tx_magn = lo->tx_magn;
7370         if (tx_bias == 0xff)
7371                 tx_bias = 0;
7372
7373         pg->pg_txctl = txctl;
7374         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7375         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7376         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7377         bwn_phy_g_set_bbatt(mac, bb);
7378         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7379         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7380                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7381         else {
7382                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7383                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7384         }
7385         if (BWN_HAS_TXMAG(phy))
7386                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7387         else
7388                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7389         bwn_lo_g_adjust(mac);
7390 }
7391
7392 static void
7393 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7394     uint16_t bbatt)
7395 {
7396         struct bwn_phy *phy = &mac->mac_phy;
7397
7398         if (phy->analog == 0) {
7399                 BWN_WRITE_2(mac, BWN_PHY0,
7400                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7401                 return;
7402         }
7403         if (phy->analog > 1) {
7404                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7405                 return;
7406         }
7407         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7408 }
7409
7410 static uint16_t
7411 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7412 {
7413         struct bwn_phy *phy = &mac->mac_phy;
7414         struct bwn_phy_g *pg = &phy->phy_g;
7415         struct bwn_softc *sc = mac->mac_sc;
7416         int max_lb_gain;
7417         uint16_t extlna;
7418         uint16_t i;
7419
7420         if (phy->gmode == 0)
7421                 return (0);
7422
7423         if (BWN_HAS_LOOPBACK(phy)) {
7424                 max_lb_gain = pg->pg_max_lb_gain;
7425                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7426                 if (max_lb_gain >= 0x46) {
7427                         extlna = 0x3000;
7428                         max_lb_gain -= 0x46;
7429                 } else if (max_lb_gain >= 0x3a) {
7430                         extlna = 0x1000;
7431                         max_lb_gain -= 0x3a;
7432                 } else if (max_lb_gain >= 0x2e) {
7433                         extlna = 0x2000;
7434                         max_lb_gain -= 0x2e;
7435                 } else {
7436                         extlna = 0;
7437                         max_lb_gain -= 0x10;
7438                 }
7439
7440                 for (i = 0; i < 16; i++) {
7441                         max_lb_gain -= (i * 6);
7442                         if (max_lb_gain < 6)
7443                                 break;
7444                 }
7445
7446                 if ((phy->rev < 7) ||
7447                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7448                         if (reg == BWN_PHY_RFOVER) {
7449                                 return (0x1b3);
7450                         } else if (reg == BWN_PHY_RFOVERVAL) {
7451                                 extlna |= (i << 8);
7452                                 switch (lpd) {
7453                                 case BWN_LPD(0, 1, 1):
7454                                         return (0x0f92);
7455                                 case BWN_LPD(0, 0, 1):
7456                                 case BWN_LPD(1, 0, 1):
7457                                         return (0x0092 | extlna);
7458                                 case BWN_LPD(1, 0, 0):
7459                                         return (0x0093 | extlna);
7460                                 }
7461                                 KASSERT(0 == 1,
7462                                     ("%s:%d: fail", __func__, __LINE__));
7463                         }
7464                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7465                 } else {
7466                         if (reg == BWN_PHY_RFOVER)
7467                                 return (0x9b3);
7468                         if (reg == BWN_PHY_RFOVERVAL) {
7469                                 if (extlna)
7470                                         extlna |= 0x8000;
7471                                 extlna |= (i << 8);
7472                                 switch (lpd) {
7473                                 case BWN_LPD(0, 1, 1):
7474                                         return (0x8f92);
7475                                 case BWN_LPD(0, 0, 1):
7476                                         return (0x8092 | extlna);
7477                                 case BWN_LPD(1, 0, 1):
7478                                         return (0x2092 | extlna);
7479                                 case BWN_LPD(1, 0, 0):
7480                                         return (0x2093 | extlna);
7481                                 }
7482                                 KASSERT(0 == 1,
7483                                     ("%s:%d: fail", __func__, __LINE__));
7484                         }
7485                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7486                 }
7487                 return (0);
7488         }
7489
7490         if ((phy->rev < 7) ||
7491             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7492                 if (reg == BWN_PHY_RFOVER) {
7493                         return (0x1b3);
7494                 } else if (reg == BWN_PHY_RFOVERVAL) {
7495                         switch (lpd) {
7496                         case BWN_LPD(0, 1, 1):
7497                                 return (0x0fb2);
7498                         case BWN_LPD(0, 0, 1):
7499                                 return (0x00b2);
7500                         case BWN_LPD(1, 0, 1):
7501                                 return (0x30b2);
7502                         case BWN_LPD(1, 0, 0):
7503                                 return (0x30b3);
7504                         }
7505                         KASSERT(0 == 1,
7506                             ("%s:%d: fail", __func__, __LINE__));
7507                 }
7508                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7509         } else {
7510                 if (reg == BWN_PHY_RFOVER) {
7511                         return (0x9b3);
7512                 } else if (reg == BWN_PHY_RFOVERVAL) {
7513                         switch (lpd) {
7514                         case BWN_LPD(0, 1, 1):
7515                                 return (0x8fb2);
7516                         case BWN_LPD(0, 0, 1):
7517                                 return (0x80b2);
7518                         case BWN_LPD(1, 0, 1):
7519                                 return (0x20b2);
7520                         case BWN_LPD(1, 0, 0):
7521                                 return (0x20b3);
7522                         }
7523                         KASSERT(0 == 1,
7524                             ("%s:%d: fail", __func__, __LINE__));
7525                 }
7526                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7527         }
7528         return (0);
7529 }
7530
7531 static void
7532 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7533 {
7534
7535         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7536                 return;
7537         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7538             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7539         DELAY(1000);
7540         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7541 }
7542
7543 static int
7544 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7545 {
7546         struct bwn_softc *sc = mac->mac_sc;
7547         struct bwn_fw *fw = &mac->mac_fw;
7548         const uint8_t rev = siba_get_revid(sc->sc_dev);
7549         const char *filename;
7550         uint32_t high;
7551         int error;
7552
7553         /* microcode */
7554         if (rev >= 5 && rev <= 10)
7555                 filename = "ucode5";
7556         else if (rev >= 11 && rev <= 12)
7557                 filename = "ucode11";
7558         else if (rev == 13)
7559                 filename = "ucode13";
7560         else if (rev == 14)
7561                 filename = "ucode14";
7562         else if (rev >= 15)
7563                 filename = "ucode15";
7564         else {
7565                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7566                 bwn_release_firmware(mac);
7567                 return (EOPNOTSUPP);
7568         }
7569         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7570         if (error) {
7571                 bwn_release_firmware(mac);
7572                 return (error);
7573         }
7574
7575         /* PCM */
7576         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7577         if (rev >= 5 && rev <= 10) {
7578                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7579                 if (error == ENOENT)
7580                         fw->no_pcmfile = 1;
7581                 else if (error) {
7582                         bwn_release_firmware(mac);
7583                         return (error);
7584                 }
7585         } else if (rev < 11) {
7586                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7587                 return (EOPNOTSUPP);
7588         }
7589
7590         /* initvals */
7591         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7592         switch (mac->mac_phy.type) {
7593         case BWN_PHYTYPE_A:
7594                 if (rev < 5 || rev > 10)
7595                         goto fail1;
7596                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7597                         filename = "a0g1initvals5";
7598                 else
7599                         filename = "a0g0initvals5";
7600                 break;
7601         case BWN_PHYTYPE_G:
7602                 if (rev >= 5 && rev <= 10)
7603                         filename = "b0g0initvals5";
7604                 else if (rev >= 13)
7605                         filename = "b0g0initvals13";
7606                 else
7607                         goto fail1;
7608                 break;
7609         case BWN_PHYTYPE_LP:
7610                 if (rev == 13)
7611                         filename = "lp0initvals13";
7612                 else if (rev == 14)
7613                         filename = "lp0initvals14";
7614                 else if (rev >= 15)
7615                         filename = "lp0initvals15";
7616                 else
7617                         goto fail1;
7618                 break;
7619         case BWN_PHYTYPE_N:
7620                 if (rev >= 11 && rev <= 12)
7621                         filename = "n0initvals11";
7622                 else
7623                         goto fail1;
7624                 break;
7625         default:
7626                 goto fail1;
7627         }
7628         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7629         if (error) {
7630                 bwn_release_firmware(mac);
7631                 return (error);
7632         }
7633
7634         /* bandswitch initvals */
7635         switch (mac->mac_phy.type) {
7636         case BWN_PHYTYPE_A:
7637                 if (rev >= 5 && rev <= 10) {
7638                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7639                                 filename = "a0g1bsinitvals5";
7640                         else
7641                                 filename = "a0g0bsinitvals5";
7642                 } else if (rev >= 11)
7643                         filename = NULL;
7644                 else
7645                         goto fail1;
7646                 break;
7647         case BWN_PHYTYPE_G:
7648                 if (rev >= 5 && rev <= 10)
7649                         filename = "b0g0bsinitvals5";
7650                 else if (rev >= 11)
7651                         filename = NULL;
7652                 else
7653                         goto fail1;
7654                 break;
7655         case BWN_PHYTYPE_LP:
7656                 if (rev == 13)
7657                         filename = "lp0bsinitvals13";
7658                 else if (rev == 14)
7659                         filename = "lp0bsinitvals14";
7660                 else if (rev >= 15)
7661                         filename = "lp0bsinitvals15";
7662                 else
7663                         goto fail1;
7664                 break;
7665         case BWN_PHYTYPE_N:
7666                 if (rev >= 11 && rev <= 12)
7667                         filename = "n0bsinitvals11";
7668                 else
7669                         goto fail1;
7670                 break;
7671         default:
7672                 goto fail1;
7673         }
7674         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7675         if (error) {
7676                 bwn_release_firmware(mac);
7677                 return (error);
7678         }
7679         return (0);
7680 fail1:
7681         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7682         bwn_release_firmware(mac);
7683         return (EOPNOTSUPP);
7684 }
7685
7686 static int
7687 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7688     const char *name, struct bwn_fwfile *bfw)
7689 {
7690         const struct bwn_fwhdr *hdr;
7691         struct bwn_softc *sc = mac->mac_sc;
7692         const struct firmware *fw;
7693         char namebuf[64];
7694
7695         if (name == NULL) {
7696                 bwn_do_release_fw(bfw);
7697                 return (0);
7698         }
7699         if (bfw->filename != NULL) {
7700                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7701                         return (0);
7702                 bwn_do_release_fw(bfw);
7703         }
7704
7705         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7706             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7707             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7708         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7709         fw = firmware_get(namebuf);
7710         if (fw == NULL) {
7711                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7712                     namebuf);
7713                 return (ENOENT);
7714         }
7715         if (fw->datasize < sizeof(struct bwn_fwhdr))
7716                 goto fail;
7717         hdr = (const struct bwn_fwhdr *)(fw->data);
7718         switch (hdr->type) {
7719         case BWN_FWTYPE_UCODE:
7720         case BWN_FWTYPE_PCM:
7721                 if (be32toh(hdr->size) !=
7722                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7723                         goto fail;
7724                 /* FALLTHROUGH */
7725         case BWN_FWTYPE_IV:
7726                 if (hdr->ver != 1)
7727                         goto fail;
7728                 break;
7729         default:
7730                 goto fail;
7731         }
7732         bfw->filename = name;
7733         bfw->fw = fw;
7734         bfw->type = type;
7735         return (0);
7736 fail:
7737         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7738         if (fw != NULL)
7739                 firmware_put(fw, FIRMWARE_UNLOAD);
7740         return (EPROTO);
7741 }
7742
7743 static void
7744 bwn_release_firmware(struct bwn_mac *mac)
7745 {
7746
7747         bwn_do_release_fw(&mac->mac_fw.ucode);
7748         bwn_do_release_fw(&mac->mac_fw.pcm);
7749         bwn_do_release_fw(&mac->mac_fw.initvals);
7750         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7751 }
7752
7753 static void
7754 bwn_do_release_fw(struct bwn_fwfile *bfw)
7755 {
7756
7757         if (bfw->fw != NULL)
7758                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7759         bfw->fw = NULL;
7760         bfw->filename = NULL;
7761 }
7762
7763 static int
7764 bwn_fw_loaducode(struct bwn_mac *mac)
7765 {
7766 #define GETFWOFFSET(fwp, offset)        \
7767         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7768 #define GETFWSIZE(fwp, offset)  \
7769         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7770         struct bwn_softc *sc = mac->mac_sc;
7771         const uint32_t *data;
7772         unsigned int i;
7773         uint32_t ctl;
7774         uint16_t date, fwcaps, time;
7775         int error = 0;
7776
7777         ctl = BWN_READ_4(mac, BWN_MACCTL);
7778         ctl |= BWN_MACCTL_MCODE_JMP0;
7779         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7780             __LINE__));
7781         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7782         for (i = 0; i < 64; i++)
7783                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7784         for (i = 0; i < 4096; i += 2)
7785                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7786
7787         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7788         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7789         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7790              i++) {
7791                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7792                 DELAY(10);
7793         }
7794
7795         if (mac->mac_fw.pcm.fw) {
7796                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7797                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7798                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7799                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7800                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7801                     sizeof(struct bwn_fwhdr)); i++) {
7802                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7803                         DELAY(10);
7804                 }
7805         }
7806
7807         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7808         BWN_WRITE_4(mac, BWN_MACCTL,
7809             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7810             BWN_MACCTL_MCODE_RUN);
7811
7812         for (i = 0; i < 21; i++) {
7813                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7814                         break;
7815                 if (i >= 20) {
7816                         device_printf(sc->sc_dev, "ucode timeout\n");
7817                         error = ENXIO;
7818                         goto error;
7819                 }
7820                 DELAY(50000);
7821         }
7822         BWN_READ_4(mac, BWN_INTR_REASON);
7823
7824         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7825         if (mac->mac_fw.rev <= 0x128) {
7826                 device_printf(sc->sc_dev, "the firmware is too old\n");
7827                 error = EOPNOTSUPP;
7828                 goto error;
7829         }
7830         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7831             BWN_SHARED_UCODE_PATCH);
7832         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7833         mac->mac_fw.opensource = (date == 0xffff);
7834         if (bwn_wme != 0)
7835                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7836         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7837
7838         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7839         if (mac->mac_fw.opensource == 0) {
7840                 device_printf(sc->sc_dev,
7841                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7842                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7843                 if (mac->mac_fw.no_pcmfile)
7844                         device_printf(sc->sc_dev,
7845                             "no HW crypto acceleration due to pcm5\n");
7846         } else {
7847                 mac->mac_fw.patch = time;
7848                 fwcaps = bwn_fwcaps_read(mac);
7849                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7850                         device_printf(sc->sc_dev,
7851                             "disabling HW crypto acceleration\n");
7852                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7853                 }
7854                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7855                         device_printf(sc->sc_dev, "disabling WME support\n");
7856                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7857                 }
7858         }
7859
7860         if (BWN_ISOLDFMT(mac))
7861                 device_printf(sc->sc_dev, "using old firmware image\n");
7862
7863         return (0);
7864
7865 error:
7866         BWN_WRITE_4(mac, BWN_MACCTL,
7867             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7868             BWN_MACCTL_MCODE_JMP0);
7869
7870         return (error);
7871 #undef GETFWSIZE
7872 #undef GETFWOFFSET
7873 }
7874
7875 /* OpenFirmware only */
7876 static uint16_t
7877 bwn_fwcaps_read(struct bwn_mac *mac)
7878 {
7879
7880         KASSERT(mac->mac_fw.opensource == 1,
7881             ("%s:%d: fail", __func__, __LINE__));
7882         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7883 }
7884
7885 static int
7886 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7887     size_t count, size_t array_size)
7888 {
7889 #define GET_NEXTIV16(iv)                                                \
7890         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7891             sizeof(uint16_t) + sizeof(uint16_t)))
7892 #define GET_NEXTIV32(iv)                                                \
7893         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7894             sizeof(uint16_t) + sizeof(uint32_t)))
7895         struct bwn_softc *sc = mac->mac_sc;
7896         const struct bwn_fwinitvals *iv;
7897         uint16_t offset;
7898         size_t i;
7899         uint8_t bit32;
7900
7901         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7902             ("%s:%d: fail", __func__, __LINE__));
7903         iv = ivals;
7904         for (i = 0; i < count; i++) {
7905                 if (array_size < sizeof(iv->offset_size))
7906                         goto fail;
7907                 array_size -= sizeof(iv->offset_size);
7908                 offset = be16toh(iv->offset_size);
7909                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7910                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7911                 if (offset >= 0x1000)
7912                         goto fail;
7913                 if (bit32) {
7914                         if (array_size < sizeof(iv->data.d32))
7915                                 goto fail;
7916                         array_size -= sizeof(iv->data.d32);
7917                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7918                         iv = GET_NEXTIV32(iv);
7919                 } else {
7920
7921                         if (array_size < sizeof(iv->data.d16))
7922                                 goto fail;
7923                         array_size -= sizeof(iv->data.d16);
7924                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7925
7926                         iv = GET_NEXTIV16(iv);
7927                 }
7928         }
7929         if (array_size != 0)
7930                 goto fail;
7931         return (0);
7932 fail:
7933         device_printf(sc->sc_dev, "initvals: invalid format\n");
7934         return (EPROTO);
7935 #undef GET_NEXTIV16
7936 #undef GET_NEXTIV32
7937 }
7938
7939 static int
7940 bwn_switch_channel(struct bwn_mac *mac, int chan)
7941 {
7942         struct bwn_phy *phy = &(mac->mac_phy);
7943         struct bwn_softc *sc = mac->mac_sc;
7944         struct ifnet *ifp = sc->sc_ifp;
7945         struct ieee80211com *ic = ifp->if_l2com;
7946         uint16_t channelcookie, savedcookie;
7947         int error;
7948
7949         if (chan == 0xffff)
7950                 chan = phy->get_default_chan(mac);
7951
7952         channelcookie = chan;
7953         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7954                 channelcookie |= 0x100;
7955         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7956         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7957         error = phy->switch_channel(mac, chan);
7958         if (error)
7959                 goto fail;
7960
7961         mac->mac_phy.chan = chan;
7962         DELAY(8000);
7963         return (0);
7964 fail:
7965         device_printf(sc->sc_dev, "failed to switch channel\n");
7966         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7967         return (error);
7968 }
7969
7970 static uint16_t
7971 bwn_ant2phy(int antenna)
7972 {
7973
7974         switch (antenna) {
7975         case BWN_ANT0:
7976                 return (BWN_TX_PHY_ANT0);
7977         case BWN_ANT1:
7978                 return (BWN_TX_PHY_ANT1);
7979         case BWN_ANT2:
7980                 return (BWN_TX_PHY_ANT2);
7981         case BWN_ANT3:
7982                 return (BWN_TX_PHY_ANT3);
7983         case BWN_ANTAUTO:
7984                 return (BWN_TX_PHY_ANT01AUTO);
7985         }
7986         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7987         return (0);
7988 }
7989
7990 static void
7991 bwn_wme_load(struct bwn_mac *mac)
7992 {
7993         struct bwn_softc *sc = mac->mac_sc;
7994         int i;
7995
7996         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7997             ("%s:%d: fail", __func__, __LINE__));
7998
7999         bwn_mac_suspend(mac);
8000         for (i = 0; i < N(sc->sc_wmeParams); i++)
8001                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8002                     bwn_wme_shm_offsets[i]);
8003         bwn_mac_enable(mac);
8004 }
8005
8006 static void
8007 bwn_wme_loadparams(struct bwn_mac *mac,
8008     const struct wmeParams *p, uint16_t shm_offset)
8009 {
8010 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8011         struct bwn_softc *sc = mac->mac_sc;
8012         uint16_t params[BWN_NR_WMEPARAMS];
8013         int slot, tmp;
8014         unsigned int i;
8015
8016         slot = BWN_READ_2(mac, BWN_RNG) &
8017             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8018
8019         memset(&params, 0, sizeof(params));
8020
8021         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8022             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8023             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8024
8025         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8026         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8027         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8028         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8029         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8030         params[BWN_WMEPARAM_BSLOTS] = slot;
8031         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8032
8033         for (i = 0; i < N(params); i++) {
8034                 if (i == BWN_WMEPARAM_STATUS) {
8035                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8036                             shm_offset + (i * 2));
8037                         tmp |= 0x100;
8038                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8039                             tmp);
8040                 } else {
8041                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8042                             params[i]);
8043                 }
8044         }
8045 }
8046
8047 static void
8048 bwn_mac_write_bssid(struct bwn_mac *mac)
8049 {
8050         struct bwn_softc *sc = mac->mac_sc;
8051         uint32_t tmp;
8052         int i;
8053         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8054
8055         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8056         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8057         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8058             IEEE80211_ADDR_LEN);
8059
8060         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8061                 tmp = (uint32_t) (mac_bssid[i + 0]);
8062                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8063                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8064                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8065                 bwn_ram_write(mac, 0x20 + i, tmp);
8066         }
8067 }
8068
8069 static void
8070 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8071     const uint8_t *macaddr)
8072 {
8073         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8074         uint16_t data;
8075
8076         if (!mac)
8077                 macaddr = zero;
8078
8079         offset |= 0x0020;
8080         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8081
8082         data = macaddr[0];
8083         data |= macaddr[1] << 8;
8084         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8085         data = macaddr[2];
8086         data |= macaddr[3] << 8;
8087         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8088         data = macaddr[4];
8089         data |= macaddr[5] << 8;
8090         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8091 }
8092
8093 static void
8094 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8095     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8096 {
8097         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8098         uint8_t per_sta_keys_start = 8;
8099
8100         if (BWN_SEC_NEWAPI(mac))
8101                 per_sta_keys_start = 4;
8102
8103         KASSERT(index < mac->mac_max_nr_keys,
8104             ("%s:%d: fail", __func__, __LINE__));
8105         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8106             ("%s:%d: fail", __func__, __LINE__));
8107
8108         if (index >= per_sta_keys_start)
8109                 bwn_key_macwrite(mac, index, NULL);
8110         if (key)
8111                 memcpy(buf, key, key_len);
8112         bwn_key_write(mac, index, algorithm, buf);
8113         if (index >= per_sta_keys_start)
8114                 bwn_key_macwrite(mac, index, mac_addr);
8115
8116         mac->mac_key[index].algorithm = algorithm;
8117 }
8118
8119 static void
8120 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8121 {
8122         struct bwn_softc *sc = mac->mac_sc;
8123         uint32_t addrtmp[2] = { 0, 0 };
8124         uint8_t start = 8;
8125
8126         if (BWN_SEC_NEWAPI(mac))
8127                 start = 4;
8128
8129         KASSERT(index >= start,
8130             ("%s:%d: fail", __func__, __LINE__));
8131         index -= start;
8132
8133         if (addr) {
8134                 addrtmp[0] = addr[0];
8135                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8136                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8137                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8138                 addrtmp[1] = addr[4];
8139                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8140         }
8141
8142         if (siba_get_revid(sc->sc_dev) >= 5) {
8143                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8144                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8145         } else {
8146                 if (index >= 8) {
8147                         bwn_shm_write_4(mac, BWN_SHARED,
8148                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8149                         bwn_shm_write_2(mac, BWN_SHARED,
8150                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8151                 }
8152         }
8153 }
8154
8155 static void
8156 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8157     const uint8_t *key)
8158 {
8159         unsigned int i;
8160         uint32_t offset;
8161         uint16_t kidx, value;
8162
8163         kidx = BWN_SEC_KEY2FW(mac, index);
8164         bwn_shm_write_2(mac, BWN_SHARED,
8165             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8166
8167         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8168         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8169                 value = key[i];
8170                 value |= (uint16_t)(key[i + 1]) << 8;
8171                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8172         }
8173 }
8174
8175 static void
8176 bwn_phy_exit(struct bwn_mac *mac)
8177 {
8178
8179         mac->mac_phy.rf_onoff(mac, 0);
8180         if (mac->mac_phy.exit != NULL)
8181                 mac->mac_phy.exit(mac);
8182 }
8183
8184 static void
8185 bwn_dma_free(struct bwn_mac *mac)
8186 {
8187         struct bwn_dma *dma;
8188
8189         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8190                 return;
8191         dma = &mac->mac_method.dma;
8192
8193         bwn_dma_ringfree(&dma->rx);
8194         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8195         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8196         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8197         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8198         bwn_dma_ringfree(&dma->mcast);
8199 }
8200
8201 static void
8202 bwn_core_stop(struct bwn_mac *mac)
8203 {
8204         struct bwn_softc *sc = mac->mac_sc;
8205
8206         BWN_ASSERT_LOCKED(sc);
8207
8208         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8209                 return;
8210
8211         callout_stop(&sc->sc_rfswitch_ch);
8212         callout_stop(&sc->sc_task_ch);
8213         callout_stop(&sc->sc_watchdog_ch);
8214         sc->sc_watchdog_timer = 0;
8215         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8216         BWN_READ_4(mac, BWN_INTR_MASK);
8217         bwn_mac_suspend(mac);
8218
8219         mac->mac_status = BWN_MAC_STATUS_INITED;
8220 }
8221
8222 static int
8223 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8224 {
8225         struct bwn_mac *up_dev = NULL;
8226         struct bwn_mac *down_dev;
8227         struct bwn_mac *mac;
8228         int err, status;
8229         uint8_t gmode;
8230
8231         BWN_ASSERT_LOCKED(sc);
8232
8233         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8234                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8235                     mac->mac_phy.supports_2ghz) {
8236                         up_dev = mac;
8237                         gmode = 1;
8238                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8239                     mac->mac_phy.supports_5ghz) {
8240                         up_dev = mac;
8241                         gmode = 0;
8242                 } else {
8243                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8244                         return (EINVAL);
8245                 }
8246                 if (up_dev != NULL)
8247                         break;
8248         }
8249         if (up_dev == NULL) {
8250                 device_printf(sc->sc_dev, "Could not find a device\n");
8251                 return (ENODEV);
8252         }
8253         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8254                 return (0);
8255
8256         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8257             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8258
8259         down_dev = sc->sc_curmac;
8260         status = down_dev->mac_status;
8261         if (status >= BWN_MAC_STATUS_STARTED)
8262                 bwn_core_stop(down_dev);
8263         if (status >= BWN_MAC_STATUS_INITED)
8264                 bwn_core_exit(down_dev);
8265
8266         if (down_dev != up_dev)
8267                 bwn_phy_reset(down_dev);
8268
8269         up_dev->mac_phy.gmode = gmode;
8270         if (status >= BWN_MAC_STATUS_INITED) {
8271                 err = bwn_core_init(up_dev);
8272                 if (err) {
8273                         device_printf(sc->sc_dev,
8274                             "fatal: failed to initialize for %s-GHz\n",
8275                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8276                         goto fail;
8277                 }
8278         }
8279         if (status >= BWN_MAC_STATUS_STARTED)
8280                 bwn_core_start(up_dev);
8281         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8282         sc->sc_curmac = up_dev;
8283
8284         return (0);
8285 fail:
8286         sc->sc_curmac = NULL;
8287         return (err);
8288 }
8289
8290 static void
8291 bwn_rf_turnon(struct bwn_mac *mac)
8292 {
8293
8294         bwn_mac_suspend(mac);
8295         mac->mac_phy.rf_onoff(mac, 1);
8296         mac->mac_phy.rf_on = 1;
8297         bwn_mac_enable(mac);
8298 }
8299
8300 static void
8301 bwn_rf_turnoff(struct bwn_mac *mac)
8302 {
8303
8304         bwn_mac_suspend(mac);
8305         mac->mac_phy.rf_onoff(mac, 0);
8306         mac->mac_phy.rf_on = 0;
8307         bwn_mac_enable(mac);
8308 }
8309
8310 static void
8311 bwn_phy_reset(struct bwn_mac *mac)
8312 {
8313         struct bwn_softc *sc = mac->mac_sc;
8314
8315         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8316             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8317              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8318         DELAY(1000);
8319         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8320             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8321             BWN_TGSLOW_PHYRESET);
8322         DELAY(1000);
8323 }
8324
8325 static int
8326 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8327 {
8328         struct bwn_vap *bvp = BWN_VAP(vap);
8329         struct ieee80211com *ic= vap->iv_ic;
8330         struct ifnet *ifp = ic->ic_ifp;
8331         enum ieee80211_state ostate = vap->iv_state;
8332         struct bwn_softc *sc = ifp->if_softc;
8333         struct bwn_mac *mac = sc->sc_curmac;
8334         int error;
8335
8336         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8337             ieee80211_state_name[vap->iv_state],
8338             ieee80211_state_name[nstate]);
8339
8340         error = bvp->bv_newstate(vap, nstate, arg);
8341         if (error != 0)
8342                 return (error);
8343
8344         BWN_LOCK(sc);
8345
8346         bwn_led_newstate(mac, nstate);
8347
8348         /*
8349          * Clear the BSSID when we stop a STA
8350          */
8351         if (vap->iv_opmode == IEEE80211_M_STA) {
8352                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8353                         /*
8354                          * Clear out the BSSID.  If we reassociate to
8355                          * the same AP, this will reinialize things
8356                          * correctly...
8357                          */
8358                         if (ic->ic_opmode == IEEE80211_M_STA &&
8359                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8360                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8361                                 bwn_set_macaddr(mac);
8362                         }
8363                 }
8364         }
8365
8366         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8367             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8368                 /* XXX nothing to do? */
8369         } else if (nstate == IEEE80211_S_RUN) {
8370                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8371                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8372                 bwn_set_opmode(mac);
8373                 bwn_set_pretbtt(mac);
8374                 bwn_spu_setdelay(mac, 0);
8375                 bwn_set_macaddr(mac);
8376         }
8377
8378         BWN_UNLOCK(sc);
8379
8380         return (error);
8381 }
8382
8383 static void
8384 bwn_set_pretbtt(struct bwn_mac *mac)
8385 {
8386         struct bwn_softc *sc = mac->mac_sc;
8387         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8388         uint16_t pretbtt;
8389
8390         if (ic->ic_opmode == IEEE80211_M_IBSS)
8391                 pretbtt = 2;
8392         else
8393                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8394         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8395         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8396 }
8397
8398 static int
8399 bwn_intr(void *arg)
8400 {
8401         struct bwn_mac *mac = arg;
8402         struct bwn_softc *sc = mac->mac_sc;
8403         uint32_t reason;
8404
8405         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8406             (sc->sc_flags & BWN_FLAG_INVALID))
8407                 return (FILTER_STRAY);
8408
8409         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8410         if (reason == 0xffffffff)       /* shared IRQ */
8411                 return (FILTER_STRAY);
8412         reason &= mac->mac_intr_mask;
8413         if (reason == 0)
8414                 return (FILTER_HANDLED);
8415
8416         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8417         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8418         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8419         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8420         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8421         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8422         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8423         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8424         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8425         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8426         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8427
8428         /* Disable interrupts. */
8429         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8430
8431         mac->mac_reason_intr = reason;
8432
8433         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8434         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8435
8436         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8437         return (FILTER_HANDLED);
8438 }
8439
8440 static void
8441 bwn_intrtask(void *arg, int npending)
8442 {
8443         struct bwn_mac *mac = arg;
8444         struct bwn_softc *sc = mac->mac_sc;
8445         struct ifnet *ifp = sc->sc_ifp;
8446         uint32_t merged = 0;
8447         int i, tx = 0, rx = 0;
8448
8449         BWN_LOCK(sc);
8450         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8451             (sc->sc_flags & BWN_FLAG_INVALID)) {
8452                 BWN_UNLOCK(sc);
8453                 return;
8454         }
8455
8456         for (i = 0; i < N(mac->mac_reason); i++)
8457                 merged |= mac->mac_reason[i];
8458
8459         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8460                 device_printf(sc->sc_dev, "MAC trans error\n");
8461
8462         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8463                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8464                 mac->mac_phy.txerrors--;
8465                 if (mac->mac_phy.txerrors == 0) {
8466                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8467                         bwn_restart(mac, "PHY TX errors");
8468                 }
8469         }
8470
8471         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8472                 if (merged & BWN_DMAINTR_FATALMASK) {
8473                         device_printf(sc->sc_dev,
8474                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8475                             mac->mac_reason[0], mac->mac_reason[1],
8476                             mac->mac_reason[2], mac->mac_reason[3],
8477                             mac->mac_reason[4], mac->mac_reason[5]);
8478                         bwn_restart(mac, "DMA error");
8479                         BWN_UNLOCK(sc);
8480                         return;
8481                 }
8482                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8483                         device_printf(sc->sc_dev,
8484                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8485                             mac->mac_reason[0], mac->mac_reason[1],
8486                             mac->mac_reason[2], mac->mac_reason[3],
8487                             mac->mac_reason[4], mac->mac_reason[5]);
8488                 }
8489         }
8490
8491         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8492                 bwn_intr_ucode_debug(mac);
8493         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8494                 bwn_intr_tbtt_indication(mac);
8495         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8496                 bwn_intr_atim_end(mac);
8497         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8498                 bwn_intr_beacon(mac);
8499         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8500                 bwn_intr_pmq(mac);
8501         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8502                 bwn_intr_noise(mac);
8503
8504         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8505                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8506                         bwn_dma_rx(mac->mac_method.dma.rx);
8507                         rx = 1;
8508                 }
8509         } else
8510                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8511
8512         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8513         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8514         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8515         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517
8518         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8519                 bwn_intr_txeof(mac);
8520                 tx = 1;
8521         }
8522
8523         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8524
8525         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8526                 int evt = BWN_LED_EVENT_NONE;
8527
8528                 if (tx && rx) {
8529                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8530                                 evt = BWN_LED_EVENT_RX;
8531                         else
8532                                 evt = BWN_LED_EVENT_TX;
8533                 } else if (tx) {
8534                         evt = BWN_LED_EVENT_TX;
8535                 } else if (rx) {
8536                         evt = BWN_LED_EVENT_RX;
8537                 } else if (rx == 0) {
8538                         evt = BWN_LED_EVENT_POLL;
8539                 }
8540
8541                 if (evt != BWN_LED_EVENT_NONE)
8542                         bwn_led_event(mac, evt);
8543        }
8544
8545         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8546                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8547                         bwn_start_locked(ifp);
8548         }
8549
8550         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8551         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8552
8553         BWN_UNLOCK(sc);
8554 }
8555
8556 static void
8557 bwn_restart(struct bwn_mac *mac, const char *msg)
8558 {
8559         struct bwn_softc *sc = mac->mac_sc;
8560         struct ifnet *ifp = sc->sc_ifp;
8561         struct ieee80211com *ic = ifp->if_l2com;
8562
8563         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8564                 return;
8565
8566         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8567         ieee80211_runtask(ic, &mac->mac_hwreset);
8568 }
8569
8570 static void
8571 bwn_intr_ucode_debug(struct bwn_mac *mac)
8572 {
8573         struct bwn_softc *sc = mac->mac_sc;
8574         uint16_t reason;
8575
8576         if (mac->mac_fw.opensource == 0)
8577                 return;
8578
8579         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8580         switch (reason) {
8581         case BWN_DEBUGINTR_PANIC:
8582                 bwn_handle_fwpanic(mac);
8583                 break;
8584         case BWN_DEBUGINTR_DUMP_SHM:
8585                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8586                 break;
8587         case BWN_DEBUGINTR_DUMP_REGS:
8588                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8589                 break;
8590         case BWN_DEBUGINTR_MARKER:
8591                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8592                 break;
8593         default:
8594                 device_printf(sc->sc_dev,
8595                     "ucode debug unknown reason: %#x\n", reason);
8596         }
8597
8598         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8599             BWN_DEBUGINTR_ACK);
8600 }
8601
8602 static void
8603 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8604 {
8605         struct bwn_softc *sc = mac->mac_sc;
8606         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8607
8608         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8609                 bwn_psctl(mac, 0);
8610         if (ic->ic_opmode == IEEE80211_M_IBSS)
8611                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8612 }
8613
8614 static void
8615 bwn_intr_atim_end(struct bwn_mac *mac)
8616 {
8617
8618         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8619                 BWN_WRITE_4(mac, BWN_MACCMD,
8620                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8621                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8622         }
8623 }
8624
8625 static void
8626 bwn_intr_beacon(struct bwn_mac *mac)
8627 {
8628         struct bwn_softc *sc = mac->mac_sc;
8629         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8630         uint32_t cmd, beacon0, beacon1;
8631
8632         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8633             ic->ic_opmode == IEEE80211_M_MBSS)
8634                 return;
8635
8636         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8637
8638         cmd = BWN_READ_4(mac, BWN_MACCMD);
8639         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8640         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8641
8642         if (beacon0 && beacon1) {
8643                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8644                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8645                 return;
8646         }
8647
8648         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8649                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8650                 bwn_load_beacon0(mac);
8651                 bwn_load_beacon1(mac);
8652                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8653                 cmd |= BWN_MACCMD_BEACON0_VALID;
8654                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8655         } else {
8656                 if (!beacon0) {
8657                         bwn_load_beacon0(mac);
8658                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8659                         cmd |= BWN_MACCMD_BEACON0_VALID;
8660                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8661                 } else if (!beacon1) {
8662                         bwn_load_beacon1(mac);
8663                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8664                         cmd |= BWN_MACCMD_BEACON1_VALID;
8665                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8666                 }
8667         }
8668 }
8669
8670 static void
8671 bwn_intr_pmq(struct bwn_mac *mac)
8672 {
8673         uint32_t tmp;
8674
8675         while (1) {
8676                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8677                 if (!(tmp & 0x00000008))
8678                         break;
8679         }
8680         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8681 }
8682
8683 static void
8684 bwn_intr_noise(struct bwn_mac *mac)
8685 {
8686         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8687         uint16_t tmp;
8688         uint8_t noise[4];
8689         uint8_t i, j;
8690         int32_t average;
8691
8692         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8693                 return;
8694
8695         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8696         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8697         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8698             noise[3] == 0x7f)
8699                 goto new;
8700
8701         KASSERT(mac->mac_noise.noi_nsamples < 8,
8702             ("%s:%d: fail", __func__, __LINE__));
8703         i = mac->mac_noise.noi_nsamples;
8704         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8705         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8706         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8707         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8708         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8709         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8710         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8711         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8712         mac->mac_noise.noi_nsamples++;
8713         if (mac->mac_noise.noi_nsamples == 8) {
8714                 average = 0;
8715                 for (i = 0; i < 8; i++) {
8716                         for (j = 0; j < 4; j++)
8717                                 average += mac->mac_noise.noi_samples[i][j];
8718                 }
8719                 average = (((average / 32) * 125) + 64) / 128;
8720                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8721                 if (tmp >= 8)
8722                         average += 2;
8723                 else
8724                         average -= 25;
8725                 average -= (tmp == 8) ? 72 : 48;
8726
8727                 mac->mac_stats.link_noise = average;
8728                 mac->mac_noise.noi_running = 0;
8729                 return;
8730         }
8731 new:
8732         bwn_noise_gensample(mac);
8733 }
8734
8735 static int
8736 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8737 {
8738         struct bwn_mac *mac = prq->prq_mac;
8739         struct bwn_softc *sc = mac->mac_sc;
8740         unsigned int i;
8741
8742         BWN_ASSERT_LOCKED(sc);
8743
8744         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8745                 return (0);
8746
8747         for (i = 0; i < 5000; i++) {
8748                 if (bwn_pio_rxeof(prq) == 0)
8749                         break;
8750         }
8751         if (i >= 5000)
8752                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8753         return ((i > 0) ? 1 : 0);
8754 }
8755
8756 static void
8757 bwn_dma_rx(struct bwn_dma_ring *dr)
8758 {
8759         int slot, curslot;
8760
8761         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8762         curslot = dr->get_curslot(dr);
8763         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8764             ("%s:%d: fail", __func__, __LINE__));
8765
8766         slot = dr->dr_curslot;
8767         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8768                 bwn_dma_rxeof(dr, &slot);
8769
8770         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8771             BUS_DMASYNC_PREWRITE);
8772
8773         dr->set_curslot(dr, slot);
8774         dr->dr_curslot = slot;
8775 }
8776
8777 static void
8778 bwn_intr_txeof(struct bwn_mac *mac)
8779 {
8780         struct bwn_txstatus stat;
8781         uint32_t stat0, stat1;
8782         uint16_t tmp;
8783
8784         BWN_ASSERT_LOCKED(mac->mac_sc);
8785
8786         while (1) {
8787                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8788                 if (!(stat0 & 0x00000001))
8789                         break;
8790                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8791
8792                 stat.cookie = (stat0 >> 16);
8793                 stat.seq = (stat1 & 0x0000ffff);
8794                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8795                 tmp = (stat0 & 0x0000ffff);
8796                 stat.framecnt = ((tmp & 0xf000) >> 12);
8797                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8798                 stat.sreason = ((tmp & 0x001c) >> 2);
8799                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8800                 stat.im = (tmp & 0x0040) ? 1 : 0;
8801                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8802                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8803
8804                 bwn_handle_txeof(mac, &stat);
8805         }
8806 }
8807
8808 static void
8809 bwn_hwreset(void *arg, int npending)
8810 {
8811         struct bwn_mac *mac = arg;
8812         struct bwn_softc *sc = mac->mac_sc;
8813         int error = 0;
8814         int prev_status;
8815
8816         BWN_LOCK(sc);
8817
8818         prev_status = mac->mac_status;
8819         if (prev_status >= BWN_MAC_STATUS_STARTED)
8820                 bwn_core_stop(mac);
8821         if (prev_status >= BWN_MAC_STATUS_INITED)
8822                 bwn_core_exit(mac);
8823
8824         if (prev_status >= BWN_MAC_STATUS_INITED) {
8825                 error = bwn_core_init(mac);
8826                 if (error)
8827                         goto out;
8828         }
8829         if (prev_status >= BWN_MAC_STATUS_STARTED)
8830                 bwn_core_start(mac);
8831 out:
8832         if (error) {
8833                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8834                 sc->sc_curmac = NULL;
8835         }
8836         BWN_UNLOCK(sc);
8837 }
8838
8839 static void
8840 bwn_handle_fwpanic(struct bwn_mac *mac)
8841 {
8842         struct bwn_softc *sc = mac->mac_sc;
8843         uint16_t reason;
8844
8845         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8846         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8847
8848         if (reason == BWN_FWPANIC_RESTART)
8849                 bwn_restart(mac, "ucode panic");
8850 }
8851
8852 static void
8853 bwn_load_beacon0(struct bwn_mac *mac)
8854 {
8855
8856         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8857 }
8858
8859 static void
8860 bwn_load_beacon1(struct bwn_mac *mac)
8861 {
8862
8863         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8864 }
8865
8866 static uint32_t
8867 bwn_jssi_read(struct bwn_mac *mac)
8868 {
8869         uint32_t val = 0;
8870
8871         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8872         val <<= 16;
8873         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8874
8875         return (val);
8876 }
8877
8878 static void
8879 bwn_noise_gensample(struct bwn_mac *mac)
8880 {
8881         uint32_t jssi = 0x7f7f7f7f;
8882
8883         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8884         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8885         BWN_WRITE_4(mac, BWN_MACCMD,
8886             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8887 }
8888
8889 static int
8890 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8891 {
8892         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8893
8894         return (dr->dr_numslots - dr->dr_usedslot);
8895 }
8896
8897 static int
8898 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8899 {
8900         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8901
8902         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8903             ("%s:%d: fail", __func__, __LINE__));
8904         if (slot == dr->dr_numslots - 1)
8905                 return (0);
8906         return (slot + 1);
8907 }
8908
8909 static void
8910 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8911 {
8912         struct bwn_mac *mac = dr->dr_mac;
8913         struct bwn_softc *sc = mac->mac_sc;
8914         struct bwn_dma *dma = &mac->mac_method.dma;
8915         struct bwn_dmadesc_generic *desc;
8916         struct bwn_dmadesc_meta *meta;
8917         struct bwn_rxhdr4 *rxhdr;
8918         struct ifnet *ifp = sc->sc_ifp;
8919         struct mbuf *m;
8920         uint32_t macstat;
8921         int32_t tmp;
8922         int cnt = 0;
8923         uint16_t len;
8924
8925         dr->getdesc(dr, *slot, &desc, &meta);
8926
8927         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8928         m = meta->mt_m;
8929
8930         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8931                 ifp->if_ierrors++;
8932                 return;
8933         }
8934
8935         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8936         len = le16toh(rxhdr->frame_len);
8937         if (len <= 0) {
8938                 ifp->if_ierrors++;
8939                 return;
8940         }
8941         if (bwn_dma_check_redzone(dr, m)) {
8942                 device_printf(sc->sc_dev, "redzone error.\n");
8943                 bwn_dma_set_redzone(dr, m);
8944                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8945                     BUS_DMASYNC_PREWRITE);
8946                 return;
8947         }
8948         if (len > dr->dr_rx_bufsize) {
8949                 tmp = len;
8950                 while (1) {
8951                         dr->getdesc(dr, *slot, &desc, &meta);
8952                         bwn_dma_set_redzone(dr, meta->mt_m);
8953                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8954                             BUS_DMASYNC_PREWRITE);
8955                         *slot = bwn_dma_nextslot(dr, *slot);
8956                         cnt++;
8957                         tmp -= dr->dr_rx_bufsize;
8958                         if (tmp <= 0)
8959                                 break;
8960                 }
8961                 device_printf(sc->sc_dev, "too small buffer "
8962                        "(len %u buffer %u dropped %d)\n",
8963                        len, dr->dr_rx_bufsize, cnt);
8964                 return;
8965         }
8966         macstat = le32toh(rxhdr->mac_status);
8967         if (macstat & BWN_RX_MAC_FCSERR) {
8968                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8969                         device_printf(sc->sc_dev, "RX drop\n");
8970                         return;
8971                 }
8972         }
8973
8974         m->m_pkthdr.rcvif = ifp;
8975         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8976         m_adj(m, dr->dr_frameoffset);
8977
8978         bwn_rxeof(dr->dr_mac, m, rxhdr);
8979 }
8980
8981 static void
8982 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8983 {
8984         struct bwn_dma_ring *dr;
8985         struct bwn_dmadesc_generic *desc;
8986         struct bwn_dmadesc_meta *meta;
8987         struct bwn_pio_txqueue *tq;
8988         struct bwn_pio_txpkt *tp = NULL;
8989         struct bwn_softc *sc = mac->mac_sc;
8990         struct bwn_stats *stats = &mac->mac_stats;
8991         struct ieee80211_node *ni;
8992         struct ieee80211vap *vap;
8993         int retrycnt = 0, slot;
8994
8995         BWN_ASSERT_LOCKED(mac->mac_sc);
8996
8997         if (status->im)
8998                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8999         if (status->ampdu)
9000                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9001         if (status->rtscnt) {
9002                 if (status->rtscnt == 0xf)
9003                         stats->rtsfail++;
9004                 else
9005                         stats->rts++;
9006         }
9007
9008         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9009                 if (status->ack) {
9010                         dr = bwn_dma_parse_cookie(mac, status,
9011                             status->cookie, &slot);
9012                         if (dr == NULL) {
9013                                 device_printf(sc->sc_dev,
9014                                     "failed to parse cookie\n");
9015                                 return;
9016                         }
9017                         while (1) {
9018                                 dr->getdesc(dr, slot, &desc, &meta);
9019                                 if (meta->mt_islast) {
9020                                         ni = meta->mt_ni;
9021                                         vap = ni->ni_vap;
9022                                         ieee80211_ratectl_tx_complete(vap, ni,
9023                                             status->ack ?
9024                                               IEEE80211_RATECTL_TX_SUCCESS :
9025                                               IEEE80211_RATECTL_TX_FAILURE,
9026                                             &retrycnt, 0);
9027                                         break;
9028                                 }
9029                                 slot = bwn_dma_nextslot(dr, slot);
9030                         }
9031                 }
9032                 bwn_dma_handle_txeof(mac, status);
9033         } else {
9034                 if (status->ack) {
9035                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9036                         if (tq == NULL) {
9037                                 device_printf(sc->sc_dev,
9038                                     "failed to parse cookie\n");
9039                                 return;
9040                         }
9041                         ni = tp->tp_ni;
9042                         vap = ni->ni_vap;
9043                         ieee80211_ratectl_tx_complete(vap, ni,
9044                             status->ack ?
9045                               IEEE80211_RATECTL_TX_SUCCESS :
9046                               IEEE80211_RATECTL_TX_FAILURE,
9047                             &retrycnt, 0);
9048                 }
9049                 bwn_pio_handle_txeof(mac, status);
9050         }
9051
9052         bwn_phy_txpower_check(mac, 0);
9053 }
9054
9055 static uint8_t
9056 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9057 {
9058         struct bwn_mac *mac = prq->prq_mac;
9059         struct bwn_softc *sc = mac->mac_sc;
9060         struct bwn_rxhdr4 rxhdr;
9061         struct ifnet *ifp = sc->sc_ifp;
9062         struct mbuf *m;
9063         uint32_t ctl32, macstat, v32;
9064         unsigned int i, padding;
9065         uint16_t ctl16, len, totlen, v16;
9066         unsigned char *mp;
9067         char *data;
9068
9069         memset(&rxhdr, 0, sizeof(rxhdr));
9070
9071         if (prq->prq_rev >= 8) {
9072                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9073                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9074                         return (0);
9075                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9076                     BWN_PIO8_RXCTL_FRAMEREADY);
9077                 for (i = 0; i < 10; i++) {
9078                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9079                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9080                                 goto ready;
9081                         DELAY(10);
9082                 }
9083         } else {
9084                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9085                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9086                         return (0);
9087                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9088                     BWN_PIO_RXCTL_FRAMEREADY);
9089                 for (i = 0; i < 10; i++) {
9090                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9091                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9092                                 goto ready;
9093                         DELAY(10);
9094                 }
9095         }
9096         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9097         return (1);
9098 ready:
9099         if (prq->prq_rev >= 8)
9100                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9101                     prq->prq_base + BWN_PIO8_RXDATA);
9102         else
9103                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9104                     prq->prq_base + BWN_PIO_RXDATA);
9105         len = le16toh(rxhdr.frame_len);
9106         if (len > 0x700) {
9107                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9108                 goto error;
9109         }
9110         if (len == 0) {
9111                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9112                 goto error;
9113         }
9114
9115         macstat = le32toh(rxhdr.mac_status);
9116         if (macstat & BWN_RX_MAC_FCSERR) {
9117                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9118                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9119                         goto error;
9120                 }
9121         }
9122
9123         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9124         totlen = len + padding;
9125         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9126         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9127         if (m == NULL) {
9128                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9129                 goto error;
9130         }
9131         mp = mtod(m, unsigned char *);
9132         if (prq->prq_rev >= 8) {
9133                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9134                     prq->prq_base + BWN_PIO8_RXDATA);
9135                 if (totlen & 3) {
9136                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9137                         data = &(mp[totlen - 1]);
9138                         switch (totlen & 3) {
9139                         case 3:
9140                                 *data = (v32 >> 16);
9141                                 data--;
9142                         case 2:
9143                                 *data = (v32 >> 8);
9144                                 data--;
9145                         case 1:
9146                                 *data = v32;
9147                         }
9148                 }
9149         } else {
9150                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9151                     prq->prq_base + BWN_PIO_RXDATA);
9152                 if (totlen & 1) {
9153                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9154                         mp[totlen - 1] = v16;
9155                 }
9156         }
9157
9158         m->m_pkthdr.rcvif = ifp;
9159         m->m_len = m->m_pkthdr.len = totlen;
9160
9161         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9162
9163         return (1);
9164 error:
9165         if (prq->prq_rev >= 8)
9166                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9167                     BWN_PIO8_RXCTL_DATAREADY);
9168         else
9169                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9170         return (1);
9171 }
9172
9173 static int
9174 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9175     struct bwn_dmadesc_meta *meta, int init)
9176 {
9177         struct bwn_mac *mac = dr->dr_mac;
9178         struct bwn_dma *dma = &mac->mac_method.dma;
9179         struct bwn_rxhdr4 *hdr;
9180         bus_dmamap_t map;
9181         bus_addr_t paddr;
9182         struct mbuf *m;
9183         int error;
9184
9185         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9186         if (m == NULL) {
9187                 error = ENOBUFS;
9188
9189                 /*
9190                  * If the NIC is up and running, we need to:
9191                  * - Clear RX buffer's header.
9192                  * - Restore RX descriptor settings.
9193                  */
9194                 if (init)
9195                         return (error);
9196                 else
9197                         goto back;
9198         }
9199         m->m_len = m->m_pkthdr.len = MCLBYTES;
9200
9201         bwn_dma_set_redzone(dr, m);
9202
9203         /*
9204          * Try to load RX buf into temporary DMA map
9205          */
9206         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9207             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9208         if (error) {
9209                 m_freem(m);
9210
9211                 /*
9212                  * See the comment above
9213                  */
9214                 if (init)
9215                         return (error);
9216                 else
9217                         goto back;
9218         }
9219
9220         if (!init)
9221                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9222         meta->mt_m = m;
9223         meta->mt_paddr = paddr;
9224
9225         /*
9226          * Swap RX buf's DMA map with the loaded temporary one
9227          */
9228         map = meta->mt_dmap;
9229         meta->mt_dmap = dr->dr_spare_dmap;
9230         dr->dr_spare_dmap = map;
9231
9232 back:
9233         /*
9234          * Clear RX buf header
9235          */
9236         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9237         bzero(hdr, sizeof(*hdr));
9238         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9239             BUS_DMASYNC_PREWRITE);
9240
9241         /*
9242          * Setup RX buf descriptor
9243          */
9244         dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9245             sizeof(*hdr), 0, 0, 0);
9246         return (error);
9247 }
9248
9249 static void
9250 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9251                  bus_size_t mapsz __unused, int error)
9252 {
9253
9254         if (!error) {
9255                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9256                 *((bus_addr_t *)arg) = seg->ds_addr;
9257         }
9258 }
9259
9260 static int
9261 bwn_hwrate2ieeerate(int rate)
9262 {
9263
9264         switch (rate) {
9265         case BWN_CCK_RATE_1MB:
9266                 return (2);
9267         case BWN_CCK_RATE_2MB:
9268                 return (4);
9269         case BWN_CCK_RATE_5MB:
9270                 return (11);
9271         case BWN_CCK_RATE_11MB:
9272                 return (22);
9273         case BWN_OFDM_RATE_6MB:
9274                 return (12);
9275         case BWN_OFDM_RATE_9MB:
9276                 return (18);
9277         case BWN_OFDM_RATE_12MB:
9278                 return (24);
9279         case BWN_OFDM_RATE_18MB:
9280                 return (36);
9281         case BWN_OFDM_RATE_24MB:
9282                 return (48);
9283         case BWN_OFDM_RATE_36MB:
9284                 return (72);
9285         case BWN_OFDM_RATE_48MB:
9286                 return (96);
9287         case BWN_OFDM_RATE_54MB:
9288                 return (108);
9289         default:
9290                 printf("Ooops\n");
9291                 return (0);
9292         }
9293 }
9294
9295 static void
9296 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9297 {
9298         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9299         struct bwn_plcp6 *plcp;
9300         struct bwn_softc *sc = mac->mac_sc;
9301         struct ieee80211_frame_min *wh;
9302         struct ieee80211_node *ni;
9303         struct ifnet *ifp = sc->sc_ifp;
9304         struct ieee80211com *ic = ifp->if_l2com;
9305         uint32_t macstat;
9306         int padding, rate, rssi = 0, noise = 0, type;
9307         uint16_t phytype, phystat0, phystat3, chanstat;
9308         unsigned char *mp = mtod(m, unsigned char *);
9309         static int rx_mac_dec_rpt = 0;
9310
9311         BWN_ASSERT_LOCKED(sc);
9312
9313         phystat0 = le16toh(rxhdr->phy_status0);
9314         phystat3 = le16toh(rxhdr->phy_status3);
9315         macstat = le32toh(rxhdr->mac_status);
9316         chanstat = le16toh(rxhdr->channel);
9317         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9318
9319         if (macstat & BWN_RX_MAC_FCSERR)
9320                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9321         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9322                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9323         if (macstat & BWN_RX_MAC_DECERR)
9324                 goto drop;
9325
9326         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9327         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9328                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9329                     m->m_pkthdr.len);
9330                 goto drop;
9331         }
9332         plcp = (struct bwn_plcp6 *)(mp + padding);
9333         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9334         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9335                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9336                     m->m_pkthdr.len);
9337                 goto drop;
9338         }
9339         wh = mtod(m, struct ieee80211_frame_min *);
9340
9341         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9342                 device_printf(sc->sc_dev,
9343                     "RX decryption attempted (old %d keyidx %#x)\n",
9344                     BWN_ISOLDFMT(mac),
9345                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9346
9347         /* XXX calculating RSSI & noise & antenna */
9348
9349         if (phystat0 & BWN_RX_PHYST0_OFDM)
9350                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9351                     phytype == BWN_PHYTYPE_A);
9352         else
9353                 rate = bwn_plcp_get_cckrate(mac, plcp);
9354         if (rate == -1) {
9355                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9356                         goto drop;
9357         }
9358         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9359
9360         /* RX radio tap */
9361         if (ieee80211_radiotap_active(ic))
9362                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9363         m_adj(m, -IEEE80211_CRC_LEN);
9364
9365         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9366         noise = mac->mac_stats.link_noise;
9367
9368         ifp->if_ipackets++;
9369
9370         BWN_UNLOCK(sc);
9371
9372         ni = ieee80211_find_rxnode(ic, wh);
9373         if (ni != NULL) {
9374                 type = ieee80211_input(ni, m, rssi, noise);
9375                 ieee80211_free_node(ni);
9376         } else
9377                 type = ieee80211_input_all(ic, m, rssi, noise);
9378
9379         BWN_LOCK(sc);
9380         return;
9381 drop:
9382         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9383 }
9384
9385 static void
9386 bwn_dma_handle_txeof(struct bwn_mac *mac,
9387     const struct bwn_txstatus *status)
9388 {
9389         struct bwn_dma *dma = &mac->mac_method.dma;
9390         struct bwn_dma_ring *dr;
9391         struct bwn_dmadesc_generic *desc;
9392         struct bwn_dmadesc_meta *meta;
9393         struct bwn_softc *sc = mac->mac_sc;
9394         struct ieee80211_node *ni;
9395         struct ifnet *ifp = sc->sc_ifp;
9396         struct mbuf *m;
9397         int slot;
9398
9399         BWN_ASSERT_LOCKED(sc);
9400
9401         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9402         if (dr == NULL) {
9403                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9404                 return;
9405         }
9406         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9407
9408         while (1) {
9409                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9410                     ("%s:%d: fail", __func__, __LINE__));
9411                 dr->getdesc(dr, slot, &desc, &meta);
9412
9413                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9414                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9415                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9416                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9417
9418                 if (meta->mt_islast) {
9419                         KASSERT(meta->mt_m != NULL,
9420                             ("%s:%d: fail", __func__, __LINE__));
9421
9422                         ni = meta->mt_ni;
9423                         m = meta->mt_m;
9424                         if (ni != NULL) {
9425                                 /*
9426                                  * Do any tx complete callback. Note this must
9427                                  * be done before releasing the node reference.
9428                                  */
9429                                 if (m->m_flags & M_TXCB)
9430                                         ieee80211_process_callback(ni, m, 0);
9431                                 ieee80211_free_node(ni);
9432                                 meta->mt_ni = NULL;
9433                         }
9434                         m_freem(m);
9435                         meta->mt_m = NULL;
9436                 } else {
9437                         KASSERT(meta->mt_m == NULL,
9438                             ("%s:%d: fail", __func__, __LINE__));
9439                 }
9440
9441                 dr->dr_usedslot--;
9442                 if (meta->mt_islast) {
9443                         ifp->if_opackets++;
9444                         break;
9445                 }
9446                 slot = bwn_dma_nextslot(dr, slot);
9447         }
9448         sc->sc_watchdog_timer = 0;
9449         if (dr->dr_stop) {
9450                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9451                     ("%s:%d: fail", __func__, __LINE__));
9452                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9453                 dr->dr_stop = 0;
9454         }
9455 }
9456
9457 static void
9458 bwn_pio_handle_txeof(struct bwn_mac *mac,
9459     const struct bwn_txstatus *status)
9460 {
9461         struct bwn_pio_txqueue *tq;
9462         struct bwn_pio_txpkt *tp = NULL;
9463         struct bwn_softc *sc = mac->mac_sc;
9464         struct ifnet *ifp = sc->sc_ifp;
9465
9466         BWN_ASSERT_LOCKED(sc);
9467
9468         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9469         if (tq == NULL)
9470                 return;
9471
9472         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9473         tq->tq_free++;
9474
9475         if (tp->tp_ni != NULL) {
9476                 /*
9477                  * Do any tx complete callback.  Note this must
9478                  * be done before releasing the node reference.
9479                  */
9480                 if (tp->tp_m->m_flags & M_TXCB)
9481                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9482                 ieee80211_free_node(tp->tp_ni);
9483                 tp->tp_ni = NULL;
9484         }
9485         m_freem(tp->tp_m);
9486         tp->tp_m = NULL;
9487         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9488
9489         ifp->if_opackets++;
9490
9491         sc->sc_watchdog_timer = 0;
9492         if (tq->tq_stop) {
9493                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9494                 tq->tq_stop = 0;
9495         }
9496 }
9497
9498 static void
9499 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9500 {
9501         struct bwn_softc *sc = mac->mac_sc;
9502         struct bwn_phy *phy = &mac->mac_phy;
9503         struct ifnet *ifp = sc->sc_ifp;
9504         struct ieee80211com *ic = ifp->if_l2com;
9505         unsigned long now;
9506         int result;
9507
9508         BWN_GETTIME(now);
9509
9510         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9511                 return;
9512         phy->nexttime = now + 2 * 1000;
9513
9514         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9515             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9516                 return;
9517
9518         if (phy->recalc_txpwr != NULL) {
9519                 result = phy->recalc_txpwr(mac,
9520                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9521                 if (result == BWN_TXPWR_RES_DONE)
9522                         return;
9523                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9524                     ("%s: fail", __func__));
9525                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9526
9527                 ieee80211_runtask(ic, &mac->mac_txpower);
9528         }
9529 }
9530
9531 static uint16_t
9532 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9533 {
9534
9535         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9536 }
9537
9538 static uint32_t
9539 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9540 {
9541
9542         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9543 }
9544
9545 static void
9546 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9547 {
9548
9549         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9550 }
9551
9552 static void
9553 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9554 {
9555
9556         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9557 }
9558
9559 static int
9560 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9561 {
9562
9563         switch (rate) {
9564         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9565         case 12:
9566                 return (BWN_OFDM_RATE_6MB);
9567         case 18:
9568                 return (BWN_OFDM_RATE_9MB);
9569         case 24:
9570                 return (BWN_OFDM_RATE_12MB);
9571         case 36:
9572                 return (BWN_OFDM_RATE_18MB);
9573         case 48:
9574                 return (BWN_OFDM_RATE_24MB);
9575         case 72:
9576                 return (BWN_OFDM_RATE_36MB);
9577         case 96:
9578                 return (BWN_OFDM_RATE_48MB);
9579         case 108:
9580                 return (BWN_OFDM_RATE_54MB);
9581         /* CCK rates (NB: not IEEE std, device-specific) */
9582         case 2:
9583                 return (BWN_CCK_RATE_1MB);
9584         case 4:
9585                 return (BWN_CCK_RATE_2MB);
9586         case 11:
9587                 return (BWN_CCK_RATE_5MB);
9588         case 22:
9589                 return (BWN_CCK_RATE_11MB);
9590         }
9591
9592         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9593         return (BWN_CCK_RATE_1MB);
9594 }
9595
9596 static int
9597 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9598     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9599 {
9600         const struct bwn_phy *phy = &mac->mac_phy;
9601         struct bwn_softc *sc = mac->mac_sc;
9602         struct ieee80211_frame *wh;
9603         struct ieee80211_frame *protwh;
9604         struct ieee80211_frame_cts *cts;
9605         struct ieee80211_frame_rts *rts;
9606         const struct ieee80211_txparam *tp;
9607         struct ieee80211vap *vap = ni->ni_vap;
9608         struct ifnet *ifp = sc->sc_ifp;
9609         struct ieee80211com *ic = ifp->if_l2com;
9610         struct mbuf *mprot;
9611         unsigned int len;
9612         uint32_t macctl = 0;
9613         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9614         uint16_t phyctl = 0;
9615         uint8_t rate, rate_fb;
9616
9617         wh = mtod(m, struct ieee80211_frame *);
9618         memset(txhdr, 0, sizeof(*txhdr));
9619
9620         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9621         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9622         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9623
9624         /*
9625          * Find TX rate
9626          */
9627         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9628         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9629                 rate = rate_fb = tp->mgmtrate;
9630         else if (ismcast)
9631                 rate = rate_fb = tp->mcastrate;
9632         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9633                 rate = rate_fb = tp->ucastrate;
9634         else {
9635                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9636                 rate = ni->ni_txrate;
9637
9638                 if (rix > 0)
9639                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9640                             IEEE80211_RATE_VAL;
9641                 else
9642                         rate_fb = rate;
9643         }
9644
9645         sc->sc_tx_rate = rate;
9646
9647         rate = bwn_ieeerate2hwrate(sc, rate);
9648         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9649
9650         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9651             bwn_plcp_getcck(rate);
9652         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9653         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9654
9655         if ((rate_fb == rate) ||
9656             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9657             (*(u_int16_t *)wh->i_dur == htole16(0)))
9658                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9659         else
9660                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9661                     m->m_pkthdr.len, rate, isshort);
9662
9663         /* XXX TX encryption */
9664         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9665             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9666             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9667             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9668         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9669             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9670
9671         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9672             BWN_TX_EFT_FB_CCK;
9673         txhdr->chan = phy->chan;
9674         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9675             BWN_TX_PHY_ENC_CCK;
9676         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9677              rate == BWN_CCK_RATE_11MB))
9678                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9679
9680         /* XXX TX antenna selection */
9681
9682         switch (bwn_antenna_sanitize(mac, 0)) {
9683         case 0:
9684                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9685                 break;
9686         case 1:
9687                 phyctl |= BWN_TX_PHY_ANT0;
9688                 break;
9689         case 2:
9690                 phyctl |= BWN_TX_PHY_ANT1;
9691                 break;
9692         case 3:
9693                 phyctl |= BWN_TX_PHY_ANT2;
9694                 break;
9695         case 4:
9696                 phyctl |= BWN_TX_PHY_ANT3;
9697                 break;
9698         default:
9699                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9700         }
9701
9702         if (!ismcast)
9703                 macctl |= BWN_TX_MAC_ACK;
9704
9705         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9706         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9707             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9708                 macctl |= BWN_TX_MAC_LONGFRAME;
9709
9710         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9711                 /* XXX RTS rate is always 1MB??? */
9712                 rts_rate = BWN_CCK_RATE_1MB;
9713                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9714
9715                 protdur = ieee80211_compute_duration(ic->ic_rt,
9716                     m->m_pkthdr.len, rate, isshort) +
9717                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9718
9719                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9720                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9721                             (txhdr->body.old.rts_frame) :
9722                             (txhdr->body.new.rts_frame));
9723                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9724                             protdur);
9725                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9726                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9727                             mprot->m_pkthdr.len);
9728                         m_freem(mprot);
9729                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9730                         len = sizeof(struct ieee80211_frame_cts);
9731                 } else {
9732                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9733                             (txhdr->body.old.rts_frame) :
9734                             (txhdr->body.new.rts_frame));
9735                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9736                             isshort);
9737                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9738                             wh->i_addr2, protdur);
9739                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9740                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9741                             mprot->m_pkthdr.len);
9742                         m_freem(mprot);
9743                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9744                         len = sizeof(struct ieee80211_frame_rts);
9745                 }
9746                 len += IEEE80211_CRC_LEN;
9747                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9748                     &txhdr->body.old.rts_plcp :
9749                     &txhdr->body.new.rts_plcp), len, rts_rate);
9750                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9751                     rts_rate_fb);
9752
9753                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9754                     (&txhdr->body.old.rts_frame) :
9755                     (&txhdr->body.new.rts_frame));
9756                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9757
9758                 if (BWN_ISOFDMRATE(rts_rate)) {
9759                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9760                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9761                 } else {
9762                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9763                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9764                 }
9765                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9766                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9767         }
9768
9769         if (BWN_ISOLDFMT(mac))
9770                 txhdr->body.old.cookie = htole16(cookie);
9771         else
9772                 txhdr->body.new.cookie = htole16(cookie);
9773
9774         txhdr->macctl = htole32(macctl);
9775         txhdr->phyctl = htole16(phyctl);
9776
9777         /*
9778          * TX radio tap
9779          */
9780         if (ieee80211_radiotap_active_vap(vap)) {
9781                 sc->sc_tx_th.wt_flags = 0;
9782                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9783                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9784                 if (isshort &&
9785                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9786                      rate == BWN_CCK_RATE_11MB))
9787                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9788                 sc->sc_tx_th.wt_rate = rate;
9789
9790                 ieee80211_radiotap_tx(vap, m);
9791         }
9792
9793         return (0);
9794 }
9795
9796 static void
9797 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9798     const uint8_t rate)
9799 {
9800         uint32_t d, plen;
9801         uint8_t *raw = plcp->o.raw;
9802
9803         if (BWN_ISOFDMRATE(rate)) {
9804                 d = bwn_plcp_getofdm(rate);
9805                 KASSERT(!(octets & 0xf000),
9806                     ("%s:%d: fail", __func__, __LINE__));
9807                 d |= (octets << 5);
9808                 plcp->o.data = htole32(d);
9809         } else {
9810                 plen = octets * 16 / rate;
9811                 if ((octets * 16 % rate) > 0) {
9812                         plen++;
9813                         if ((rate == BWN_CCK_RATE_11MB)
9814                             && ((octets * 8 % 11) < 4)) {
9815                                 raw[1] = 0x84;
9816                         } else
9817                                 raw[1] = 0x04;
9818                 } else
9819                         raw[1] = 0x04;
9820                 plcp->o.data |= htole32(plen << 16);
9821                 raw[0] = bwn_plcp_getcck(rate);
9822         }
9823 }
9824
9825 static uint8_t
9826 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9827 {
9828         struct bwn_softc *sc = mac->mac_sc;
9829         uint8_t mask;
9830
9831         if (n == 0)
9832                 return (0);
9833         if (mac->mac_phy.gmode)
9834                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9835         else
9836                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9837         if (!(mask & (1 << (n - 1))))
9838                 return (0);
9839         return (n);
9840 }
9841
9842 static uint8_t
9843 bwn_get_fbrate(uint8_t bitrate)
9844 {
9845         switch (bitrate) {
9846         case BWN_CCK_RATE_1MB:
9847                 return (BWN_CCK_RATE_1MB);
9848         case BWN_CCK_RATE_2MB:
9849                 return (BWN_CCK_RATE_1MB);
9850         case BWN_CCK_RATE_5MB:
9851                 return (BWN_CCK_RATE_2MB);
9852         case BWN_CCK_RATE_11MB:
9853                 return (BWN_CCK_RATE_5MB);
9854         case BWN_OFDM_RATE_6MB:
9855                 return (BWN_CCK_RATE_5MB);
9856         case BWN_OFDM_RATE_9MB:
9857                 return (BWN_OFDM_RATE_6MB);
9858         case BWN_OFDM_RATE_12MB:
9859                 return (BWN_OFDM_RATE_9MB);
9860         case BWN_OFDM_RATE_18MB:
9861                 return (BWN_OFDM_RATE_12MB);
9862         case BWN_OFDM_RATE_24MB:
9863                 return (BWN_OFDM_RATE_18MB);
9864         case BWN_OFDM_RATE_36MB:
9865                 return (BWN_OFDM_RATE_24MB);
9866         case BWN_OFDM_RATE_48MB:
9867                 return (BWN_OFDM_RATE_36MB);
9868         case BWN_OFDM_RATE_54MB:
9869                 return (BWN_OFDM_RATE_48MB);
9870         }
9871         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9872         return (0);
9873 }
9874
9875 static uint32_t
9876 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9877     uint32_t ctl, const void *_data, int len)
9878 {
9879         struct bwn_softc *sc = mac->mac_sc;
9880         uint32_t value = 0;
9881         const uint8_t *data = _data;
9882
9883         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9884             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9885         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9886
9887         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9888             tq->tq_base + BWN_PIO8_TXDATA);
9889         if (len & 3) {
9890                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9891                     BWN_PIO8_TXCTL_24_31);
9892                 data = &(data[len - 1]);
9893                 switch (len & 3) {
9894                 case 3:
9895                         ctl |= BWN_PIO8_TXCTL_16_23;
9896                         value |= (uint32_t)(*data) << 16;
9897                         data--;
9898                 case 2:
9899                         ctl |= BWN_PIO8_TXCTL_8_15;
9900                         value |= (uint32_t)(*data) << 8;
9901                         data--;
9902                 case 1:
9903                         value |= (uint32_t)(*data);
9904                 }
9905                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9906                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9907         }
9908
9909         return (ctl);
9910 }
9911
9912 static void
9913 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9914     uint16_t offset, uint32_t value)
9915 {
9916
9917         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9918 }
9919
9920 static uint16_t
9921 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9922     uint16_t ctl, const void *_data, int len)
9923 {
9924         struct bwn_softc *sc = mac->mac_sc;
9925         const uint8_t *data = _data;
9926
9927         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9928         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9929
9930         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9931             tq->tq_base + BWN_PIO_TXDATA);
9932         if (len & 1) {
9933                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9934                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9935                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9936         }
9937
9938         return (ctl);
9939 }
9940
9941 static uint16_t
9942 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9943     uint16_t ctl, struct mbuf *m0)
9944 {
9945         int i, j = 0;
9946         uint16_t data = 0;
9947         const uint8_t *buf;
9948         struct mbuf *m = m0;
9949
9950         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9951         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9952
9953         for (; m != NULL; m = m->m_next) {
9954                 buf = mtod(m, const uint8_t *);
9955                 for (i = 0; i < m->m_len; i++) {
9956                         if (!((j++) % 2))
9957                                 data |= buf[i];
9958                         else {
9959                                 data |= (buf[i] << 8);
9960                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9961                                 data = 0;
9962                         }
9963                 }
9964         }
9965         if (m0->m_pkthdr.len % 2) {
9966                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9967                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9968                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9969         }
9970
9971         return (ctl);
9972 }
9973
9974 static void
9975 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9976 {
9977
9978         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9979                 return;
9980         BWN_WRITE_2(mac, 0x684, 510 + time);
9981         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9982 }
9983
9984 static struct bwn_dma_ring *
9985 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9986 {
9987
9988         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9989                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9990
9991         switch (prio) {
9992         case 3:
9993                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9994         case 2:
9995                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9996         case 0:
9997                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9998         case 1:
9999                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10000         }
10001         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10002         return (NULL);
10003 }
10004
10005 static int
10006 bwn_dma_getslot(struct bwn_dma_ring *dr)
10007 {
10008         int slot;
10009
10010         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10011
10012         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10013         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10014         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10015
10016         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10017         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10018         dr->dr_curslot = slot;
10019         dr->dr_usedslot++;
10020
10021         return (slot);
10022 }
10023
10024 static int
10025 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10026 {
10027         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10028         unsigned int a, b, c, d;
10029         unsigned int avg;
10030         uint32_t tmp;
10031
10032         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10033         a = tmp & 0xff;
10034         b = (tmp >> 8) & 0xff;
10035         c = (tmp >> 16) & 0xff;
10036         d = (tmp >> 24) & 0xff;
10037         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10038             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10039                 return (ENOENT);
10040         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10041             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10042             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10043
10044         if (ofdm) {
10045                 a = (a + 32) & 0x3f;
10046                 b = (b + 32) & 0x3f;
10047                 c = (c + 32) & 0x3f;
10048                 d = (d + 32) & 0x3f;
10049         }
10050
10051         avg = (a + b + c + d + 2) / 4;
10052         if (ofdm) {
10053                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10054                     & BWN_HF_4DB_CCK_POWERBOOST)
10055                         avg = (avg >= 13) ? (avg - 13) : 0;
10056         }
10057         return (avg);
10058 }
10059
10060 static void
10061 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10062 {
10063         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10064         int rfatt = *rfattp;
10065         int bbatt = *bbattp;
10066
10067         while (1) {
10068                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10069                         break;
10070                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10071                         break;
10072                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10073                         break;
10074                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10075                         break;
10076                 if (bbatt > lo->bbatt.max) {
10077                         bbatt -= 4;
10078                         rfatt += 1;
10079                         continue;
10080                 }
10081                 if (bbatt < lo->bbatt.min) {
10082                         bbatt += 4;
10083                         rfatt -= 1;
10084                         continue;
10085                 }
10086                 if (rfatt > lo->rfatt.max) {
10087                         rfatt -= 1;
10088                         bbatt += 4;
10089                         continue;
10090                 }
10091                 if (rfatt < lo->rfatt.min) {
10092                         rfatt += 1;
10093                         bbatt -= 4;
10094                         continue;
10095                 }
10096                 break;
10097         }
10098
10099         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10100         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10101 }
10102
10103 static void
10104 bwn_phy_lock(struct bwn_mac *mac)
10105 {
10106         struct bwn_softc *sc = mac->mac_sc;
10107         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10108
10109         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10110             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10111
10112         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10113                 bwn_psctl(mac, BWN_PS_AWAKE);
10114 }
10115
10116 static void
10117 bwn_phy_unlock(struct bwn_mac *mac)
10118 {
10119         struct bwn_softc *sc = mac->mac_sc;
10120         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10121
10122         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10123             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10124
10125         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10126                 bwn_psctl(mac, 0);
10127 }
10128
10129 static void
10130 bwn_rf_lock(struct bwn_mac *mac)
10131 {
10132
10133         BWN_WRITE_4(mac, BWN_MACCTL,
10134             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10135         BWN_READ_4(mac, BWN_MACCTL);
10136         DELAY(10);
10137 }
10138
10139 static void
10140 bwn_rf_unlock(struct bwn_mac *mac)
10141 {
10142
10143         BWN_READ_2(mac, BWN_PHYVER);
10144         BWN_WRITE_4(mac, BWN_MACCTL,
10145             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10146 }
10147
10148 static struct bwn_pio_txqueue *
10149 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10150     struct bwn_pio_txpkt **pack)
10151 {
10152         struct bwn_pio *pio = &mac->mac_method.pio;
10153         struct bwn_pio_txqueue *tq = NULL;
10154         unsigned int index;
10155
10156         switch (cookie & 0xf000) {
10157         case 0x1000:
10158                 tq = &pio->wme[WME_AC_BK];
10159                 break;
10160         case 0x2000:
10161                 tq = &pio->wme[WME_AC_BE];
10162                 break;
10163         case 0x3000:
10164                 tq = &pio->wme[WME_AC_VI];
10165                 break;
10166         case 0x4000:
10167                 tq = &pio->wme[WME_AC_VO];
10168                 break;
10169         case 0x5000:
10170                 tq = &pio->mcast;
10171                 break;
10172         }
10173         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10174         if (tq == NULL)
10175                 return (NULL);
10176         index = (cookie & 0x0fff);
10177         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10178         if (index >= N(tq->tq_pkts))
10179                 return (NULL);
10180         *pack = &tq->tq_pkts[index];
10181         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10182         return (tq);
10183 }
10184
10185 static void
10186 bwn_txpwr(void *arg, int npending)
10187 {
10188         struct bwn_mac *mac = arg;
10189         struct bwn_softc *sc = mac->mac_sc;
10190
10191         BWN_LOCK(sc);
10192         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10193             mac->mac_phy.set_txpwr != NULL)
10194                 mac->mac_phy.set_txpwr(mac);
10195         BWN_UNLOCK(sc);
10196 }
10197
10198 static void
10199 bwn_task_15s(struct bwn_mac *mac)
10200 {
10201         uint16_t reg;
10202
10203         if (mac->mac_fw.opensource) {
10204                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10205                 if (reg) {
10206                         bwn_restart(mac, "fw watchdog");
10207                         return;
10208                 }
10209                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10210         }
10211         if (mac->mac_phy.task_15s)
10212                 mac->mac_phy.task_15s(mac);
10213
10214         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10215 }
10216
10217 static void
10218 bwn_task_30s(struct bwn_mac *mac)
10219 {
10220
10221         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10222                 return;
10223         mac->mac_noise.noi_running = 1;
10224         mac->mac_noise.noi_nsamples = 0;
10225
10226         bwn_noise_gensample(mac);
10227 }
10228
10229 static void
10230 bwn_task_60s(struct bwn_mac *mac)
10231 {
10232
10233         if (mac->mac_phy.task_60s)
10234                 mac->mac_phy.task_60s(mac);
10235         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10236 }
10237
10238 static void
10239 bwn_tasks(void *arg)
10240 {
10241         struct bwn_mac *mac = arg;
10242         struct bwn_softc *sc = mac->mac_sc;
10243
10244         BWN_ASSERT_LOCKED(sc);
10245         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10246                 return;
10247
10248         if (mac->mac_task_state % 4 == 0)
10249                 bwn_task_60s(mac);
10250         if (mac->mac_task_state % 2 == 0)
10251                 bwn_task_30s(mac);
10252         bwn_task_15s(mac);
10253
10254         mac->mac_task_state++;
10255         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10256 }
10257
10258 static int
10259 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10260 {
10261         struct bwn_softc *sc = mac->mac_sc;
10262
10263         KASSERT(a == 0, ("not support APHY\n"));
10264
10265         switch (plcp->o.raw[0] & 0xf) {
10266         case 0xb:
10267                 return (BWN_OFDM_RATE_6MB);
10268         case 0xf:
10269                 return (BWN_OFDM_RATE_9MB);
10270         case 0xa:
10271                 return (BWN_OFDM_RATE_12MB);
10272         case 0xe:
10273                 return (BWN_OFDM_RATE_18MB);
10274         case 0x9:
10275                 return (BWN_OFDM_RATE_24MB);
10276         case 0xd:
10277                 return (BWN_OFDM_RATE_36MB);
10278         case 0x8:
10279                 return (BWN_OFDM_RATE_48MB);
10280         case 0xc:
10281                 return (BWN_OFDM_RATE_54MB);
10282         }
10283         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10284             plcp->o.raw[0] & 0xf);
10285         return (-1);
10286 }
10287
10288 static int
10289 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10290 {
10291         struct bwn_softc *sc = mac->mac_sc;
10292
10293         switch (plcp->o.raw[0]) {
10294         case 0x0a:
10295                 return (BWN_CCK_RATE_1MB);
10296         case 0x14:
10297                 return (BWN_CCK_RATE_2MB);
10298         case 0x37:
10299                 return (BWN_CCK_RATE_5MB);
10300         case 0x6e:
10301                 return (BWN_CCK_RATE_11MB);
10302         }
10303         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10304         return (-1);
10305 }
10306
10307 static void
10308 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10309     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10310     int rssi, int noise)
10311 {
10312         struct bwn_softc *sc = mac->mac_sc;
10313         const struct ieee80211_frame_min *wh;
10314         uint64_t tsf;
10315         uint16_t low_mactime_now;
10316
10317         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10318                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10319
10320         wh = mtod(m, const struct ieee80211_frame_min *);
10321         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10322                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10323
10324         bwn_tsf_read(mac, &tsf);
10325         low_mactime_now = tsf;
10326         tsf = tsf & ~0xffffULL;
10327         tsf += le16toh(rxhdr->mac_time);
10328         if (low_mactime_now < le16toh(rxhdr->mac_time))
10329                 tsf -= 0x10000;
10330
10331         sc->sc_rx_th.wr_tsf = tsf;
10332         sc->sc_rx_th.wr_rate = rate;
10333         sc->sc_rx_th.wr_antsignal = rssi;
10334         sc->sc_rx_th.wr_antnoise = noise;
10335 }
10336
10337 static void
10338 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10339 {
10340         uint32_t low, high;
10341
10342         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10343             ("%s:%d: fail", __func__, __LINE__));
10344
10345         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10346         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10347         *tsf = high;
10348         *tsf <<= 32;
10349         *tsf |= low;
10350 }
10351
10352 static int
10353 bwn_dma_attach(struct bwn_mac *mac)
10354 {
10355         struct bwn_dma *dma = &mac->mac_method.dma;
10356         struct bwn_softc *sc = mac->mac_sc;
10357         bus_addr_t lowaddr = 0;
10358         int error;
10359
10360         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10361                 return (0);
10362
10363         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10364
10365         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10366
10367         dma->dmatype = bwn_dma_gettype(mac);
10368         if (dma->dmatype == BWN_DMA_30BIT)
10369                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10370         else if (dma->dmatype == BWN_DMA_32BIT)
10371                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10372         else
10373                 lowaddr = BUS_SPACE_MAXADDR;
10374
10375         /*
10376          * Create top level DMA tag
10377          */
10378         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10379                                BWN_ALIGN, 0,            /* alignment, bounds */
10380                                lowaddr,                 /* lowaddr */
10381                                BUS_SPACE_MAXADDR,       /* highaddr */
10382                                NULL, NULL,              /* filter, filterarg */
10383                                MAXBSIZE,                /* maxsize */
10384                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10385                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10386                                0,                       /* flags */
10387                                NULL, NULL,              /* lockfunc, lockarg */
10388                                &dma->parent_dtag);
10389         if (error) {
10390                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10391                 return (error);
10392         }
10393
10394         /*
10395          * Create TX/RX mbuf DMA tag
10396          */
10397         error = bus_dma_tag_create(dma->parent_dtag,
10398                                 1,
10399                                 0,
10400                                 BUS_SPACE_MAXADDR,
10401                                 BUS_SPACE_MAXADDR,
10402                                 NULL, NULL,
10403                                 MCLBYTES,
10404                                 1,
10405                                 BUS_SPACE_MAXSIZE_32BIT,
10406                                 0,
10407                                 NULL, NULL,
10408                                 &dma->rxbuf_dtag);
10409         if (error) {
10410                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10411                 goto fail0;
10412         }
10413         error = bus_dma_tag_create(dma->parent_dtag,
10414                                 1,
10415                                 0,
10416                                 BUS_SPACE_MAXADDR,
10417                                 BUS_SPACE_MAXADDR,
10418                                 NULL, NULL,
10419                                 MCLBYTES,
10420                                 1,
10421                                 BUS_SPACE_MAXSIZE_32BIT,
10422                                 0,
10423                                 NULL, NULL,
10424                                 &dma->txbuf_dtag);
10425         if (error) {
10426                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10427                 goto fail1;
10428         }
10429
10430         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10431         if (!dma->wme[WME_AC_BK])
10432                 goto fail2;
10433
10434         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10435         if (!dma->wme[WME_AC_BE])
10436                 goto fail3;
10437
10438         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10439         if (!dma->wme[WME_AC_VI])
10440                 goto fail4;
10441
10442         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10443         if (!dma->wme[WME_AC_VO])
10444                 goto fail5;
10445
10446         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10447         if (!dma->mcast)
10448                 goto fail6;
10449         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10450         if (!dma->rx)
10451                 goto fail7;
10452
10453         return (error);
10454
10455 fail7:  bwn_dma_ringfree(&dma->mcast);
10456 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10457 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10458 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10459 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10460 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10461 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10462 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10463         return (error);
10464 }
10465
10466 static struct bwn_dma_ring *
10467 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10468     uint16_t cookie, int *slot)
10469 {
10470         struct bwn_dma *dma = &mac->mac_method.dma;
10471         struct bwn_dma_ring *dr;
10472         struct bwn_softc *sc = mac->mac_sc;
10473
10474         BWN_ASSERT_LOCKED(mac->mac_sc);
10475
10476         switch (cookie & 0xf000) {
10477         case 0x1000:
10478                 dr = dma->wme[WME_AC_BK];
10479                 break;
10480         case 0x2000:
10481                 dr = dma->wme[WME_AC_BE];
10482                 break;
10483         case 0x3000:
10484                 dr = dma->wme[WME_AC_VI];
10485                 break;
10486         case 0x4000:
10487                 dr = dma->wme[WME_AC_VO];
10488                 break;
10489         case 0x5000:
10490                 dr = dma->mcast;
10491                 break;
10492         default:
10493                 dr = NULL;
10494                 KASSERT(0 == 1,
10495                     ("invalid cookie value %d", cookie & 0xf000));
10496         }
10497         *slot = (cookie & 0x0fff);
10498         if (*slot < 0 || *slot >= dr->dr_numslots) {
10499                 /*
10500                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10501                  * that it occurs events which have same H/W sequence numbers.
10502                  * When it's occurred just prints a WARNING msgs and ignores.
10503                  */
10504                 KASSERT(status->seq == dma->lastseq,
10505                     ("%s:%d: fail", __func__, __LINE__));
10506                 device_printf(sc->sc_dev,
10507                     "out of slot ranges (0 < %d < %d)\n", *slot,
10508                     dr->dr_numslots);
10509                 return (NULL);
10510         }
10511         dma->lastseq = status->seq;
10512         return (dr);
10513 }
10514
10515 static void
10516 bwn_dma_stop(struct bwn_mac *mac)
10517 {
10518         struct bwn_dma *dma;
10519
10520         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10521                 return;
10522         dma = &mac->mac_method.dma;
10523
10524         bwn_dma_ringstop(&dma->rx);
10525         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10526         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10527         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10528         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10529         bwn_dma_ringstop(&dma->mcast);
10530 }
10531
10532 static void
10533 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10534 {
10535
10536         if (dr == NULL)
10537                 return;
10538
10539         bwn_dma_cleanup(*dr);
10540 }
10541
10542 static void
10543 bwn_pio_stop(struct bwn_mac *mac)
10544 {
10545         struct bwn_pio *pio;
10546
10547         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10548                 return;
10549         pio = &mac->mac_method.pio;
10550
10551         bwn_destroy_queue_tx(&pio->mcast);
10552         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10553         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10554         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10555         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10556 }
10557
10558 static void
10559 bwn_led_attach(struct bwn_mac *mac)
10560 {
10561         struct bwn_softc *sc = mac->mac_sc;
10562         const uint8_t *led_act = NULL;
10563         uint16_t val[BWN_LED_MAX];
10564         int i;
10565
10566         sc->sc_led_idle = (2350 * hz) / 1000;
10567         sc->sc_led_blink = 1;
10568
10569         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10570                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10571                     bwn_vendor_led_act[i].vid) {
10572                         led_act = bwn_vendor_led_act[i].led_act;
10573                         break;
10574                 }
10575         }
10576         if (led_act == NULL)
10577                 led_act = bwn_default_led_act;
10578
10579         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10580         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10581         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10582         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10583
10584         for (i = 0; i < BWN_LED_MAX; ++i) {
10585                 struct bwn_led *led = &sc->sc_leds[i];
10586
10587                 if (val[i] == 0xff) {
10588                         led->led_act = led_act[i];
10589                 } else {
10590                         if (val[i] & BWN_LED_ACT_LOW)
10591                                 led->led_flags |= BWN_LED_F_ACTLOW;
10592                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10593                 }
10594                 led->led_mask = (1 << i);
10595
10596                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10597                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10598                     led->led_act == BWN_LED_ACT_BLINK) {
10599                         led->led_flags |= BWN_LED_F_BLINK;
10600                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10601                                 led->led_flags |= BWN_LED_F_POLLABLE;
10602                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10603                                 led->led_flags |= BWN_LED_F_SLOW;
10604
10605                         if (sc->sc_blink_led == NULL) {
10606                                 sc->sc_blink_led = led;
10607                                 if (led->led_flags & BWN_LED_F_SLOW)
10608                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10609                         }
10610                 }
10611
10612                 DPRINTF(sc, BWN_DEBUG_LED,
10613                     "%dth led, act %d, lowact %d\n", i,
10614                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10615         }
10616         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10617 }
10618
10619 static __inline uint16_t
10620 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10621 {
10622
10623         if (led->led_flags & BWN_LED_F_ACTLOW)
10624                 on = !on;
10625         if (on)
10626                 val |= led->led_mask;
10627         else
10628                 val &= ~led->led_mask;
10629         return val;
10630 }
10631
10632 static void
10633 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10634 {
10635         struct bwn_softc *sc = mac->mac_sc;
10636         struct ifnet *ifp = sc->sc_ifp;
10637         struct ieee80211com *ic = ifp->if_l2com;
10638         uint16_t val;
10639         int i;
10640
10641         if (nstate == IEEE80211_S_INIT) {
10642                 callout_stop(&sc->sc_led_blink_ch);
10643                 sc->sc_led_blinking = 0;
10644         }
10645
10646         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10647                 return;
10648
10649         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10650         for (i = 0; i < BWN_LED_MAX; ++i) {
10651                 struct bwn_led *led = &sc->sc_leds[i];
10652                 int on;
10653
10654                 if (led->led_act == BWN_LED_ACT_UNKN ||
10655                     led->led_act == BWN_LED_ACT_NULL)
10656                         continue;
10657
10658                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10659                     nstate != IEEE80211_S_INIT)
10660                         continue;
10661
10662                 switch (led->led_act) {
10663                 case BWN_LED_ACT_ON:    /* Always on */
10664                         on = 1;
10665                         break;
10666                 case BWN_LED_ACT_OFF:   /* Always off */
10667                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10668                         on = 0;
10669                         break;
10670                 default:
10671                         on = 1;
10672                         switch (nstate) {
10673                         case IEEE80211_S_INIT:
10674                                 on = 0;
10675                                 break;
10676                         case IEEE80211_S_RUN:
10677                                 if (led->led_act == BWN_LED_ACT_11G &&
10678                                     ic->ic_curmode != IEEE80211_MODE_11G)
10679                                         on = 0;
10680                                 break;
10681                         default:
10682                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10683                                         on = 0;
10684                                 break;
10685                         }
10686                         break;
10687                 }
10688
10689                 val = bwn_led_onoff(led, val, on);
10690         }
10691         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10692 }
10693
10694 static void
10695 bwn_led_event(struct bwn_mac *mac, int event)
10696 {
10697         struct bwn_softc *sc = mac->mac_sc;
10698         struct bwn_led *led = sc->sc_blink_led;
10699         int rate;
10700
10701         if (event == BWN_LED_EVENT_POLL) {
10702                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10703                         return;
10704                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10705                         return;
10706         }
10707
10708         sc->sc_led_ticks = ticks;
10709         if (sc->sc_led_blinking)
10710                 return;
10711
10712         switch (event) {
10713         case BWN_LED_EVENT_RX:
10714                 rate = sc->sc_rx_rate;
10715                 break;
10716         case BWN_LED_EVENT_TX:
10717                 rate = sc->sc_tx_rate;
10718                 break;
10719         case BWN_LED_EVENT_POLL:
10720                 rate = 0;
10721                 break;
10722         default:
10723                 panic("unknown LED event %d\n", event);
10724                 break;
10725         }
10726         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10727             bwn_led_duration[rate].off_dur);
10728 }
10729
10730 static void
10731 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10732 {
10733         struct bwn_softc *sc = mac->mac_sc;
10734         struct bwn_led *led = sc->sc_blink_led;
10735         uint16_t val;
10736
10737         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10738         val = bwn_led_onoff(led, val, 1);
10739         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10740
10741         if (led->led_flags & BWN_LED_F_SLOW) {
10742                 BWN_LED_SLOWDOWN(on_dur);
10743                 BWN_LED_SLOWDOWN(off_dur);
10744         }
10745
10746         sc->sc_led_blinking = 1;
10747         sc->sc_led_blink_offdur = off_dur;
10748
10749         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10750 }
10751
10752 static void
10753 bwn_led_blink_next(void *arg)
10754 {
10755         struct bwn_mac *mac = arg;
10756         struct bwn_softc *sc = mac->mac_sc;
10757         uint16_t val;
10758
10759         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10760         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10761         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10762
10763         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10764             bwn_led_blink_end, mac);
10765 }
10766
10767 static void
10768 bwn_led_blink_end(void *arg)
10769 {
10770         struct bwn_mac *mac = arg;
10771         struct bwn_softc *sc = mac->mac_sc;
10772
10773         sc->sc_led_blinking = 0;
10774 }
10775
10776 static int
10777 bwn_suspend(device_t dev)
10778 {
10779         struct bwn_softc *sc = device_get_softc(dev);
10780
10781         bwn_stop(sc, 1);
10782         return (0);
10783 }
10784
10785 static int
10786 bwn_resume(device_t dev)
10787 {
10788         struct bwn_softc *sc = device_get_softc(dev);
10789         struct ifnet *ifp = sc->sc_ifp;
10790
10791         if (ifp->if_flags & IFF_UP)
10792                 bwn_init(sc);
10793         return (0);
10794 }
10795
10796 static void
10797 bwn_rfswitch(void *arg)
10798 {
10799         struct bwn_softc *sc = arg;
10800         struct bwn_mac *mac = sc->sc_curmac;
10801         int cur = 0, prev = 0;
10802
10803         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10804             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10805
10806         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10807                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10808                         & BWN_RF_HWENABLED_HI_MASK))
10809                         cur = 1;
10810         } else {
10811                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10812                     & BWN_RF_HWENABLED_LO_MASK)
10813                         cur = 1;
10814         }
10815
10816         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10817                 prev = 1;
10818
10819         if (cur != prev) {
10820                 if (cur)
10821                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10822                 else
10823                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10824
10825                 device_printf(sc->sc_dev,
10826                     "status of RF switch is changed to %s\n",
10827                     cur ? "ON" : "OFF");
10828                 if (cur != mac->mac_phy.rf_on) {
10829                         if (cur)
10830                                 bwn_rf_turnon(mac);
10831                         else
10832                                 bwn_rf_turnoff(mac);
10833                 }
10834         }
10835
10836         callout_schedule(&sc->sc_rfswitch_ch, hz);
10837 }
10838
10839 static void
10840 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10841 {
10842         struct bwn_phy *phy = &mac->mac_phy;
10843         struct bwn_phy_lp *plp = &phy->phy_lp;
10844
10845         plp->plp_antenna = BWN_ANT_DEFAULT;
10846 }
10847
10848 static int
10849 bwn_phy_lp_init(struct bwn_mac *mac)
10850 {
10851         static const struct bwn_stxtable tables[] = {
10852                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10853                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10854                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10855                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10856                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10857                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10858                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10859                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10860                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10861                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10862                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10863                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10864                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10865                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10866                 { 2, 11, 0x40, 0, 0x0f }
10867         };
10868         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10869         struct bwn_softc *sc = mac->mac_sc;
10870         const struct bwn_stxtable *st;
10871         struct ifnet *ifp = sc->sc_ifp;
10872         struct ieee80211com *ic = ifp->if_l2com;
10873         int i, error;
10874         uint16_t tmp;
10875
10876         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10877         bwn_phy_lp_bbinit(mac);
10878
10879         /* initialize RF */
10880         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10881         DELAY(1);
10882         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10883         DELAY(1);
10884
10885         if (mac->mac_phy.rf_ver == 0x2062)
10886                 bwn_phy_lp_b2062_init(mac);
10887         else {
10888                 bwn_phy_lp_b2063_init(mac);
10889
10890                 /* synchronize stx table. */
10891                 for (i = 0; i < N(tables); i++) {
10892                         st = &tables[i];
10893                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10894                         tmp >>= st->st_rfshift;
10895                         tmp <<= st->st_physhift;
10896                         BWN_PHY_SETMASK(mac,
10897                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10898                             ~(st->st_mask << st->st_physhift), tmp);
10899                 }
10900
10901                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10902                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10903         }
10904
10905         /* calibrate RC */
10906         if (mac->mac_phy.rev >= 2)
10907                 bwn_phy_lp_rxcal_r2(mac);
10908         else if (!plp->plp_rccap) {
10909                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10910                         bwn_phy_lp_rccal_r12(mac);
10911         } else
10912                 bwn_phy_lp_set_rccap(mac);
10913
10914         error = bwn_phy_lp_switch_channel(mac, 7);
10915         if (error)
10916                 device_printf(sc->sc_dev,
10917                     "failed to change channel 7 (%d)\n", error);
10918         bwn_phy_lp_txpctl_init(mac);
10919         bwn_phy_lp_calib(mac);
10920         return (0);
10921 }
10922
10923 static uint16_t
10924 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10925 {
10926
10927         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10928         return (BWN_READ_2(mac, BWN_PHYDATA));
10929 }
10930
10931 static void
10932 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10933 {
10934
10935         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10936         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10937 }
10938
10939 static void
10940 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10941     uint16_t set)
10942 {
10943
10944         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10945         BWN_WRITE_2(mac, BWN_PHYDATA,
10946             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10947 }
10948
10949 static uint16_t
10950 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10951 {
10952
10953         KASSERT(reg != 1, ("unaccessible register %d", reg));
10954         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10955                 reg |= 0x100;
10956         if (mac->mac_phy.rev >= 2)
10957                 reg |= 0x200;
10958         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10959         return BWN_READ_2(mac, BWN_RFDATALO);
10960 }
10961
10962 static void
10963 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10964 {
10965
10966         KASSERT(reg != 1, ("unaccessible register %d", reg));
10967         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10968         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10969 }
10970
10971 static void
10972 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10973 {
10974
10975         if (on) {
10976                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10977                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10978                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10979                 return;
10980         }
10981
10982         if (mac->mac_phy.rev >= 2) {
10983                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10984                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10985                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10986                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10987                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10988                 return;
10989         }
10990
10991         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10992         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10993         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10994         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10995 }
10996
10997 static int
10998 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10999 {
11000         struct bwn_phy *phy = &mac->mac_phy;
11001         struct bwn_phy_lp *plp = &phy->phy_lp;
11002         int error;
11003
11004         if (phy->rf_ver == 0x2063) {
11005                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11006                 if (error)
11007                         return (error);
11008         } else {
11009                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11010                 if (error)
11011                         return (error);
11012                 bwn_phy_lp_set_anafilter(mac, chan);
11013                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11014         }
11015
11016         plp->plp_chan = chan;
11017         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11018         return (0);
11019 }
11020
11021 static uint32_t
11022 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11023 {
11024         struct bwn_softc *sc = mac->mac_sc;
11025         struct ifnet *ifp = sc->sc_ifp;
11026         struct ieee80211com *ic = ifp->if_l2com;
11027
11028         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11029 }
11030
11031 static void
11032 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11033 {
11034         struct bwn_phy *phy = &mac->mac_phy;
11035         struct bwn_phy_lp *plp = &phy->phy_lp;
11036
11037         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11038                 return;
11039
11040         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11041         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11042         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11043         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11044         plp->plp_antenna = antenna;
11045 }
11046
11047 static void
11048 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11049 {
11050
11051         bwn_phy_lp_calib(mac);
11052 }
11053
11054 static void
11055 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11056 {
11057         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11058         struct bwn_softc *sc = mac->mac_sc;
11059         struct ifnet *ifp = sc->sc_ifp;
11060         struct ieee80211com *ic = ifp->if_l2com;
11061
11062         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11063                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11064                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11065                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11066                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11067                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11068                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11069                 return;
11070         }
11071
11072         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11073         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11074         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11075         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11076         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11077         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11078         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11079         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11080 }
11081
11082 static void
11083 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11084 {
11085
11086         bwn_phy_lp_tblinit(mac);
11087         if (mac->mac_phy.rev >= 2)
11088                 bwn_phy_lp_bbinit_r2(mac);
11089         else
11090                 bwn_phy_lp_bbinit_r01(mac);
11091 }
11092
11093 static void
11094 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11095 {
11096         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11097         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11098         struct bwn_softc *sc = mac->mac_sc;
11099         struct ifnet *ifp = sc->sc_ifp;
11100         struct ieee80211com *ic = ifp->if_l2com;
11101
11102         bwn_phy_lp_set_txgain(mac,
11103             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11104         bwn_phy_lp_set_bbmult(mac, 150);
11105 }
11106
11107 static void
11108 bwn_phy_lp_calib(struct bwn_mac *mac)
11109 {
11110         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11111         struct bwn_softc *sc = mac->mac_sc;
11112         struct ifnet *ifp = sc->sc_ifp;
11113         struct ieee80211com *ic = ifp->if_l2com;
11114         const struct bwn_rxcompco *rc = NULL;
11115         struct bwn_txgain ogain;
11116         int i, omode, oafeovr, orf, obbmult;
11117         uint8_t mode, fc = 0;
11118
11119         if (plp->plp_chanfullcal != plp->plp_chan) {
11120                 plp->plp_chanfullcal = plp->plp_chan;
11121                 fc = 1;
11122         }
11123
11124         bwn_mac_suspend(mac);
11125
11126         /* BlueTooth Coexistance Override */
11127         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11128         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11129
11130         if (mac->mac_phy.rev >= 2)
11131                 bwn_phy_lp_digflt_save(mac);
11132         bwn_phy_lp_get_txpctlmode(mac);
11133         mode = plp->plp_txpctlmode;
11134         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11135         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11136                 bwn_phy_lp_bugfix(mac);
11137         if (mac->mac_phy.rev >= 2 && fc == 1) {
11138                 bwn_phy_lp_get_txpctlmode(mac);
11139                 omode = plp->plp_txpctlmode;
11140                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11141                 if (oafeovr)
11142                         ogain = bwn_phy_lp_get_txgain(mac);
11143                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11144                 obbmult = bwn_phy_lp_get_bbmult(mac);
11145                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11146                 if (oafeovr)
11147                         bwn_phy_lp_set_txgain(mac, &ogain);
11148                 bwn_phy_lp_set_bbmult(mac, obbmult);
11149                 bwn_phy_lp_set_txpctlmode(mac, omode);
11150                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11151         }
11152         bwn_phy_lp_set_txpctlmode(mac, mode);
11153         if (mac->mac_phy.rev >= 2)
11154                 bwn_phy_lp_digflt_restore(mac);
11155
11156         /* do RX IQ Calculation; assumes that noise is true. */
11157         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11158                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11159                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11160                                 rc = &bwn_rxcompco_5354[i];
11161                 }
11162         } else if (mac->mac_phy.rev >= 2)
11163                 rc = &bwn_rxcompco_r2;
11164         else {
11165                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11166                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11167                                 rc = &bwn_rxcompco_r12[i];
11168                 }
11169         }
11170         if (rc == NULL)
11171                 goto fail;
11172
11173         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11174         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11175
11176         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11177
11178         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11179                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11180                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11181         } else {
11182                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11183                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11184         }
11185
11186         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11187         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11188         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11189         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11190         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11191         bwn_phy_lp_set_deaf(mac, 0);
11192         /* XXX no checking return value? */
11193         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11194         bwn_phy_lp_clear_deaf(mac, 0);
11195         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11196         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11197         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11198
11199         /* disable RX GAIN override. */
11200         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11201         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11202         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11203         if (mac->mac_phy.rev >= 2) {
11204                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11205                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11206                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11207                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11208                 }
11209         } else {
11210                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11211         }
11212
11213         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11214         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11215 fail:
11216         bwn_mac_enable(mac);
11217 }
11218
11219 static void
11220 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11221 {
11222
11223         if (on) {
11224                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11225                 return;
11226         }
11227
11228         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11229         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11230 }
11231
11232 static int
11233 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11234 {
11235         static const struct bwn_b206x_chan *bc = NULL;
11236         struct bwn_softc *sc = mac->mac_sc;
11237         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11238             tmp[6];
11239         uint16_t old, scale, tmp16;
11240         int i, div;
11241
11242         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11243                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11244                         bc = &bwn_b2063_chantable[i];
11245                         break;
11246                 }
11247         }
11248         if (bc == NULL)
11249                 return (EINVAL);
11250
11251         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11252         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11253         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11254         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11255         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11256         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11257         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11258         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11259         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11260         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11261         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11262         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11263
11264         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11265         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11266
11267         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11268         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11269         freqref = freqxtal * 3;
11270         div = (freqxtal <= 26000000 ? 1 : 2);
11271         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11272         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11273                 999999) / 1000000) + 1;
11274
11275         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11276         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11277             0xfff8, timeout >> 2);
11278         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11279             0xff9f,timeout << 5);
11280         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11281
11282         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11283         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11284         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11285
11286         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11287             (timeoutref + 1)) - 1;
11288         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11289             0xf0, count >> 8);
11290         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11291
11292         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11293         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11294         while (tmp[1] >= freqref) {
11295                 tmp[0]++;
11296                 tmp[1] -= freqref;
11297         }
11298         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11299         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11300         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11301         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11302         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11303
11304         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11305         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11306         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11307         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11308
11309         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11310         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11311
11312         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11313                 scale = 1;
11314                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11315         } else {
11316                 scale = 0;
11317                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11318         }
11319         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11320         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11321
11322         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11323             (scale + 1);
11324         if (tmp[5] > 150)
11325                 tmp[5] = 0;
11326
11327         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11328         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11329
11330         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11331         if (freqxtal > 26000000)
11332                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11333         else
11334                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11335
11336         if (val[0] == 45)
11337                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11338         else
11339                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11340
11341         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11342         DELAY(1);
11343         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11344
11345         /* VCO Calibration */
11346         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11347         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11348         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11349         DELAY(1);
11350         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11351         DELAY(1);
11352         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11353         DELAY(1);
11354         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11355         DELAY(300);
11356         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11357
11358         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11359         return (0);
11360 }
11361
11362 static int
11363 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11364 {
11365         struct bwn_softc *sc = mac->mac_sc;
11366         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11367         const struct bwn_b206x_chan *bc = NULL;
11368         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11369         uint32_t tmp[9];
11370         int i;
11371
11372         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11373                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11374                         bc = &bwn_b2062_chantable[i];
11375                         break;
11376                 }
11377         }
11378
11379         if (bc == NULL)
11380                 return (EINVAL);
11381
11382         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11383         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11384         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11385         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11386         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11387         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11388         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11389         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11390         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11391         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11392
11393         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11394         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11395         bwn_phy_lp_b2062_reset_pllbias(mac);
11396         tmp[0] = freqxtal / 1000;
11397         tmp[1] = plp->plp_div * 1000;
11398         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11399         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11400                 tmp[2] *= 2;
11401         tmp[3] = 48 * tmp[0];
11402         tmp[5] = tmp[2] / tmp[3];
11403         tmp[6] = tmp[2] % tmp[3];
11404         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11405         tmp[4] = tmp[6] * 0x100;
11406         tmp[5] = tmp[4] / tmp[3];
11407         tmp[6] = tmp[4] % tmp[3];
11408         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11409         tmp[4] = tmp[6] * 0x100;
11410         tmp[5] = tmp[4] / tmp[3];
11411         tmp[6] = tmp[4] % tmp[3];
11412         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11413         tmp[4] = tmp[6] * 0x100;
11414         tmp[5] = tmp[4] / tmp[3];
11415         tmp[6] = tmp[4] % tmp[3];
11416         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11417             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11418         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11419         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11420         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11421         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11422
11423         bwn_phy_lp_b2062_vco_calib(mac);
11424         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11425                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11426                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11427                 bwn_phy_lp_b2062_reset_pllbias(mac);
11428                 bwn_phy_lp_b2062_vco_calib(mac);
11429                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11430                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11431                         return (EIO);
11432                 }
11433         }
11434         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11435         return (0);
11436 }
11437
11438 static void
11439 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11440 {
11441         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11442         uint16_t tmp = (channel == 14);
11443
11444         if (mac->mac_phy.rev < 2) {
11445                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11446                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11447                         bwn_phy_lp_set_rccap(mac);
11448                 return;
11449         }
11450
11451         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11452 }
11453
11454 static void
11455 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11456 {
11457         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11458         struct bwn_softc *sc = mac->mac_sc;
11459         struct ifnet *ifp = sc->sc_ifp;
11460         struct ieee80211com *ic = ifp->if_l2com;
11461         uint16_t iso, tmp[3];
11462
11463         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11464
11465         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11466                 iso = plp->plp_txisoband_m;
11467         else if (freq <= 5320)
11468                 iso = plp->plp_txisoband_l;
11469         else if (freq <= 5700)
11470                 iso = plp->plp_txisoband_m;
11471         else
11472                 iso = plp->plp_txisoband_h;
11473
11474         tmp[0] = ((iso - 26) / 12) << 12;
11475         tmp[1] = tmp[0] + 0x1000;
11476         tmp[2] = tmp[0] + 0x2000;
11477
11478         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11479         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11480 }
11481
11482 static void
11483 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11484 {
11485         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11486         int i;
11487         static const uint16_t addr[] = {
11488                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11489                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11490                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11491                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11492                 BWN_PHY_OFDM(0xcf),
11493         };
11494         static const uint16_t val[] = {
11495                 0xde5e, 0xe832, 0xe331, 0x4d26,
11496                 0x0026, 0x1420, 0x0020, 0xfe08,
11497                 0x0008,
11498         };
11499
11500         for (i = 0; i < N(addr); i++) {
11501                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11502                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11503         }
11504 }
11505
11506 static void
11507 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11508 {
11509         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11510         struct bwn_softc *sc = mac->mac_sc;
11511         uint16_t ctl;
11512
11513         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11514         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11515         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11516                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11517                 break;
11518         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11519                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11520                 break;
11521         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11522                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11523                 break;
11524         default:
11525                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11526                 device_printf(sc->sc_dev, "unknown command mode\n");
11527                 break;
11528         }
11529 }
11530
11531 static void
11532 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11533 {
11534         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11535         uint16_t ctl;
11536         uint8_t old;
11537
11538         bwn_phy_lp_get_txpctlmode(mac);
11539         old = plp->plp_txpctlmode;
11540         if (old == mode)
11541                 return;
11542         plp->plp_txpctlmode = mode;
11543
11544         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11545                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11546                     plp->plp_tssiidx);
11547                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11548                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11549
11550                 /* disable TX GAIN override */
11551                 if (mac->mac_phy.rev < 2)
11552                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11553                 else {
11554                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11555                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11556                 }
11557                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11558
11559                 plp->plp_txpwridx = -1;
11560         }
11561         if (mac->mac_phy.rev >= 2) {
11562                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11563                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11564                 else
11565                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11566         }
11567
11568         /* writes TX Power Control mode */
11569         switch (plp->plp_txpctlmode) {
11570         case BWN_PHYLP_TXPCTL_OFF:
11571                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11572                 break;
11573         case BWN_PHYLP_TXPCTL_ON_HW:
11574                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11575                 break;
11576         case BWN_PHYLP_TXPCTL_ON_SW:
11577                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11578                 break;
11579         default:
11580                 ctl = 0;
11581                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11582         }
11583         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11584             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11585 }
11586
11587 static void
11588 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11589 {
11590         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11591         struct bwn_softc *sc = mac->mac_sc;
11592         const unsigned int size = 256;
11593         struct bwn_txgain tg;
11594         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11595         uint16_t tssinpt, tssiidx, value[2];
11596         uint8_t mode;
11597         int8_t txpwridx;
11598
11599         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11600             M_NOWAIT | M_ZERO);
11601         if (tabs == NULL) {
11602                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11603                 return;
11604         }
11605
11606         bwn_phy_lp_get_txpctlmode(mac);
11607         mode = plp->plp_txpctlmode;
11608         txpwridx = plp->plp_txpwridx;
11609         tssinpt = plp->plp_tssinpt;
11610         tssiidx = plp->plp_tssiidx;
11611
11612         bwn_tab_read_multi(mac,
11613             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11614             BWN_TAB_4(7, 0x140), size, tabs);
11615
11616         bwn_phy_lp_tblinit(mac);
11617         bwn_phy_lp_bbinit(mac);
11618         bwn_phy_lp_txpctl_init(mac);
11619         bwn_phy_lp_rf_onoff(mac, 1);
11620         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11621
11622         bwn_tab_write_multi(mac,
11623             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11624             BWN_TAB_4(7, 0x140), size, tabs);
11625
11626         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11627         plp->plp_tssinpt = tssinpt;
11628         plp->plp_tssiidx = tssiidx;
11629         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11630         if (txpwridx != -1) {
11631                 /* set TX power by index */
11632                 plp->plp_txpwridx = txpwridx;
11633                 bwn_phy_lp_get_txpctlmode(mac);
11634                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11635                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11636                 if (mac->mac_phy.rev >= 2) {
11637                         rxcomp = bwn_tab_read(mac,
11638                             BWN_TAB_4(7, txpwridx + 320));
11639                         txgain = bwn_tab_read(mac,
11640                             BWN_TAB_4(7, txpwridx + 192));
11641                         tg.tg_pad = (txgain >> 16) & 0xff;
11642                         tg.tg_gm = txgain & 0xff;
11643                         tg.tg_pga = (txgain >> 8) & 0xff;
11644                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11645                         bwn_phy_lp_set_txgain(mac, &tg);
11646                 } else {
11647                         rxcomp = bwn_tab_read(mac,
11648                             BWN_TAB_4(10, txpwridx + 320));
11649                         txgain = bwn_tab_read(mac,
11650                             BWN_TAB_4(10, txpwridx + 192));
11651                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11652                             0xf800, (txgain >> 4) & 0x7fff);
11653                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11654                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11655                 }
11656                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11657
11658                 /* set TX IQCC */
11659                 value[0] = (rxcomp >> 10) & 0x3ff;
11660                 value[1] = rxcomp & 0x3ff;
11661                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11662
11663                 coeff = bwn_tab_read(mac,
11664                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11665                     BWN_TAB_4(10, txpwridx + 448));
11666                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11667                 if (mac->mac_phy.rev >= 2) {
11668                         rfpwr = bwn_tab_read(mac,
11669                             BWN_TAB_4(7, txpwridx + 576));
11670                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11671                             rfpwr & 0xffff);
11672                 }
11673                 bwn_phy_lp_set_txgain_override(mac);
11674         }
11675         if (plp->plp_rccap)
11676                 bwn_phy_lp_set_rccap(mac);
11677         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11678         bwn_phy_lp_set_txpctlmode(mac, mode);
11679         free(tabs, M_DEVBUF);
11680 }
11681
11682 static void
11683 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11684 {
11685         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11686         int i;
11687         static const uint16_t addr[] = {
11688                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11689                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11690                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11691                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11692                 BWN_PHY_OFDM(0xcf),
11693         };
11694
11695         for (i = 0; i < N(addr); i++)
11696                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11697 }
11698
11699 static void
11700 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11701 {
11702         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11703
11704         if (mac->mac_phy.rev < 2) {
11705                 bwn_phy_lp_tblinit_r01(mac);
11706                 bwn_phy_lp_tblinit_txgain(mac);
11707                 bwn_phy_lp_set_gaintbl(mac, freq);
11708                 return;
11709         }
11710
11711         bwn_phy_lp_tblinit_r2(mac);
11712         bwn_phy_lp_tblinit_txgain(mac);
11713 }
11714
11715 struct bwn_wpair {
11716         uint16_t                reg;
11717         uint16_t                value;
11718 };
11719
11720 struct bwn_smpair {
11721         uint16_t                offset;
11722         uint16_t                mask;
11723         uint16_t                set;
11724 };
11725
11726 static void
11727 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11728 {
11729         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11730         struct bwn_softc *sc = mac->mac_sc;
11731         struct ifnet *ifp = sc->sc_ifp;
11732         struct ieee80211com *ic = ifp->if_l2com;
11733         static const struct bwn_wpair v1[] = {
11734                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11735                 { BWN_PHY_AFE_CTL, 0x8800 },
11736                 { BWN_PHY_AFE_CTL_OVR, 0 },
11737                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11738                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11739                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11740                 { BWN_PHY_OFDM(0xf9), 0 },
11741                 { BWN_PHY_TR_LOOKUP_1, 0 }
11742         };
11743         static const struct bwn_smpair v2[] = {
11744                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11745                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11746                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11747                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11748                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11749         };
11750         static const struct bwn_smpair v3[] = {
11751                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11752                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11753                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11754                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11755                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11756                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11757                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11758                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11759                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11760                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11761
11762         };
11763         int i;
11764
11765         for (i = 0; i < N(v1); i++)
11766                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11767         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11768         for (i = 0; i < N(v2); i++)
11769                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11770
11771         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11772         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11773         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11774         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11775                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11776                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11777         } else {
11778                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11779         }
11780         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11781         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11782         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11783         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11784         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11785         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11786         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11787         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11788         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11789         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11790         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11791         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11792             (siba_get_chiprev(sc->sc_dev) == 0)) {
11793                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11794                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11795         } else {
11796                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11797                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11798         }
11799         for (i = 0; i < N(v3); i++)
11800                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11801         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11802             (siba_get_chiprev(sc->sc_dev) == 0)) {
11803                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11804                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11805         }
11806
11807         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11808                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11809                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11810                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11811                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11812                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11813                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11814         } else
11815                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11816
11817         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11818         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11819         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11820         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11821         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11822         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11823         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11824             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11825             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11826
11827         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11828             (siba_get_chiprev(sc->sc_dev) == 0)) {
11829                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11830                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11831                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11832         }
11833
11834         bwn_phy_lp_digflt_save(mac);
11835 }
11836
11837 static void
11838 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11839 {
11840         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11841         struct bwn_softc *sc = mac->mac_sc;
11842         struct ifnet *ifp = sc->sc_ifp;
11843         struct ieee80211com *ic = ifp->if_l2com;
11844         static const struct bwn_smpair v1[] = {
11845                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11846                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11847                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11848                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11849                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11850                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11851                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11852         };
11853         static const struct bwn_smpair v2[] = {
11854                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11855                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11856                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11857                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11858                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11859                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11860                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11861                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11862                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11863                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11864                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11865                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11866                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11867                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11868                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11869                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11870         };
11871         static const struct bwn_smpair v3[] = {
11872                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11873                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11874                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11875                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11876                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11877                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11878                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11879                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11880         };
11881         static const struct bwn_smpair v4[] = {
11882                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11883                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11884                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11885                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11886                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11887                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11888                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11889                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11890         };
11891         static const struct bwn_smpair v5[] = {
11892                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11893                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11894                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11895                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11896                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11897                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11898                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11899                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11900         };
11901         int i;
11902         uint16_t tmp, tmp2;
11903
11904         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11905         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11906         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11907         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11908         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11909         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11910         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11911         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11912         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11913         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11914         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11915         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11916         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11917         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11918         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11919         for (i = 0; i < N(v1); i++)
11920                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11921         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11922             0xff00, plp->plp_rxpwroffset);
11923         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11924             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11925            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11926                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11927                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11928                 if (mac->mac_phy.rev == 0)
11929                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11930                             0xffcf, 0x0010);
11931                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11932         } else {
11933                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11934                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11935                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11936         }
11937         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11938         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11939         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11940                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11941         else
11942                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11943         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11944         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11945             0xfff9, (plp->plp_bxarch << 1));
11946         if (mac->mac_phy.rev == 1 &&
11947             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11948                 for (i = 0; i < N(v2); i++)
11949                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11950                             v2[i].set);
11951         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11952             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11953             ((mac->mac_phy.rev == 0) &&
11954              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11955                 for (i = 0; i < N(v3); i++)
11956                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11957                             v3[i].set);
11958         } else if (mac->mac_phy.rev == 1 ||
11959                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11960                 for (i = 0; i < N(v4); i++)
11961                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11962                             v4[i].set);
11963         } else {
11964                 for (i = 0; i < N(v5); i++)
11965                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11966                             v5[i].set);
11967         }
11968         if (mac->mac_phy.rev == 1 &&
11969             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11970                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11971                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11972                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11973                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11974         }
11975         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11976             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11977             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11978                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11979                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11980                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11981                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11982         }
11983         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11984                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11985                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11986                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11987                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11988                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11989                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11990                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11991                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11992         } else {
11993                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11994                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11995         }
11996         if (mac->mac_phy.rev == 1) {
11997                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11998                 tmp2 = (tmp & 0x03e0) >> 5;
11999                 tmp2 |= tmp2 << 5;
12000                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12001                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12002                 tmp2 = (tmp & 0x1f00) >> 8;
12003                 tmp2 |= tmp2 << 5;
12004                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12005                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12006                 tmp2 = tmp & 0x00ff;
12007                 tmp2 |= tmp << 8;
12008                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12009         }
12010 }
12011
12012 struct bwn_b2062_freq {
12013         uint16_t                freq;
12014         uint8_t                 value[6];
12015 };
12016
12017 static void
12018 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12019 {
12020 #define CALC_CTL7(freq, div)                                            \
12021         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12022 #define CALC_CTL18(freq, div)                                           \
12023         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12024 #define CALC_CTL19(freq, div)                                           \
12025         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12026         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12027         struct bwn_softc *sc = mac->mac_sc;
12028         struct ifnet *ifp = sc->sc_ifp;
12029         struct ieee80211com *ic = ifp->if_l2com;
12030         static const struct bwn_b2062_freq freqdata_tab[] = {
12031                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12032                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12033                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12034                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12035                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12036                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12037         };
12038         static const struct bwn_wpair v1[] = {
12039                 { BWN_B2062_N_TXCTL3, 0 },
12040                 { BWN_B2062_N_TXCTL4, 0 },
12041                 { BWN_B2062_N_TXCTL5, 0 },
12042                 { BWN_B2062_N_TXCTL6, 0 },
12043                 { BWN_B2062_N_PDNCTL0, 0x40 },
12044                 { BWN_B2062_N_PDNCTL0, 0 },
12045                 { BWN_B2062_N_CALIB_TS, 0x10 },
12046                 { BWN_B2062_N_CALIB_TS, 0 }
12047         };
12048         const struct bwn_b2062_freq *f = NULL;
12049         uint32_t xtalfreq, ref;
12050         unsigned int i;
12051
12052         bwn_phy_lp_b2062_tblinit(mac);
12053
12054         for (i = 0; i < N(v1); i++)
12055                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12056         if (mac->mac_phy.rev > 0)
12057                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12058                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12059         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12060                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12061         else
12062                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12063
12064         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12065             ("%s:%d: fail", __func__, __LINE__));
12066         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12067         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12068
12069         if (xtalfreq <= 30000000) {
12070                 plp->plp_div = 1;
12071                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12072         } else {
12073                 plp->plp_div = 2;
12074                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12075         }
12076
12077         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12078             CALC_CTL7(xtalfreq, plp->plp_div));
12079         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12080             CALC_CTL18(xtalfreq, plp->plp_div));
12081         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12082             CALC_CTL19(xtalfreq, plp->plp_div));
12083
12084         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12085         ref &= 0xffff;
12086         for (i = 0; i < N(freqdata_tab); i++) {
12087                 if (ref < freqdata_tab[i].freq) {
12088                         f = &freqdata_tab[i];
12089                         break;
12090                 }
12091         }
12092         if (f == NULL)
12093                 f = &freqdata_tab[N(freqdata_tab) - 1];
12094         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12095             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12096         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12097             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12098         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12099         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12100 #undef CALC_CTL7
12101 #undef CALC_CTL18
12102 #undef CALC_CTL19
12103 }
12104
12105 static void
12106 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12107 {
12108
12109         bwn_phy_lp_b2063_tblinit(mac);
12110         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12111         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12112         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12113         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12114         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12115         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12116         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12117         if (mac->mac_phy.rev == 2) {
12118                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12119                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12120                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12121         } else {
12122                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12123                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12124         }
12125 }
12126
12127 static void
12128 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12129 {
12130         struct bwn_softc *sc = mac->mac_sc;
12131         static const struct bwn_wpair v1[] = {
12132                 { BWN_B2063_RX_BB_SP8, 0x0 },
12133                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12134                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12135                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12136                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12137                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12138                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12139                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12140         };
12141         static const struct bwn_wpair v2[] = {
12142                 { BWN_B2063_TX_BB_SP3, 0x0 },
12143                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12144                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12145                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12146                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12147         };
12148         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12149         int i;
12150         uint8_t tmp;
12151
12152         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12153
12154         for (i = 0; i < 2; i++)
12155                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12156         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12157         for (i = 2; i < N(v1); i++)
12158                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12159         for (i = 0; i < 10000; i++) {
12160                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12161                         break;
12162                 DELAY(1000);
12163         }
12164
12165         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12166                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12167
12168         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12169
12170         for (i = 0; i < N(v2); i++)
12171                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12172         if (freqxtal == 24000000) {
12173                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12174                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12175         } else {
12176                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12177                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12178         }
12179         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12180         for (i = 0; i < 10000; i++) {
12181                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12182                         break;
12183                 DELAY(1000);
12184         }
12185         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12186                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12187         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12188 }
12189
12190 static void
12191 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12192 {
12193         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12194         struct bwn_softc *sc = mac->mac_sc;
12195         struct bwn_phy_lp_iq_est ie;
12196         struct bwn_txgain tx_gains;
12197         static const uint32_t pwrtbl[21] = {
12198                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12199                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12200                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12201                 0x0004c, 0x0002c, 0x0001a,
12202         };
12203         uint32_t npwr, ipwr, sqpwr, tmp;
12204         int loopback, i, j, sum, error;
12205         uint16_t save[7];
12206         uint8_t txo, bbmult, txpctlmode;
12207
12208         error = bwn_phy_lp_switch_channel(mac, 7);
12209         if (error)
12210                 device_printf(sc->sc_dev,
12211                     "failed to change channel to 7 (%d)\n", error);
12212         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12213         bbmult = bwn_phy_lp_get_bbmult(mac);
12214         if (txo)
12215                 tx_gains = bwn_phy_lp_get_txgain(mac);
12216
12217         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12218         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12219         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12220         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12221         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12222         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12223         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12224
12225         bwn_phy_lp_get_txpctlmode(mac);
12226         txpctlmode = plp->plp_txpctlmode;
12227         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12228
12229         /* disable CRS */
12230         bwn_phy_lp_set_deaf(mac, 1);
12231         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12232         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12233         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12234         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12235         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12236         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12237         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12238         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12239         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12240         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12241         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12242         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12243         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12244         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12245         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12246         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12247         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12248         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12249         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12250         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12251         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12252         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12253         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12254         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12255
12256         loopback = bwn_phy_lp_loopback(mac);
12257         if (loopback == -1)
12258                 goto done;
12259         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12260         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12261         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12262         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12263         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12264
12265         tmp = 0;
12266         memset(&ie, 0, sizeof(ie));
12267         for (i = 128; i <= 159; i++) {
12268                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12269                 sum = 0;
12270                 for (j = 5; j <= 25; j++) {
12271                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12272                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12273                                 goto done;
12274                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12275                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12276                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12277                             12);
12278                         sum += ((ipwr - npwr) * (ipwr - npwr));
12279                         if ((i == 128) || (sum < tmp)) {
12280                                 plp->plp_rccap = i;
12281                                 tmp = sum;
12282                         }
12283                 }
12284         }
12285         bwn_phy_lp_ddfs_turnoff(mac);
12286 done:
12287         /* restore CRS */
12288         bwn_phy_lp_clear_deaf(mac, 1);
12289         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12290         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12291
12292         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12293         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12294         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12295         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12296         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12297         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12298         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12299
12300         bwn_phy_lp_set_bbmult(mac, bbmult);
12301         if (txo)
12302                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12303         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12304         if (plp->plp_rccap)
12305                 bwn_phy_lp_set_rccap(mac);
12306 }
12307
12308 static void
12309 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12310 {
12311         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12312         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12313
12314         if (mac->mac_phy.rev == 1)
12315                 rc_cap = MIN(rc_cap + 5, 15);
12316
12317         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12318             MAX(plp->plp_rccap - 4, 0x80));
12319         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12320         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12321             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12322 }
12323
12324 static uint32_t
12325 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12326 {
12327         uint32_t i, q, r;
12328
12329         if (div == 0)
12330                 return (0);
12331
12332         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12333                 q <<= 1;
12334                 if (r << 1 >= div) {
12335                         q++;
12336                         r = (r << 1) - div;
12337                 }
12338         }
12339         if (r << 1 >= div)
12340                 q++;
12341         return (q);
12342 }
12343
12344 static void
12345 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12346 {
12347         struct bwn_softc *sc = mac->mac_sc;
12348
12349         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12350         DELAY(20);
12351         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12352                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12353                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12354         } else {
12355                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12356         }
12357         DELAY(5);
12358 }
12359
12360 static void
12361 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12362 {
12363
12364         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12365         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12366         DELAY(200);
12367 }
12368
12369 static void
12370 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12371 {
12372 #define FLAG_A  0x01
12373 #define FLAG_G  0x02
12374         struct bwn_softc *sc = mac->mac_sc;
12375         struct ifnet *ifp = sc->sc_ifp;
12376         struct ieee80211com *ic = ifp->if_l2com;
12377         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12378                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12379                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12380                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12381                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12382                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12383                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12384                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12385                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12386                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12387                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12388                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12389                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12390                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12391                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12392                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12393                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12399                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12425         };
12426         const struct bwn_b206x_rfinit_entry *br;
12427         unsigned int i;
12428
12429         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12430                 br = &bwn_b2062_init_tab[i];
12431                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12432                         if (br->br_flags & FLAG_G)
12433                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12434                 } else {
12435                         if (br->br_flags & FLAG_A)
12436                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12437                 }
12438         }
12439 #undef FLAG_A
12440 #undef FLAG_B
12441 }
12442
12443 static void
12444 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12445 {
12446 #define FLAG_A  0x01
12447 #define FLAG_G  0x02
12448         struct bwn_softc *sc = mac->mac_sc;
12449         struct ifnet *ifp = sc->sc_ifp;
12450         struct ieee80211com *ic = ifp->if_l2com;
12451         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12452                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12453                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12454                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12455                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12456                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12457                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12458                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12459                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12460                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12461                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12462                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12464                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12465                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12466                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12467                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12468                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12469                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12470                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12471                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12472                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12473                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12474                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12475                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12476                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12477                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12478                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12479                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12482                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12483                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12485                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12486                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12487                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12488                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12489                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12493                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12494         };
12495         const struct bwn_b206x_rfinit_entry *br;
12496         unsigned int i;
12497
12498         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12499                 br = &bwn_b2063_init_tab[i];
12500                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12501                         if (br->br_flags & FLAG_G)
12502                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12503                 } else {
12504                         if (br->br_flags & FLAG_A)
12505                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12506                 }
12507         }
12508 #undef FLAG_A
12509 #undef FLAG_B
12510 }
12511
12512 static void
12513 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12514     int count, void *_data)
12515 {
12516         unsigned int i;
12517         uint32_t offset, type;
12518         uint8_t *data = _data;
12519
12520         type = BWN_TAB_GETTYPE(typenoffset);
12521         offset = BWN_TAB_GETOFFSET(typenoffset);
12522         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12523
12524         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12525
12526         for (i = 0; i < count; i++) {
12527                 switch (type) {
12528                 case BWN_TAB_8BIT:
12529                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12530                         data++;
12531                         break;
12532                 case BWN_TAB_16BIT:
12533                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12534                             BWN_PHY_TABLEDATALO);
12535                         data += 2;
12536                         break;
12537                 case BWN_TAB_32BIT:
12538                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12539                             BWN_PHY_TABLEDATAHI);
12540                         *((uint32_t *)data) <<= 16;
12541                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12542                             BWN_PHY_TABLEDATALO);
12543                         data += 4;
12544                         break;
12545                 default:
12546                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12547                 }
12548         }
12549 }
12550
12551 static void
12552 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12553     int count, const void *_data)
12554 {
12555         uint32_t offset, type, value;
12556         const uint8_t *data = _data;
12557         unsigned int i;
12558
12559         type = BWN_TAB_GETTYPE(typenoffset);
12560         offset = BWN_TAB_GETOFFSET(typenoffset);
12561         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12562
12563         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12564
12565         for (i = 0; i < count; i++) {
12566                 switch (type) {
12567                 case BWN_TAB_8BIT:
12568                         value = *data;
12569                         data++;
12570                         KASSERT(!(value & ~0xff),
12571                             ("%s:%d: fail", __func__, __LINE__));
12572                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12573                         break;
12574                 case BWN_TAB_16BIT:
12575                         value = *((const uint16_t *)data);
12576                         data += 2;
12577                         KASSERT(!(value & ~0xffff),
12578                             ("%s:%d: fail", __func__, __LINE__));
12579                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12580                         break;
12581                 case BWN_TAB_32BIT:
12582                         value = *((const uint32_t *)data);
12583                         data += 4;
12584                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12585                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12586                         break;
12587                 default:
12588                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12589                 }
12590         }
12591 }
12592
12593 static struct bwn_txgain
12594 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12595 {
12596         struct bwn_txgain tg;
12597         uint16_t tmp;
12598
12599         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12600         if (mac->mac_phy.rev < 2) {
12601                 tmp = BWN_PHY_READ(mac,
12602                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12603                 tg.tg_gm = tmp & 0x0007;
12604                 tg.tg_pga = (tmp & 0x0078) >> 3;
12605                 tg.tg_pad = (tmp & 0x780) >> 7;
12606                 return (tg);
12607         }
12608
12609         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12610         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12611         tg.tg_gm = tmp & 0xff;
12612         tg.tg_pga = (tmp >> 8) & 0xff;
12613         return (tg);
12614 }
12615
12616 static uint8_t
12617 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12618 {
12619
12620         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12621 }
12622
12623 static void
12624 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12625 {
12626         uint16_t pa;
12627
12628         if (mac->mac_phy.rev < 2) {
12629                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12630                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12631                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12632                 bwn_phy_lp_set_txgain_override(mac);
12633                 return;
12634         }
12635
12636         pa = bwn_phy_lp_get_pa_gain(mac);
12637         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12638             (tg->tg_pga << 8) | tg->tg_gm);
12639         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12640             tg->tg_pad | (pa << 6));
12641         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12642         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12643             tg->tg_pad | (pa << 8));
12644         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12645         bwn_phy_lp_set_txgain_override(mac);
12646 }
12647
12648 static void
12649 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12650 {
12651
12652         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12653 }
12654
12655 static void
12656 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12657 {
12658         uint16_t trsw = (tx << 1) | rx;
12659
12660         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12661         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12662 }
12663
12664 static void
12665 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12666 {
12667         struct bwn_softc *sc = mac->mac_sc;
12668         struct ifnet *ifp = sc->sc_ifp;
12669         struct ieee80211com *ic = ifp->if_l2com;
12670         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12671
12672         if (mac->mac_phy.rev < 2) {
12673                 trsw = gain & 0x1;
12674                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12675                 ext_lna = (gain & 2) >> 1;
12676
12677                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12678                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12679                     0xfbff, ext_lna << 10);
12680                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12681                     0xf7ff, ext_lna << 11);
12682                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12683         } else {
12684                 low_gain = gain & 0xffff;
12685                 high_gain = (gain >> 16) & 0xf;
12686                 ext_lna = (gain >> 21) & 0x1;
12687                 trsw = ~(gain >> 20) & 0x1;
12688
12689                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12690                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12691                     0xfdff, ext_lna << 9);
12692                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12693                     0xfbff, ext_lna << 10);
12694                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12695                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12696                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12697                         tmp = (gain >> 2) & 0x3;
12698                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12699                             0xe7ff, tmp<<11);
12700                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12701                             tmp << 3);
12702                 }
12703         }
12704
12705         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12706         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12707         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12708         if (mac->mac_phy.rev >= 2) {
12709                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12710                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12711                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12712                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12713                 }
12714                 return;
12715         }
12716         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12717 }
12718
12719 static void
12720 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12721 {
12722         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12723
12724         if (user)
12725                 plp->plp_crsusr_off = 1;
12726         else
12727                 plp->plp_crssys_off = 1;
12728
12729         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12730 }
12731
12732 static void
12733 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12734 {
12735         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12736         struct bwn_softc *sc = mac->mac_sc;
12737         struct ifnet *ifp = sc->sc_ifp;
12738         struct ieee80211com *ic = ifp->if_l2com;
12739
12740         if (user)
12741                 plp->plp_crsusr_off = 0;
12742         else
12743                 plp->plp_crssys_off = 0;
12744
12745         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12746                 return;
12747
12748         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12749                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12750         else
12751                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12752 }
12753
12754 static unsigned int
12755 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12756 {
12757         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12758         static uint8_t sqrt_table[256] = {
12759                 10, 14, 17, 20, 22, 24, 26, 28,
12760                 30, 31, 33, 34, 36, 37, 38, 40,
12761                 41, 42, 43, 44, 45, 46, 47, 48,
12762                 50, 50, 51, 52, 53, 54, 55, 56,
12763                 57, 58, 59, 60, 60, 61, 62, 63,
12764                 64, 64, 65, 66, 67, 67, 68, 69,
12765                 70, 70, 71, 72, 72, 73, 74, 74,
12766                 75, 76, 76, 77, 78, 78, 79, 80,
12767                 80, 81, 81, 82, 83, 83, 84, 84,
12768                 85, 86, 86, 87, 87, 88, 88, 89,
12769                 90, 90, 91, 91, 92, 92, 93, 93,
12770                 94, 94, 95, 95, 96, 96, 97, 97,
12771                 98, 98, 99, 100, 100, 100, 101, 101,
12772                 102, 102, 103, 103, 104, 104, 105, 105,
12773                 106, 106, 107, 107, 108, 108, 109, 109,
12774                 110, 110, 110, 111, 111, 112, 112, 113,
12775                 113, 114, 114, 114, 115, 115, 116, 116,
12776                 117, 117, 117, 118, 118, 119, 119, 120,
12777                 120, 120, 121, 121, 122, 122, 122, 123,
12778                 123, 124, 124, 124, 125, 125, 126, 126,
12779                 126, 127, 127, 128, 128, 128, 129, 129,
12780                 130, 130, 130, 131, 131, 131, 132, 132,
12781                 133, 133, 133, 134, 134, 134, 135, 135,
12782                 136, 136, 136, 137, 137, 137, 138, 138,
12783                 138, 139, 139, 140, 140, 140, 141, 141,
12784                 141, 142, 142, 142, 143, 143, 143, 144,
12785                 144, 144, 145, 145, 145, 146, 146, 146,
12786                 147, 147, 147, 148, 148, 148, 149, 149,
12787                 150, 150, 150, 150, 151, 151, 151, 152,
12788                 152, 152, 153, 153, 153, 154, 154, 154,
12789                 155, 155, 155, 156, 156, 156, 157, 157,
12790                 157, 158, 158, 158, 159, 159, 159, 160
12791         };
12792
12793         if (x == 0)
12794                 return (0);
12795         if (x >= 256) {
12796                 unsigned int tmp;
12797
12798                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12799                         /* do nothing */ ;
12800                 return (tmp);
12801         }
12802         return (sqrt_table[x - 1] / 10);
12803 }
12804
12805 static int
12806 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12807 {
12808 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12809         int _t;                                                         \
12810         _t = _x - 20;                                                   \
12811         if (_t >= 0) {                                                  \
12812                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12813         } else {                                                        \
12814                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12815         }                                                               \
12816 } while (0)
12817 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12818         int _t;                                                         \
12819         _t = _x - 11;                                                   \
12820         if (_t >= 0)                                                    \
12821                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12822         else                                                            \
12823                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12824 } while (0)
12825         struct bwn_phy_lp_iq_est ie;
12826         uint16_t v0, v1;
12827         int tmp[2], ret;
12828
12829         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12830         v0 = v1 >> 8;
12831         v1 |= 0xff;
12832
12833         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12834         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12835
12836         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12837         if (ret == 0)
12838                 goto done;
12839
12840         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12841                 ret = 0;
12842                 goto done;
12843         }
12844
12845         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12846         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12847
12848         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12849         v0 = tmp[0] >> 3;
12850         v1 = tmp[1] >> 4;
12851 done:
12852         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12853         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12854         return ret;
12855 #undef CALC_COEFF
12856 #undef CALC_COEFF2
12857 }
12858
12859 static void
12860 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12861 {
12862         static const uint16_t noisescale[] = {
12863                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12864                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12865                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12866                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12867                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12868         };
12869         static const uint16_t crsgainnft[] = {
12870                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12871                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12872                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12873                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12874                 0x013d,
12875         };
12876         static const uint16_t filterctl[] = {
12877                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12878                 0xff53, 0x0127,
12879         };
12880         static const uint32_t psctl[] = {
12881                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12882                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12883                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12884                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12885                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12886                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12887                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12888                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12889         };
12890         static const uint16_t ofdmcckgain_r0[] = {
12891                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12892                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12893                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12894                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12895                 0x755d,
12896         };
12897         static const uint16_t ofdmcckgain_r1[] = {
12898                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12899                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12900                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12901                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12902                 0x755d,
12903         };
12904         static const uint16_t gaindelta[] = {
12905                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12906                 0x0000,
12907         };
12908         static const uint32_t txpwrctl[] = {
12909                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12910                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12911                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12912                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12913                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12914                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12915                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12916                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12917                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12918                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12919                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12920                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12921                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12922                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12923                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12924                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12925                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12926                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12948                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12949                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12950                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12951                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12952                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12953                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12954                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12955                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12956                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12957                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12958                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12959                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12960                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12961                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12962                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12963                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12964                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12965                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12966                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12967                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12968                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12969                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12970                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12971                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12972                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12973                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12974                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
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, 0x000000ff, 0x000002fc,
12999                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13000                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13001                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13002                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13003                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13004                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13005                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13006                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13007                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13008                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13009                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13010                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13011                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13012                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13013                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13014                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13015                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13016                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13017                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13018                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13019                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13020                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13021                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13022                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13023                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13024                 0x00000702,
13025         };
13026
13027         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13028
13029         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13030             bwn_tab_sigsq_tbl);
13031         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13032         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13033         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13034         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13035         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13036             bwn_tab_pllfrac_tbl);
13037         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13038             bwn_tabl_iqlocal_tbl);
13039         if (mac->mac_phy.rev == 0) {
13040                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13041                     ofdmcckgain_r0);
13042                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13043                     ofdmcckgain_r0);
13044         } else {
13045                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13046                     ofdmcckgain_r1);
13047                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13048                     ofdmcckgain_r1);
13049         }
13050         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13051         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13052 }
13053
13054 static void
13055 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13056 {
13057         struct bwn_softc *sc = mac->mac_sc;
13058         int i;
13059         static const uint16_t noisescale[] = {
13060                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13061                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13062                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13063                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13067         };
13068         static const uint32_t filterctl[] = {
13069                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13070                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13071         };
13072         static const uint32_t psctl[] = {
13073                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13074                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13075                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13076                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13077         };
13078         static const uint32_t gainidx[] = {
13079                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13080                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13081                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13082                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13083                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13084                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13085                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13086                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13087                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13088                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13089                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13090                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13091                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13092                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13093                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13094                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13095                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13096                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13097                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13098                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13099                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13100                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13101                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13102                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13103                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13104                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13105                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13106                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13107                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13108                 0x0000001a, 0x64ca55ad, 0x0000001a
13109         };
13110         static const uint16_t auxgainidx[] = {
13111                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13112                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13113                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13114                 0x0004, 0x0016
13115         };
13116         static const uint16_t swctl[] = {
13117                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13118                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13119                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13120                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13121                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13122                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13123                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13124                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13125         };
13126         static const uint8_t hf[] = {
13127                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13128                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13129         };
13130         static const uint32_t gainval[] = {
13131                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13132                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13133                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13134                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13135                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13136                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13137                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13138                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13139                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13141                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13142                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13143                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13144                 0x000000f1, 0x00000000, 0x00000000
13145         };
13146         static const uint16_t gain[] = {
13147                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13148                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13149                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13150                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13151                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13152                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13153                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13154                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13155                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13156                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13157                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13158                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13159         };
13160         static const uint32_t papdeps[] = {
13161                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13162                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13163                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13164                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13165                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13166                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13167                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13168                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13169                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13170                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13171                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13172                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13173                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13174         };
13175         static const uint32_t papdmult[] = {
13176                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13177                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13178                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13179                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13180                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13181                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13182                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13183                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13184                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13185                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13186                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13187                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13188                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13189         };
13190         static const uint32_t gainidx_a0[] = {
13191                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13192                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13193                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13194                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13195                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13196                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13197                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13198                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13199                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13200                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13201                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13202                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13203                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13204         };
13205         static const uint16_t auxgainidx_a0[] = {
13206                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13207                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13208                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13209                 0x0002, 0x0014
13210         };
13211         static const uint32_t gainval_a0[] = {
13212                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13213                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13214                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13215                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13216                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13217                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13218                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13219                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13220                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13221                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13222                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13223                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13224                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13225                 0x000000f7, 0x00000000, 0x00000000
13226         };
13227         static const uint16_t gain_a0[] = {
13228                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13229                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13230                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13231                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13232                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13233                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13234                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13235                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13236                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13237                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13238                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13239                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13240         };
13241
13242         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13243
13244         for (i = 0; i < 704; i++)
13245                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13246
13247         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13248             bwn_tab_sigsq_tbl);
13249         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13250         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13251         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13252         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13253         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13254         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13255         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13256         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13257         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13258         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13259             bwn_tab_pllfrac_tbl);
13260         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13261             bwn_tabl_iqlocal_tbl);
13262         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13263         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13264
13265         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13266             (siba_get_chiprev(sc->sc_dev) == 0)) {
13267                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13268                     gainidx_a0);
13269                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13270                     auxgainidx_a0);
13271                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13272                     gainval_a0);
13273                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13274         }
13275 }
13276
13277 static void
13278 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13279 {
13280         struct bwn_softc *sc = mac->mac_sc;
13281         struct ifnet *ifp = sc->sc_ifp;
13282         struct ieee80211com *ic = ifp->if_l2com;
13283         static struct bwn_txgain_entry txgain_r2[] = {
13284                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13285                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13286                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13287                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13288                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13289                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13290                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13291                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13292                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13293                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13294                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13295                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13296                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13297                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13298                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13299                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13300                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13301                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13302                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13303                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13304                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13305                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13306                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13307                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13308                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13309                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13310                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13311                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13312                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13313                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13314                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13315                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13316                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13317                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13318                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13319                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13320                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13321                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13322                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13323                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13324                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13325                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13326                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13327                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13328                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13329                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13330                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13331                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13332                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13333                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13334                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13335                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13336                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13337                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13338                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13339                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13340                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13341                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13342                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13343                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13344                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13345                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13346                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13347                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13348         };
13349         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13350                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13351                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13352                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13353                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13354                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13355                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13356                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13357                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13358                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13359                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13360                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13361                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13362                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13363                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13364                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13365                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13366                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13367                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13368                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13369                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13370                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13371                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13372                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13373                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13374                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13375                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13376                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13377                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13378                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13379                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13380                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13381                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13382                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13383                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13384                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13385                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13386                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13387                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13388                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13389                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13390                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13391                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13392                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13393                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13394                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13395                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13396                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13397                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13398                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13399                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13400                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13401                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13402                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13403                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13404                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13405                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13406                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13407                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13408                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13409                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13410                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13411                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13412                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13413                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13414         };
13415         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13416                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13417                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13418                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13419                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13420                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13421                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13422                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13423                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13424                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13425                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13426                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13427                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13428                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13429                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13430                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13431                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13432                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13433                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13434                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13435                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13436                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13437                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13438                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13439                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13440                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13441                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13442                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13443                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13444                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13445                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13446                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13447                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13448                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13449                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13450                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13451                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13452                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13453                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13454                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13455                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13456                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13457                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13458                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13459                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13460                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13461                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13462                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13463                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13464                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13465                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13466                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13467                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13468                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13469                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13470                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13471                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13472                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13473                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13474                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13475                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13476                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13477                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13478                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13479                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13480         };
13481         static struct bwn_txgain_entry txgain_r0[] = {
13482                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13483                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13484                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13485                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13486                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13487                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13488                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13489                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13490                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13491                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13492                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13493                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13494                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13495                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13496                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13497                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13498                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13499                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13500                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13501                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13502                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13503                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13504                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13505                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13506                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13507                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13508                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13509                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13510                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13511                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13512                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13513                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13514                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13515                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13516                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13517                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13518                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13519                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13520                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13521                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13522                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13523                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13524                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13525                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13526                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13527                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13528                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13529                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13530                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13531                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13532                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13533                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13534                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13535                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13536                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13537                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13538                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13539                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13540                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13541                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13542                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13543                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13544                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13545                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13546         };
13547         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13548                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13549                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13550                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13551                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13552                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13553                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13554                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13555                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13556                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13557                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13558                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13559                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13560                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13561                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13562                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13563                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13564                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13565                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13566                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13567                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13568                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13569                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13570                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13571                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13572                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13573                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13574                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13575                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13576                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13577                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13578                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13579                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13580                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13581                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13582                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13583                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13584                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13585                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13586                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13587                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13588                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13589                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13590                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13591                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13592                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13593                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13594                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13595                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13596                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13597                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13598                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13599                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13600                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13601                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13602                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13603                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13604                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13605                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13606                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13607                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13608                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13609                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13610                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13611                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13612         };
13613         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13614                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13615                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13616                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13617                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13618                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13619                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13620                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13621                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13622                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13623                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13624                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13625                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13626                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13627                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13628                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13629                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13630                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13631                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13632                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13633                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13634                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13635                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13636                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13637                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13638                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13639                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13640                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13641                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13642                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13643                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13644                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13645                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13646                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13647                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13648                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13649                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13650                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13651                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13652                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13653                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13654                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13655                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13656                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13657                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13658                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13659                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13660                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13661                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13662                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13663                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13664                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13665                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13666                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13667                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13668                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13669                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13670                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13671                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13672                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13673                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13674                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13675                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13676                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13677                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13678         };
13679         static struct bwn_txgain_entry txgain_r1[] = {
13680                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13681                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13682                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13683                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13684                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13685                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13686                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13687                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13688                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13689                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13690                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13691                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13692                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13693                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13694                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13695                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13696                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13697                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13698                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13699                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13700                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13701                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13702                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13703                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13704                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13705                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13706                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13707                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13708                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13709                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13710                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13711                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13712                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13713                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13714                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13715                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13716                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13717                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13718                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13719                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13720                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13721                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13722                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13723                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13724                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13725                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13726                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13727                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13728                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13729                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13730                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13731                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13732                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13733                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13734                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13735                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13736                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13737                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13738                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13739                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13740                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13741                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13742                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13743                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13744                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13745                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13746                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13747                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13748                 { 7, 11, 6, 0, 71 }
13749         };
13750         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13751                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13752                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13753                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13754                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13755                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13756                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13757                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13758                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13759                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13760                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13761                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13762                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13763                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13764                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13765                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13766                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13767                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13768                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13769                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13770                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13771                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13772                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13773                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13774                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13775                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13776                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13777                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13778                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13779                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13780                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13781                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13782                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13783                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13784                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13785                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13786                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13787                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13788                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13789                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13790                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13791                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13792                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13793                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13794                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13795                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13796                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13797                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13798                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13799                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13800                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13801                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13802                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13803                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13804                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13805                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13806                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13807                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13808                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13809                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13810                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13811                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13812                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13813                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13814                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13815         };
13816         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13817                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13818                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13819                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13820                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13821                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13822                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13823                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13824                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13825                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13826                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13827                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13828                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13829                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13830                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13831                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13832                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13833                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13834                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13835                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13836                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13837                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13838                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13839                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13840                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13841                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13842                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13843                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13844                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13845                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13846                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13847                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13848                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13849                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13850                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13851                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13852                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13853                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13854                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13855                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13856                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13857                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13858                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13859                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13860                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13861                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13862                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13863                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13864                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13865                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13866                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13867                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13868                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13869                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13870                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13871                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13872                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13873                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13874                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13875                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13876                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13877                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13878                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13879                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13880                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13881         };
13882
13883         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13884                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13885                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13886                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13887                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13888                             txgain_2ghz_r2);
13889                 else
13890                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13891                             txgain_5ghz_r2);
13892                 return;
13893         }
13894
13895         if (mac->mac_phy.rev == 0) {
13896                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13897                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13898                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13899                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13900                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13901                             txgain_2ghz_r0);
13902                 else
13903                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13904                             txgain_5ghz_r0);
13905                 return;
13906         }
13907
13908         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13909             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13910                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13911         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13912                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13913         else
13914                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13915 }
13916
13917 static void
13918 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13919 {
13920         uint32_t offset, type;
13921
13922         type = BWN_TAB_GETTYPE(typeoffset);
13923         offset = BWN_TAB_GETOFFSET(typeoffset);
13924         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13925
13926         switch (type) {
13927         case BWN_TAB_8BIT:
13928                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13929                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13930                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13931                 break;
13932         case BWN_TAB_16BIT:
13933                 KASSERT(!(value & ~0xffff),
13934                     ("%s:%d: fail", __func__, __LINE__));
13935                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13936                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13937                 break;
13938         case BWN_TAB_32BIT:
13939                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13940                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13941                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13942                 break;
13943         default:
13944                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13945         }
13946 }
13947
13948 static int
13949 bwn_phy_lp_loopback(struct bwn_mac *mac)
13950 {
13951         struct bwn_phy_lp_iq_est ie;
13952         int i, index = -1;
13953         uint32_t tmp;
13954
13955         memset(&ie, 0, sizeof(ie));
13956
13957         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13958         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13959         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13960         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13961         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13962         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13963         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13964         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13965         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13966         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13967         for (i = 0; i < 32; i++) {
13968                 bwn_phy_lp_set_rxgain_idx(mac, i);
13969                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13970                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13971                         continue;
13972                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13973                 if ((tmp > 4000) && (tmp < 10000)) {
13974                         index = i;
13975                         break;
13976                 }
13977         }
13978         bwn_phy_lp_ddfs_turnoff(mac);
13979         return (index);
13980 }
13981
13982 static void
13983 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13984 {
13985
13986         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13987 }
13988
13989 static void
13990 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13991     int incr1, int incr2, int scale_idx)
13992 {
13993
13994         bwn_phy_lp_ddfs_turnoff(mac);
13995         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13996         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13997         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13998         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13999         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14000         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14001         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14002         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14003         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14004         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14005 }
14006
14007 static uint8_t
14008 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14009     struct bwn_phy_lp_iq_est *ie)
14010 {
14011         int i;
14012
14013         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14014         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14015         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14016         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14017         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14018
14019         for (i = 0; i < 500; i++) {
14020                 if (!(BWN_PHY_READ(mac,
14021                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14022                         break;
14023                 DELAY(1000);
14024         }
14025         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14026                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14027                 return 0;
14028         }
14029
14030         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14031         ie->ie_iqprod <<= 16;
14032         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14033         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14034         ie->ie_ipwr <<= 16;
14035         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14036         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14037         ie->ie_qpwr <<= 16;
14038         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14039
14040         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14041         return 1;
14042 }
14043
14044 static uint32_t
14045 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14046 {
14047         uint32_t offset, type, value;
14048
14049         type = BWN_TAB_GETTYPE(typeoffset);
14050         offset = BWN_TAB_GETOFFSET(typeoffset);
14051         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14052
14053         switch (type) {
14054         case BWN_TAB_8BIT:
14055                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14056                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14057                 break;
14058         case BWN_TAB_16BIT:
14059                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14060                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14061                 break;
14062         case BWN_TAB_32BIT:
14063                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14064                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14065                 value <<= 16;
14066                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14067                 break;
14068         default:
14069                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14070                 value = 0;
14071         }
14072
14073         return (value);
14074 }
14075
14076 static void
14077 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14078 {
14079
14080         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14081         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14082 }
14083
14084 static void
14085 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14086 {
14087         uint16_t ctl;
14088
14089         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14090         ctl |= dac << 7;
14091         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14092 }
14093
14094 static void
14095 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14096 {
14097
14098         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14099         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14100 }
14101
14102 static void
14103 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14104 {
14105
14106         if (mac->mac_phy.rev < 2)
14107                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14108         else {
14109                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14110                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14111         }
14112         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14113 }
14114
14115 static uint16_t
14116 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14117 {
14118
14119         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14120 }
14121
14122 static uint8_t
14123 bwn_nbits(int32_t val)
14124 {
14125         uint32_t tmp;
14126         uint8_t nbits = 0;
14127
14128         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14129                 nbits++;
14130         return (nbits);
14131 }
14132
14133 static void
14134 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14135     struct bwn_txgain_entry *table)
14136 {
14137         int i;
14138
14139         for (i = offset; i < count; i++)
14140                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14141 }
14142
14143 static void
14144 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14145     struct bwn_txgain_entry data)
14146 {
14147
14148         if (mac->mac_phy.rev >= 2)
14149                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14150         else
14151                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14152 }
14153
14154 static void
14155 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14156     struct bwn_txgain_entry te)
14157 {
14158         struct bwn_softc *sc = mac->mac_sc;
14159         struct ifnet *ifp = sc->sc_ifp;
14160         struct ieee80211com *ic = ifp->if_l2com;
14161         uint32_t tmp;
14162
14163         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14164
14165         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14166         if (mac->mac_phy.rev >= 3) {
14167                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14168                     (0x10 << 24) : (0x70 << 24));
14169         } else {
14170                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14171                     (0x14 << 24) : (0x7f << 24));
14172         }
14173         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14174         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14175             te.te_bbmult << 20 | te.te_dac << 28);
14176 }
14177
14178 static void
14179 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14180     struct bwn_txgain_entry te)
14181 {
14182
14183         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14184
14185         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14186             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14187             te.te_dac);
14188         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14189 }
14190
14191 static void
14192 bwn_sysctl_node(struct bwn_softc *sc)
14193 {
14194         device_t dev = sc->sc_dev;
14195         struct bwn_mac *mac;
14196         struct bwn_stats *stats;
14197
14198         /* XXX assume that count of MAC is only 1. */
14199
14200         if ((mac = sc->sc_curmac) == NULL)
14201                 return;
14202         stats = &mac->mac_stats;
14203
14204         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14205             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14206             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14207         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14208             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14209             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14210         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14211             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14212             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14213
14214 #ifdef BWN_DEBUG
14215         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14216             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14217             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14218 #endif
14219 }
14220
14221 static device_method_t bwn_methods[] = {
14222         /* Device interface */
14223         DEVMETHOD(device_probe,         bwn_probe),
14224         DEVMETHOD(device_attach,        bwn_attach),
14225         DEVMETHOD(device_detach,        bwn_detach),
14226         DEVMETHOD(device_suspend,       bwn_suspend),
14227         DEVMETHOD(device_resume,        bwn_resume),
14228         KOBJMETHOD_END
14229 };
14230 static driver_t bwn_driver = {
14231         "bwn",
14232         bwn_methods,
14233         sizeof(struct bwn_softc)
14234 };
14235 static devclass_t bwn_devclass;
14236 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14237 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14238 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14239 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14240 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);