]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/dev/bwn/if_bwn.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
72
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
75
76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
77
78 /*
79  * Tunable & sysctl variables.
80  */
81
82 #ifdef BWN_DEBUG
83 static  int bwn_debug = 0;
84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
85     "Broadcom debugging printfs");
86 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
87 enum {
88         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
89         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
90         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
91         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
92         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
93         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
94         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
95         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
96         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
97         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
98         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
99         BWN_DEBUG_LED           = 0x00000800,   /* led management */
100         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
101         BWN_DEBUG_LO            = 0x00002000,   /* LO */
102         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
103         BWN_DEBUG_WME           = 0x00008000,   /* WME */
104         BWN_DEBUG_RF            = 0x00010000,   /* RF */
105         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
106         BWN_DEBUG_ANY           = 0xffffffff
107 };
108 #define DPRINTF(sc, m, fmt, ...) do {                   \
109         if (sc->sc_debug & (m))                         \
110                 printf(fmt, __VA_ARGS__);               \
111 } while (0)
112 #else
113 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
114 #endif
115
116 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
118     "uses Bad Frames Preemption");
119 static int      bwn_bluetooth = 1;
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
121     "turns on Bluetooth Coexistence");
122 static int      bwn_hwpctl = 0;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
124     "uses H/W power control");
125 static int      bwn_msi_disable = 0;            /* MSI disabled  */
126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
127 static int      bwn_usedma = 1;
128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
129     "uses DMA");
130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
131 static int      bwn_wme = 1;
132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
133     "uses WME support");
134
135 static int      bwn_attach_pre(struct bwn_softc *);
136 static int      bwn_attach_post(struct bwn_softc *);
137 static void     bwn_sprom_bugfixes(device_t);
138 static void     bwn_init(void *);
139 static int      bwn_init_locked(struct bwn_softc *);
140 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t);
141 static void     bwn_start(struct ifnet *);
142 static int      bwn_attach_core(struct bwn_mac *);
143 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
144 static int      bwn_phy_getinfo(struct bwn_mac *, int);
145 static int      bwn_chiptest(struct bwn_mac *);
146 static int      bwn_setup_channels(struct bwn_mac *, int, int);
147 static int      bwn_phy_g_attach(struct bwn_mac *);
148 static void     bwn_phy_g_detach(struct bwn_mac *);
149 static void     bwn_phy_g_init_pre(struct bwn_mac *);
150 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
151 static int      bwn_phy_g_init(struct bwn_mac *);
152 static void     bwn_phy_g_exit(struct bwn_mac *);
153 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
154 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
155                     uint16_t);
156 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
157 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
158                     uint16_t);
159 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
160 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
161 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
162 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
163 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
164 static int      bwn_phy_g_im(struct bwn_mac *, int);
165 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
166 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
167 static void     bwn_phy_g_task_15s(struct bwn_mac *);
168 static void     bwn_phy_g_task_60s(struct bwn_mac *);
169 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
170 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
171 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
172 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
173                     uint16_t);
174 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
175 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
176                     uint32_t);
177 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
178                     uint16_t);
179 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
180                     const struct bwn_channelinfo *, int);
181 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
182                     const struct ieee80211_bpf_params *);
183 static void     bwn_updateslot(struct ifnet *);
184 static void     bwn_update_promisc(struct ifnet *);
185 static void     bwn_wme_init(struct bwn_mac *);
186 static int      bwn_wme_update(struct ieee80211com *);
187 static void     bwn_wme_clear(struct bwn_softc *);
188 static void     bwn_wme_load(struct bwn_mac *);
189 static void     bwn_wme_loadparams(struct bwn_mac *,
190                     const struct wmeParams *, uint16_t);
191 static void     bwn_scan_start(struct ieee80211com *);
192 static void     bwn_scan_end(struct ieee80211com *);
193 static void     bwn_set_channel(struct ieee80211com *);
194 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
195                     const char [IFNAMSIZ], int, int,
196                     int, const uint8_t [IEEE80211_ADDR_LEN],
197                     const uint8_t [IEEE80211_ADDR_LEN]);
198 static void     bwn_vap_delete(struct ieee80211vap *);
199 static void     bwn_stop(struct bwn_softc *, int);
200 static void     bwn_stop_locked(struct bwn_softc *, int);
201 static int      bwn_core_init(struct bwn_mac *);
202 static void     bwn_core_start(struct bwn_mac *);
203 static void     bwn_core_exit(struct bwn_mac *);
204 static void     bwn_bt_disable(struct bwn_mac *);
205 static int      bwn_chip_init(struct bwn_mac *);
206 static uint64_t bwn_hf_read(struct bwn_mac *);
207 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void     bwn_set_txretry(struct bwn_mac *, int, int);
209 static void     bwn_rate_init(struct bwn_mac *);
210 static void     bwn_set_phytxctl(struct bwn_mac *);
211 static void     bwn_spu_setdelay(struct bwn_mac *, int);
212 static void     bwn_bt_enable(struct bwn_mac *);
213 static void     bwn_set_macaddr(struct bwn_mac *);
214 static void     bwn_crypt_init(struct bwn_mac *);
215 static void     bwn_chip_exit(struct bwn_mac *);
216 static int      bwn_fw_fillinfo(struct bwn_mac *);
217 static int      bwn_fw_loaducode(struct bwn_mac *);
218 static int      bwn_gpio_init(struct bwn_mac *);
219 static int      bwn_fw_loadinitvals(struct bwn_mac *);
220 static int      bwn_phy_init(struct bwn_mac *);
221 static void     bwn_set_txantenna(struct bwn_mac *, int);
222 static void     bwn_set_opmode(struct bwn_mac *);
223 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t  bwn_plcp_getcck(const uint8_t);
225 static uint8_t  bwn_plcp_getofdm(const uint8_t);
226 static void     bwn_pio_init(struct bwn_mac *);
227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
228 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
229                     int);
230 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
231                     struct bwn_pio_rxqueue *, int);
232 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
234                     uint16_t);
235 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void     bwn_pio_handle_txeof(struct bwn_mac *,
239                     const struct bwn_txstatus *);
240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
243                     uint16_t);
244 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
245                     uint32_t);
246 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
247                     struct mbuf *);
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
250                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
252                     uint16_t, uint32_t);
253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
254                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
256                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258                     uint16_t, struct bwn_pio_txpkt **);
259 static void     bwn_dma_init(struct bwn_mac *);
260 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int      bwn_dma_mask2type(uint64_t);
262 static uint64_t bwn_dma_mask(struct bwn_mac *);
263 static uint16_t bwn_dma_base(int, int);
264 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
266                     int, struct bwn_dmadesc_generic **,
267                     struct bwn_dmadesc_meta **);
268 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
269                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
270                     int, int);
271 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
277                     int, struct bwn_dmadesc_generic **,
278                     struct bwn_dmadesc_meta **);
279 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
280                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
281                     int, int);
282 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void     bwn_dma_setup(struct bwn_dma_ring *);
289 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void     bwn_dma_rx(struct bwn_dma_ring *);
294 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
296                     struct bwn_dmadesc_meta *);
297 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int      bwn_dma_gettype(struct bwn_mac *);
299 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
304                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
305                     int);
306 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
307                     bus_size_t, int);
308 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void     bwn_dma_handle_txeof(struct bwn_mac *,
310                     const struct bwn_txstatus *);
311 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
312                     struct mbuf *);
313 static int      bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
315                     uint8_t);
316 static int      bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
318                     int, int, int);
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320                     const struct bwn_txstatus *, uint16_t, int *);
321 static void     bwn_dma_free(struct bwn_mac *);
322 static void     bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
324 static void     bwn_phy_init_b5(struct bwn_mac *);
325 static void     bwn_phy_init_b6(struct bwn_mac *);
326 static void     bwn_phy_init_a(struct bwn_mac *);
327 static void     bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void     bwn_lo_g_init(struct bwn_mac *);
330 static void     bwn_lo_g_adjust(struct bwn_mac *);
331 static void     bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333                     const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338                     const struct bwn_bbatt *, const struct bwn_rfatt *,
339                     uint8_t);
340 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void     bwn_wa_init(struct bwn_mac *);
344 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
345                     uint16_t);
346 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
348                     uint32_t);
349 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
350                     uint16_t);
351 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void     bwn_mac_suspend(struct bwn_mac *);
353 static void     bwn_mac_enable(struct bwn_mac *);
354 static void     bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void     bwn_nrssi_offset(struct bwn_mac *);
357 static void     bwn_nrssi_threshold(struct bwn_mac *);
358 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360                     int16_t);
361 static void     bwn_set_original_gains(struct bwn_mac *);
362 static void     bwn_hwpctl_early_init(struct bwn_mac *);
363 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t bwn_phy_g_chan2freq(uint8_t);
365 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367                     const char *, struct bwn_fwfile *);
368 static void     bwn_release_firmware(struct bwn_mac *);
369 static void     bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371 static int      bwn_fwinitvals_write(struct bwn_mac *,
372                     const struct bwn_fwinitvals *, size_t, size_t);
373 static int      bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t bwn_ant2phy(int);
375 static void     bwn_mac_write_bssid(struct bwn_mac *);
376 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377                     const uint8_t *);
378 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379                     const uint8_t *, size_t, const uint8_t *);
380 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
381                     const uint8_t *);
382 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
383                     const uint8_t *);
384 static void     bwn_phy_exit(struct bwn_mac *);
385 static void     bwn_core_stop(struct bwn_mac *);
386 static int      bwn_switch_band(struct bwn_softc *,
387                     struct ieee80211_channel *);
388 static void     bwn_phy_reset(struct bwn_mac *);
389 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void     bwn_set_pretbtt(struct bwn_mac *);
391 static int      bwn_intr(void *);
392 static void     bwn_intrtask(void *, int);
393 static void     bwn_restart(struct bwn_mac *, const char *);
394 static void     bwn_intr_ucode_debug(struct bwn_mac *);
395 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void     bwn_intr_atim_end(struct bwn_mac *);
397 static void     bwn_intr_beacon(struct bwn_mac *);
398 static void     bwn_intr_pmq(struct bwn_mac *);
399 static void     bwn_intr_noise(struct bwn_mac *);
400 static void     bwn_intr_txeof(struct bwn_mac *);
401 static void     bwn_hwreset(void *, int);
402 static void     bwn_handle_fwpanic(struct bwn_mac *);
403 static void     bwn_load_beacon0(struct bwn_mac *);
404 static void     bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t bwn_jssi_read(struct bwn_mac *);
406 static void     bwn_noise_gensample(struct bwn_mac *);
407 static void     bwn_handle_txeof(struct bwn_mac *,
408                     const struct bwn_txstatus *);
409 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static void     bwn_start_locked(struct ifnet *);
412 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
413                     struct mbuf *);
414 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
415 static int      bwn_set_txhdr(struct bwn_mac *,
416                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
417                     uint16_t);
418 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
419                     const uint8_t);
420 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
421 static uint8_t  bwn_get_fbrate(uint8_t);
422 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
423 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
424 static void     bwn_phy_lock(struct bwn_mac *);
425 static void     bwn_phy_unlock(struct bwn_mac *);
426 static void     bwn_rf_lock(struct bwn_mac *);
427 static void     bwn_rf_unlock(struct bwn_mac *);
428 static void     bwn_txpwr(void *, int);
429 static void     bwn_tasks(void *);
430 static void     bwn_task_15s(struct bwn_mac *);
431 static void     bwn_task_30s(struct bwn_mac *);
432 static void     bwn_task_60s(struct bwn_mac *);
433 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
434                     uint8_t);
435 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
436 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
437                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
438                     int, int);
439 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
440 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
441 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
442 static void     bwn_watchdog(void *);
443 static void     bwn_dma_stop(struct bwn_mac *);
444 static void     bwn_pio_stop(struct bwn_mac *);
445 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
446 static void     bwn_led_attach(struct bwn_mac *);
447 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
448 static void     bwn_led_event(struct bwn_mac *, int);
449 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
450 static void     bwn_led_blink_next(void *);
451 static void     bwn_led_blink_end(void *);
452 static void     bwn_rfswitch(void *);
453 static void     bwn_rf_turnon(struct bwn_mac *);
454 static void     bwn_rf_turnoff(struct bwn_mac *);
455 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
456 static int      bwn_phy_lp_init(struct bwn_mac *);
457 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
458 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
459 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
460                     uint16_t);
461 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
462 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
464 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
465 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
466 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
467 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
468 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
469 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
470 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
471 static void     bwn_phy_lp_calib(struct bwn_mac *);
472 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
473 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
474 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
475 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
476 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
477 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
478 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
479 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
480 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
481 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
482 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
483 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
484 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
485 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
486 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
487 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
488 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
489 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
490 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
491 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
492 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
493 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
494                     const void *);
495 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
496 static struct bwn_txgain
497                 bwn_phy_lp_get_txgain(struct bwn_mac *);
498 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
499 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
500 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
501 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
502 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
503 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
504 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
505 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
506 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
507 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
508 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
509 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
510 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
511 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
512 static int      bwn_phy_lp_loopback(struct bwn_mac *);
513 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
514 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
515                     int);
516 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
517                     struct bwn_phy_lp_iq_est *);
518 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
519 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
520 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
521 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
522 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
523 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
524 static uint8_t  bwn_nbits(int32_t);
525 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
526                     struct bwn_txgain_entry *);
527 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
528                     struct bwn_txgain_entry);
529 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
530                     struct bwn_txgain_entry);
531 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
532                     struct bwn_txgain_entry);
533 static void     bwn_sysctl_node(struct bwn_softc *);
534
535 static struct resource_spec bwn_res_spec_legacy[] = {
536         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
537         { -1,                   0,              0 }
538 };
539
540 static struct resource_spec bwn_res_spec_msi[] = {
541         { SYS_RES_IRQ,          1,              RF_ACTIVE },
542         { -1,                   0,              0 }
543 };
544
545 static const struct bwn_channelinfo bwn_chantable_bg = {
546         .channels = {
547                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
548                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
549                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
550                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
551                 { 2472, 13, 30 }, { 2484, 14, 30 } },
552         .nchannels = 14
553 };
554
555 static const struct bwn_channelinfo bwn_chantable_a = {
556         .channels = {
557                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
558                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
559                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
560                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
561                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
562                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
563                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
564                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
565                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
566                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
567                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
568                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
569                 { 6080, 216, 30 } },
570         .nchannels = 37
571 };
572
573 static const struct bwn_channelinfo bwn_chantable_n = {
574         .channels = {
575                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
576                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
577                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
578                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
579                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
580                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
581                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
582                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
583                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
584                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
585                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
586                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
587                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
588                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
589                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
590                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
591                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
592                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
593                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
594                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
595                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
596                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
597                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
598                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
599                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
600                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
601                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
602                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
603                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
604                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
605                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
606                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
607                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
608                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
609                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
610                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
611                 { 6130, 226, 30 }, { 6140, 228, 30 } },
612         .nchannels = 110
613 };
614
615 static const uint8_t bwn_b2063_chantable_data[33][12] = {
616         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
622         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
623         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
624         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
628         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
629         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
630         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
633         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
634         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
635         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
649 };
650
651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
652         { 1, 2412, bwn_b2063_chantable_data[0] },
653         { 2, 2417, bwn_b2063_chantable_data[0] },
654         { 3, 2422, bwn_b2063_chantable_data[0] },
655         { 4, 2427, bwn_b2063_chantable_data[1] },
656         { 5, 2432, bwn_b2063_chantable_data[1] },
657         { 6, 2437, bwn_b2063_chantable_data[1] },
658         { 7, 2442, bwn_b2063_chantable_data[1] },
659         { 8, 2447, bwn_b2063_chantable_data[1] },
660         { 9, 2452, bwn_b2063_chantable_data[2] },
661         { 10, 2457, bwn_b2063_chantable_data[2] },
662         { 11, 2462, bwn_b2063_chantable_data[3] },
663         { 12, 2467, bwn_b2063_chantable_data[3] },
664         { 13, 2472, bwn_b2063_chantable_data[3] },
665         { 14, 2484, bwn_b2063_chantable_data[4] },
666         { 34, 5170, bwn_b2063_chantable_data[5] },
667         { 36, 5180, bwn_b2063_chantable_data[6] },
668         { 38, 5190, bwn_b2063_chantable_data[7] },
669         { 40, 5200, bwn_b2063_chantable_data[8] },
670         { 42, 5210, bwn_b2063_chantable_data[9] },
671         { 44, 5220, bwn_b2063_chantable_data[10] },
672         { 46, 5230, bwn_b2063_chantable_data[11] },
673         { 48, 5240, bwn_b2063_chantable_data[12] },
674         { 52, 5260, bwn_b2063_chantable_data[13] },
675         { 56, 5280, bwn_b2063_chantable_data[14] },
676         { 60, 5300, bwn_b2063_chantable_data[14] },
677         { 64, 5320, bwn_b2063_chantable_data[15] },
678         { 100, 5500, bwn_b2063_chantable_data[16] },
679         { 104, 5520, bwn_b2063_chantable_data[17] },
680         { 108, 5540, bwn_b2063_chantable_data[18] },
681         { 112, 5560, bwn_b2063_chantable_data[19] },
682         { 116, 5580, bwn_b2063_chantable_data[20] },
683         { 120, 5600, bwn_b2063_chantable_data[21] },
684         { 124, 5620, bwn_b2063_chantable_data[21] },
685         { 128, 5640, bwn_b2063_chantable_data[22] },
686         { 132, 5660, bwn_b2063_chantable_data[22] },
687         { 136, 5680, bwn_b2063_chantable_data[22] },
688         { 140, 5700, bwn_b2063_chantable_data[23] },
689         { 149, 5745, bwn_b2063_chantable_data[23] },
690         { 153, 5765, bwn_b2063_chantable_data[23] },
691         { 157, 5785, bwn_b2063_chantable_data[23] },
692         { 161, 5805, bwn_b2063_chantable_data[23] },
693         { 165, 5825, bwn_b2063_chantable_data[23] },
694         { 184, 4920, bwn_b2063_chantable_data[24] },
695         { 188, 4940, bwn_b2063_chantable_data[25] },
696         { 192, 4960, bwn_b2063_chantable_data[26] },
697         { 196, 4980, bwn_b2063_chantable_data[27] },
698         { 200, 5000, bwn_b2063_chantable_data[28] },
699         { 204, 5020, bwn_b2063_chantable_data[29] },
700         { 208, 5040, bwn_b2063_chantable_data[30] },
701         { 212, 5060, bwn_b2063_chantable_data[31] },
702         { 216, 5080, bwn_b2063_chantable_data[32] }
703 };
704
705 static const uint8_t bwn_b2062_chantable_data[22][12] = {
706         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
707         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
727         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
728 };
729
730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
731         { 1, 2412, bwn_b2062_chantable_data[0] },
732         { 2, 2417, bwn_b2062_chantable_data[0] },
733         { 3, 2422, bwn_b2062_chantable_data[0] },
734         { 4, 2427, bwn_b2062_chantable_data[0] },
735         { 5, 2432, bwn_b2062_chantable_data[0] },
736         { 6, 2437, bwn_b2062_chantable_data[0] },
737         { 7, 2442, bwn_b2062_chantable_data[0] },
738         { 8, 2447, bwn_b2062_chantable_data[0] },
739         { 9, 2452, bwn_b2062_chantable_data[0] },
740         { 10, 2457, bwn_b2062_chantable_data[0] },
741         { 11, 2462, bwn_b2062_chantable_data[0] },
742         { 12, 2467, bwn_b2062_chantable_data[0] },
743         { 13, 2472, bwn_b2062_chantable_data[0] },
744         { 14, 2484, bwn_b2062_chantable_data[0] },
745         { 34, 5170, bwn_b2062_chantable_data[1] },
746         { 38, 5190, bwn_b2062_chantable_data[2] },
747         { 42, 5210, bwn_b2062_chantable_data[2] },
748         { 46, 5230, bwn_b2062_chantable_data[3] },
749         { 36, 5180, bwn_b2062_chantable_data[4] },
750         { 40, 5200, bwn_b2062_chantable_data[5] },
751         { 44, 5220, bwn_b2062_chantable_data[6] },
752         { 48, 5240, bwn_b2062_chantable_data[3] },
753         { 52, 5260, bwn_b2062_chantable_data[3] },
754         { 56, 5280, bwn_b2062_chantable_data[3] },
755         { 60, 5300, bwn_b2062_chantable_data[7] },
756         { 64, 5320, bwn_b2062_chantable_data[8] },
757         { 100, 5500, bwn_b2062_chantable_data[9] },
758         { 104, 5520, bwn_b2062_chantable_data[10] },
759         { 108, 5540, bwn_b2062_chantable_data[10] },
760         { 112, 5560, bwn_b2062_chantable_data[10] },
761         { 116, 5580, bwn_b2062_chantable_data[11] },
762         { 120, 5600, bwn_b2062_chantable_data[12] },
763         { 124, 5620, bwn_b2062_chantable_data[12] },
764         { 128, 5640, bwn_b2062_chantable_data[12] },
765         { 132, 5660, bwn_b2062_chantable_data[12] },
766         { 136, 5680, bwn_b2062_chantable_data[12] },
767         { 140, 5700, bwn_b2062_chantable_data[12] },
768         { 149, 5745, bwn_b2062_chantable_data[12] },
769         { 153, 5765, bwn_b2062_chantable_data[12] },
770         { 157, 5785, bwn_b2062_chantable_data[12] },
771         { 161, 5805, bwn_b2062_chantable_data[12] },
772         { 165, 5825, bwn_b2062_chantable_data[12] },
773         { 184, 4920, bwn_b2062_chantable_data[13] },
774         { 188, 4940, bwn_b2062_chantable_data[14] },
775         { 192, 4960, bwn_b2062_chantable_data[15] },
776         { 196, 4980, bwn_b2062_chantable_data[16] },
777         { 200, 5000, bwn_b2062_chantable_data[17] },
778         { 204, 5020, bwn_b2062_chantable_data[18] },
779         { 208, 5040, bwn_b2062_chantable_data[19] },
780         { 212, 5060, bwn_b2062_chantable_data[20] },
781         { 216, 5080, bwn_b2062_chantable_data[21] }
782 };
783
784 /* for LP PHY */
785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
786         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
787         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
788         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
789         { 13, -66, 13 }, { 14, -66, 13 },
790 };
791
792 /* for LP PHY */
793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
794         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
795         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
796         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
797         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
798         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
799         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
800         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
801         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
802         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
803         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
804         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
805         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
806         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
807 };
808
809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
810
811 static const uint8_t bwn_tab_sigsq_tbl[] = {
812         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
813         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
814         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
816         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
817         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
818 };
819
820 static const uint8_t bwn_tab_pllfrac_tbl[] = {
821         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
822         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
823 };
824
825 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
826         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
827         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
828         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
830         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
831         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
832         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838 };
839
840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
846
847 #define VENDOR_LED_ACT(vendor)                          \
848 {                                                       \
849         .vid = PCI_VENDOR_##vendor,                     \
850         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
851 }
852
853 static const struct {
854         uint16_t        vid;
855         uint8_t         led_act[BWN_LED_MAX];
856 } bwn_vendor_led_act[] = {
857         VENDOR_LED_ACT(COMPAQ),
858         VENDOR_LED_ACT(ASUSTEK)
859 };
860
861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
862         { BWN_VENDOR_LED_ACT_DEFAULT };
863
864 #undef VENDOR_LED_ACT
865
866 static const struct {
867         int             on_dur;
868         int             off_dur;
869 } bwn_led_duration[109] = {
870         [0]     = { 400, 100 },
871         [2]     = { 150, 75 },
872         [4]     = { 90, 45 },
873         [11]    = { 66, 34 },
874         [12]    = { 53, 26 },
875         [18]    = { 42, 21 },
876         [22]    = { 35, 17 },
877         [24]    = { 32, 16 },
878         [36]    = { 21, 10 },
879         [48]    = { 16, 8 },
880         [72]    = { 11, 5 },
881         [96]    = { 9, 4 },
882         [108]   = { 7, 3 }
883 };
884
885 static const uint16_t bwn_wme_shm_offsets[] = {
886         [0] = BWN_WME_BESTEFFORT,
887         [1] = BWN_WME_BACKGROUND,
888         [2] = BWN_WME_VOICE,
889         [3] = BWN_WME_VIDEO,
890 };
891
892 static const struct siba_devid bwn_devs[] = {
893         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
894         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
895         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
896         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
897         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
898         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
899         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
900         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
901         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
902 };
903
904 static int
905 bwn_probe(device_t dev)
906 {
907         int i;
908
909         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
910                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
911                     siba_get_device(dev) == bwn_devs[i].sd_device &&
912                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
913                         return (BUS_PROBE_DEFAULT);
914         }
915
916         return (ENXIO);
917 }
918
919 static int
920 bwn_attach(device_t dev)
921 {
922         struct bwn_mac *mac;
923         struct bwn_softc *sc = device_get_softc(dev);
924         int error, i, msic, reg;
925
926         sc->sc_dev = dev;
927 #ifdef BWN_DEBUG
928         sc->sc_debug = bwn_debug;
929 #endif
930
931         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
932                 error = bwn_attach_pre(sc);
933                 if (error != 0)
934                         return (error);
935                 bwn_sprom_bugfixes(dev);
936                 sc->sc_flags |= BWN_FLAG_ATTACHED;
937         }
938
939         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
940                 if (siba_get_pci_device(dev) != 0x4313 &&
941                     siba_get_pci_device(dev) != 0x431a &&
942                     siba_get_pci_device(dev) != 0x4321) {
943                         device_printf(sc->sc_dev,
944                             "skip 802.11 cores\n");
945                         return (ENODEV);
946                 }
947         }
948
949         mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
950             M_NOWAIT | M_ZERO);
951         if (mac == NULL)
952                 return (ENOMEM);
953         mac->mac_sc = sc;
954         mac->mac_status = BWN_MAC_STATUS_UNINIT;
955         if (bwn_bfp != 0)
956                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
957
958         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
959         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
960         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
961
962         error = bwn_attach_core(mac);
963         if (error)
964                 goto fail0;
965         bwn_led_attach(mac);
966
967         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
968             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
969             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
970             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
971             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
972             mac->mac_phy.rf_rev);
973         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
974                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
975                     mac->mac_method.dma.dmatype);
976         else
977                 device_printf(sc->sc_dev, "PIO\n");
978
979         /*
980          * setup PCI resources and interrupt.
981          */
982         if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
983                 msic = pci_msi_count(dev);
984                 if (bootverbose)
985                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
986         } else
987                 msic = 0;
988
989         mac->mac_intr_spec = bwn_res_spec_legacy;
990         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
991                 if (pci_alloc_msi(dev, &msic) == 0) {
992                         device_printf(sc->sc_dev,
993                             "Using %d MSI messages\n", msic);
994                         mac->mac_intr_spec = bwn_res_spec_msi;
995                         mac->mac_msi = 1;
996                 }
997         }
998
999         error = bus_alloc_resources(dev, mac->mac_intr_spec,
1000             mac->mac_res_irq);
1001         if (error) {
1002                 device_printf(sc->sc_dev,
1003                     "couldn't allocate IRQ resources (%d)\n", error);
1004                 goto fail1;
1005         }
1006
1007         if (mac->mac_msi == 0)
1008                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1009                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1010                     &mac->mac_intrhand[0]);
1011         else {
1012                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1013                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1014                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1015                             &mac->mac_intrhand[i]);
1016                         if (error != 0) {
1017                                 device_printf(sc->sc_dev,
1018                                     "couldn't setup interrupt (%d)\n", error);
1019                                 break;
1020                         }
1021                 }
1022         }
1023
1024         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1025
1026         /*
1027          * calls attach-post routine
1028          */
1029         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1030                 bwn_attach_post(sc);
1031
1032         return (0);
1033 fail1:
1034         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1035                 pci_release_msi(dev);
1036 fail0:
1037         free(mac, M_DEVBUF);
1038         return (error);
1039 }
1040
1041 static int
1042 bwn_is_valid_ether_addr(uint8_t *addr)
1043 {
1044         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1045
1046         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1047                 return (FALSE);
1048
1049         return (TRUE);
1050 }
1051
1052 static int
1053 bwn_attach_post(struct bwn_softc *sc)
1054 {
1055         struct ieee80211com *ic;
1056         struct ifnet *ifp = sc->sc_ifp;
1057
1058         ic = ifp->if_l2com;
1059         ic->ic_ifp = ifp;
1060         /* XXX not right but it's not used anywhere important */
1061         ic->ic_phytype = IEEE80211_T_OFDM;
1062         ic->ic_opmode = IEEE80211_M_STA;
1063         ic->ic_caps =
1064                   IEEE80211_C_STA               /* station mode supported */
1065                 | IEEE80211_C_MONITOR           /* monitor mode */
1066                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1067                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1068                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1069                 | IEEE80211_C_WME               /* WME/WMM supported */
1070                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1071                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1072                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1073                 ;
1074
1075         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1076
1077         /* call MI attach routine. */
1078         ieee80211_ifattach(ic,
1079             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1080             siba_sprom_get_mac_80211a(sc->sc_dev) :
1081             siba_sprom_get_mac_80211bg(sc->sc_dev));
1082
1083         ic->ic_headroom = sizeof(struct bwn_txhdr);
1084
1085         /* override default methods */
1086         ic->ic_raw_xmit = bwn_raw_xmit;
1087         ic->ic_updateslot = bwn_updateslot;
1088         ic->ic_update_promisc = bwn_update_promisc;
1089         ic->ic_wme.wme_update = bwn_wme_update;
1090
1091         ic->ic_scan_start = bwn_scan_start;
1092         ic->ic_scan_end = bwn_scan_end;
1093         ic->ic_set_channel = bwn_set_channel;
1094
1095         ic->ic_vap_create = bwn_vap_create;
1096         ic->ic_vap_delete = bwn_vap_delete;
1097
1098         ieee80211_radiotap_attach(ic,
1099             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1100             BWN_TX_RADIOTAP_PRESENT,
1101             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1102             BWN_RX_RADIOTAP_PRESENT);
1103
1104         bwn_sysctl_node(sc);
1105
1106         if (bootverbose)
1107                 ieee80211_announce(ic);
1108         return (0);
1109 }
1110
1111 static void
1112 bwn_phy_detach(struct bwn_mac *mac)
1113 {
1114
1115         if (mac->mac_phy.detach != NULL)
1116                 mac->mac_phy.detach(mac);
1117 }
1118
1119 static int
1120 bwn_detach(device_t dev)
1121 {
1122         struct bwn_softc *sc = device_get_softc(dev);
1123         struct bwn_mac *mac = sc->sc_curmac;
1124         struct ifnet *ifp = sc->sc_ifp;
1125         struct ieee80211com *ic = ifp->if_l2com;
1126         int i;
1127
1128         sc->sc_flags |= BWN_FLAG_INVALID;
1129
1130         if (device_is_attached(sc->sc_dev)) {
1131                 bwn_stop(sc, 1);
1132                 bwn_dma_free(mac);
1133                 callout_drain(&sc->sc_led_blink_ch);
1134                 callout_drain(&sc->sc_rfswitch_ch);
1135                 callout_drain(&sc->sc_task_ch);
1136                 callout_drain(&sc->sc_watchdog_ch);
1137                 bwn_phy_detach(mac);
1138                 if (ifp != NULL) {
1139                         ieee80211_draintask(ic, &mac->mac_hwreset);
1140                         ieee80211_draintask(ic, &mac->mac_txpower);
1141                         ieee80211_ifdetach(ic);
1142                         if_free(ifp);
1143                 }
1144         }
1145         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1146         taskqueue_free(sc->sc_tq);
1147
1148         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1149                 if (mac->mac_intrhand[i] != NULL) {
1150                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1151                             mac->mac_intrhand[i]);
1152                         mac->mac_intrhand[i] = NULL;
1153                 }
1154         }
1155         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1156         if (mac->mac_msi != 0)
1157                 pci_release_msi(dev);
1158
1159         BWN_LOCK_DESTROY(sc);
1160         return (0);
1161 }
1162
1163 static int
1164 bwn_attach_pre(struct bwn_softc *sc)
1165 {
1166         struct ifnet *ifp;
1167         int error = 0;
1168
1169         BWN_LOCK_INIT(sc);
1170         TAILQ_INIT(&sc->sc_maclist);
1171         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1172         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1173         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1174
1175         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1176                 taskqueue_thread_enqueue, &sc->sc_tq);
1177         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1178                 "%s taskq", device_get_nameunit(sc->sc_dev));
1179
1180         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1181         if (ifp == NULL) {
1182                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1183                 error = ENOSPC;
1184                 goto fail;
1185         }
1186
1187         /* set these up early for if_printf use */
1188         if_initname(ifp, device_get_name(sc->sc_dev),
1189             device_get_unit(sc->sc_dev));
1190
1191         ifp->if_softc = sc;
1192         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1193         ifp->if_init = bwn_init;
1194         ifp->if_ioctl = bwn_ioctl;
1195         ifp->if_start = bwn_start;
1196         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1197         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1198         IFQ_SET_READY(&ifp->if_snd);
1199
1200         return (0);
1201
1202 fail:   BWN_LOCK_DESTROY(sc);
1203         return (error);
1204 }
1205
1206 static void
1207 bwn_sprom_bugfixes(device_t dev)
1208 {
1209 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1210         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1211          (siba_get_pci_device(dev) == _device) &&                       \
1212          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1213          (siba_get_pci_subdevice(dev) == _subdevice))
1214
1215         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1216             siba_get_pci_subdevice(dev) == 0x4e &&
1217             siba_get_pci_revid(dev) > 0x40)
1218                 siba_sprom_set_bf_lo(dev,
1219                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1220         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1221             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1222                 siba_sprom_set_bf_lo(dev,
1223                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1224         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1225                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1226                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1227                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1228                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1229                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1230                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1231                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1232                         siba_sprom_set_bf_lo(dev,
1233                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1234         }
1235 #undef  BWN_ISDEV
1236 }
1237
1238 static int
1239 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1240 {
1241 #define IS_RUNNING(ifp) \
1242         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1243         struct bwn_softc *sc = ifp->if_softc;
1244         struct ieee80211com *ic = ifp->if_l2com;
1245         struct ifreq *ifr = (struct ifreq *)data;
1246         int error = 0, startall;
1247
1248         switch (cmd) {
1249         case SIOCSIFFLAGS:
1250                 startall = 0;
1251                 if (IS_RUNNING(ifp)) {
1252                         bwn_update_promisc(ifp);
1253                 } else if (ifp->if_flags & IFF_UP) {
1254                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1255                                 bwn_init(sc);
1256                                 startall = 1;
1257                         }
1258                 } else
1259                         bwn_stop(sc, 1);
1260                 if (startall)
1261                         ieee80211_start_all(ic);
1262                 break;
1263         case SIOCGIFMEDIA:
1264                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1265                 break;
1266         case SIOCGIFADDR:
1267                 error = ether_ioctl(ifp, cmd, data);
1268                 break;
1269         default:
1270                 error = EINVAL;
1271                 break;
1272         }
1273         return (error);
1274 }
1275
1276 static void
1277 bwn_start(struct ifnet *ifp)
1278 {
1279         struct bwn_softc *sc = ifp->if_softc;
1280
1281         BWN_LOCK(sc);
1282         bwn_start_locked(ifp);
1283         BWN_UNLOCK(sc);
1284 }
1285
1286 static void
1287 bwn_start_locked(struct ifnet *ifp)
1288 {
1289         struct bwn_softc *sc = ifp->if_softc;
1290         struct bwn_mac *mac = sc->sc_curmac;
1291         struct ieee80211_frame *wh;
1292         struct ieee80211_node *ni;
1293         struct ieee80211_key *k;
1294         struct mbuf *m;
1295
1296         BWN_ASSERT_LOCKED(sc);
1297
1298         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1299             mac->mac_status < BWN_MAC_STATUS_STARTED)
1300                 return;
1301
1302         for (;;) {
1303                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1304                 if (m == NULL)
1305                         break;
1306
1307                 if (bwn_tx_isfull(sc, m))
1308                         break;
1309                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1310                 if (ni == NULL) {
1311                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1312                         m_freem(m);
1313                         ifp->if_oerrors++;
1314                         continue;
1315                 }
1316                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1317                 wh = mtod(m, struct ieee80211_frame *);
1318                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1319                         k = ieee80211_crypto_encap(ni, m);
1320                         if (k == NULL) {
1321                                 ieee80211_free_node(ni);
1322                                 m_freem(m);
1323                                 ifp->if_oerrors++;
1324                                 continue;
1325                         }
1326                 }
1327                 wh = NULL;      /* Catch any invalid use */
1328
1329                 if (bwn_tx_start(sc, ni, m) != 0) {
1330                         if (ni != NULL)
1331                                 ieee80211_free_node(ni);
1332                         ifp->if_oerrors++;
1333                         continue;
1334                 }
1335
1336                 sc->sc_watchdog_timer = 5;
1337         }
1338 }
1339
1340 static int
1341 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1342 {
1343         struct bwn_dma_ring *dr;
1344         struct bwn_mac *mac = sc->sc_curmac;
1345         struct bwn_pio_txqueue *tq;
1346         struct ifnet *ifp = sc->sc_ifp;
1347         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1348
1349         BWN_ASSERT_LOCKED(sc);
1350
1351         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1352                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1353                 if (dr->dr_stop == 1 ||
1354                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1355                         dr->dr_stop = 1;
1356                         goto full;
1357                 }
1358         } else {
1359                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1360                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1361                     pktlen > (tq->tq_size - tq->tq_used)) {
1362                         tq->tq_stop = 1;
1363                         goto full;
1364                 }
1365         }
1366         return (0);
1367 full:
1368         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1369         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1370         return (1);
1371 }
1372
1373 static int
1374 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1375 {
1376         struct bwn_mac *mac = sc->sc_curmac;
1377         int error;
1378
1379         BWN_ASSERT_LOCKED(sc);
1380
1381         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1382                 m_freem(m);
1383                 return (ENXIO);
1384         }
1385
1386         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1387             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1388         if (error) {
1389                 m_freem(m);
1390                 return (error);
1391         }
1392         return (0);
1393 }
1394
1395 static int
1396 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1397 {
1398         struct bwn_pio_txpkt *tp;
1399         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1400         struct bwn_softc *sc = mac->mac_sc;
1401         struct bwn_txhdr txhdr;
1402         struct mbuf *m_new;
1403         uint32_t ctl32;
1404         int error;
1405         uint16_t ctl16;
1406
1407         BWN_ASSERT_LOCKED(sc);
1408
1409         /* XXX TODO send packets after DTIM */
1410
1411         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1412         tp = TAILQ_FIRST(&tq->tq_pktlist);
1413         tp->tp_ni = ni;
1414         tp->tp_m = m;
1415
1416         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1417         if (error) {
1418                 device_printf(sc->sc_dev, "tx fail\n");
1419                 return (error);
1420         }
1421
1422         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1423         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1424         tq->tq_free--;
1425
1426         if (siba_get_revid(sc->sc_dev) >= 8) {
1427                 /*
1428                  * XXX please removes m_defrag(9)
1429                  */
1430                 m_new = m_defrag(m, M_DONTWAIT);
1431                 if (m_new == NULL) {
1432                         device_printf(sc->sc_dev,
1433                             "%s: can't defrag TX buffer\n",
1434                             __func__);
1435                         return (ENOBUFS);
1436                 }
1437                 if (m_new->m_next != NULL)
1438                         device_printf(sc->sc_dev,
1439                             "TODO: fragmented packets for PIO\n");
1440                 tp->tp_m = m_new;
1441
1442                 /* send HEADER */
1443                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1444                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1445                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1446                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1447                 /* send BODY */
1448                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1449                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1450                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1451                     ctl32 | BWN_PIO8_TXCTL_EOF);
1452         } else {
1453                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1454                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1455                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1456                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1457                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1458                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1459                     ctl16 | BWN_PIO_TXCTL_EOF);
1460         }
1461
1462         return (0);
1463 }
1464
1465 static struct bwn_pio_txqueue *
1466 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1467 {
1468
1469         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1470                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1471
1472         switch (prio) {
1473         case 0:
1474                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1475         case 1:
1476                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1477         case 2:
1478                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1479         case 3:
1480                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1481         }
1482         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1483         return (NULL);
1484 }
1485
1486 static int
1487 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1488 {
1489 #define BWN_GET_TXHDRCACHE(slot)                                        \
1490         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1491         struct bwn_dma *dma = &mac->mac_method.dma;
1492         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1493         struct bwn_dmadesc_generic *desc;
1494         struct bwn_dmadesc_meta *mt;
1495         struct bwn_softc *sc = mac->mac_sc;
1496         struct ifnet *ifp = sc->sc_ifp;
1497         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1498         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1499
1500         BWN_ASSERT_LOCKED(sc);
1501         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1502
1503         /* XXX send after DTIM */
1504
1505         slot = bwn_dma_getslot(dr);
1506         dr->getdesc(dr, slot, &desc, &mt);
1507         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1508             ("%s:%d: fail", __func__, __LINE__));
1509
1510         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1511             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1512             BWN_DMA_COOKIE(dr, slot));
1513         if (error)
1514                 goto fail;
1515         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1516             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1517             &mt->mt_paddr, BUS_DMA_NOWAIT);
1518         if (error) {
1519                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1520                     __func__, error);
1521                 goto fail;
1522         }
1523         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1524             BUS_DMASYNC_PREWRITE);
1525         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1526         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1527             BUS_DMASYNC_PREWRITE);
1528
1529         slot = bwn_dma_getslot(dr);
1530         dr->getdesc(dr, slot, &desc, &mt);
1531         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1532             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1533         mt->mt_m = m;
1534         mt->mt_ni = ni;
1535
1536         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1537             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1538         if (error && error != EFBIG) {
1539                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1540                     __func__, error);
1541                 goto fail;
1542         }
1543         if (error) {    /* error == EFBIG */
1544                 struct mbuf *m_new;
1545
1546                 m_new = m_defrag(m, M_DONTWAIT);
1547                 if (m_new == NULL) {
1548                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1549                             __func__);
1550                         error = ENOBUFS;
1551                         goto fail;
1552                 } else {
1553                         m = m_new;
1554                 }
1555
1556                 mt->mt_m = m;
1557                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1558                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1559                 if (error) {
1560                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1561                             __func__, error);
1562                         goto fail;
1563                 }
1564         }
1565         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1566         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1567         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1568             BUS_DMASYNC_PREWRITE);
1569
1570         /* XXX send after DTIM */
1571
1572         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1573         return (0);
1574 fail:
1575         dr->dr_curslot = backup[0];
1576         dr->dr_usedslot = backup[1];
1577         return (error);
1578 #undef BWN_GET_TXHDRCACHE
1579 }
1580
1581 static void
1582 bwn_watchdog(void *arg)
1583 {
1584         struct bwn_softc *sc = arg;
1585         struct ifnet *ifp = sc->sc_ifp;
1586
1587         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1588                 if_printf(ifp, "device timeout\n");
1589                 ifp->if_oerrors++;
1590         }
1591         callout_schedule(&sc->sc_watchdog_ch, hz);
1592 }
1593
1594 static int
1595 bwn_attach_core(struct bwn_mac *mac)
1596 {
1597         struct bwn_softc *sc = mac->mac_sc;
1598         int error, have_bg = 0, have_a = 0;
1599         uint32_t high;
1600
1601         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1602             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1603
1604         siba_powerup(sc->sc_dev, 0);
1605
1606         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1607         bwn_reset_core(mac,
1608             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1609         error = bwn_phy_getinfo(mac, high);
1610         if (error)
1611                 goto fail;
1612
1613         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1614         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1615         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1616             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1617             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1618                 have_a = have_bg = 0;
1619                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1620                         have_a = 1;
1621                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1622                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1623                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1624                         have_bg = 1;
1625                 else
1626                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1627                             mac->mac_phy.type));
1628         }
1629         /* XXX turns off PHY A because it's not supported */
1630         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1631             mac->mac_phy.type != BWN_PHYTYPE_N) {
1632                 have_a = 0;
1633                 have_bg = 1;
1634         }
1635
1636         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1637                 mac->mac_phy.attach = bwn_phy_g_attach;
1638                 mac->mac_phy.detach = bwn_phy_g_detach;
1639                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1640                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1641                 mac->mac_phy.init = bwn_phy_g_init;
1642                 mac->mac_phy.exit = bwn_phy_g_exit;
1643                 mac->mac_phy.phy_read = bwn_phy_g_read;
1644                 mac->mac_phy.phy_write = bwn_phy_g_write;
1645                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1646                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1647                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1648                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1649                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1650                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1651                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1652                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1653                 mac->mac_phy.set_im = bwn_phy_g_im;
1654                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1655                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1656                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1657                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1658         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1659                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1660                 mac->mac_phy.init = bwn_phy_lp_init;
1661                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1662                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1663                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1664                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1665                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1666                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1667                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1668                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1669                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1670                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1671                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1672         } else {
1673                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1674                     mac->mac_phy.type);
1675                 error = ENXIO;
1676                 goto fail;
1677         }
1678
1679         mac->mac_phy.gmode = have_bg;
1680         if (mac->mac_phy.attach != NULL) {
1681                 error = mac->mac_phy.attach(mac);
1682                 if (error) {
1683                         device_printf(sc->sc_dev, "failed\n");
1684                         goto fail;
1685                 }
1686         }
1687
1688         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1689
1690         error = bwn_chiptest(mac);
1691         if (error)
1692                 goto fail;
1693         error = bwn_setup_channels(mac, have_bg, have_a);
1694         if (error) {
1695                 device_printf(sc->sc_dev, "failed to setup channels\n");
1696                 goto fail;
1697         }
1698
1699         if (sc->sc_curmac == NULL)
1700                 sc->sc_curmac = mac;
1701
1702         error = bwn_dma_attach(mac);
1703         if (error != 0) {
1704                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1705                 goto fail;
1706         }
1707
1708         mac->mac_phy.switch_analog(mac, 0);
1709
1710         siba_dev_down(sc->sc_dev, 0);
1711 fail:
1712         siba_powerdown(sc->sc_dev);
1713         return (error);
1714 }
1715
1716 static void
1717 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1718 {
1719         struct bwn_softc *sc = mac->mac_sc;
1720         uint32_t low, ctl;
1721
1722         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1723
1724         siba_dev_up(sc->sc_dev, flags);
1725         DELAY(2000);
1726
1727         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1728             ~BWN_TGSLOW_PHYRESET;
1729         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1730         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1731         DELAY(1000);
1732         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1733         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1734         DELAY(1000);
1735
1736         if (mac->mac_phy.switch_analog != NULL)
1737                 mac->mac_phy.switch_analog(mac, 1);
1738
1739         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1740         if (flags & BWN_TGSLOW_SUPPORT_G)
1741                 ctl |= BWN_MACCTL_GMODE;
1742         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1743 }
1744
1745 static int
1746 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1747 {
1748         struct bwn_phy *phy = &mac->mac_phy;
1749         struct bwn_softc *sc = mac->mac_sc;
1750         uint32_t tmp;
1751
1752         /* PHY */
1753         tmp = BWN_READ_2(mac, BWN_PHYVER);
1754         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1755         phy->rf_on = 1;
1756         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1757         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1758         phy->rev = (tmp & BWN_PHYVER_VERSION);
1759         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1760             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1761                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1762             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1763             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1764             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1765                 goto unsupphy;
1766
1767         /* RADIO */
1768         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1769                 if (siba_get_chiprev(sc->sc_dev) == 0)
1770                         tmp = 0x3205017f;
1771                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1772                         tmp = 0x4205017f;
1773                 else
1774                         tmp = 0x5205017f;
1775         } else {
1776                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1777                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1778                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1779                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1780         }
1781         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1782         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1783         phy->rf_manuf = (tmp & 0x00000fff);
1784         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1785                 goto unsupradio;
1786         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1787              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1788             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1789             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1790             (phy->type == BWN_PHYTYPE_N &&
1791              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1792             (phy->type == BWN_PHYTYPE_LP &&
1793              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1794                 goto unsupradio;
1795
1796         return (0);
1797 unsupphy:
1798         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1799             "analog %#x)\n",
1800             phy->type, phy->rev, phy->analog);
1801         return (ENXIO);
1802 unsupradio:
1803         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1804             "rev %#x)\n",
1805             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1806         return (ENXIO);
1807 }
1808
1809 static int
1810 bwn_chiptest(struct bwn_mac *mac)
1811 {
1812 #define TESTVAL0        0x55aaaa55
1813 #define TESTVAL1        0xaa5555aa
1814         struct bwn_softc *sc = mac->mac_sc;
1815         uint32_t v, backup;
1816
1817         BWN_LOCK(sc);
1818
1819         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1820
1821         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1822         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1823                 goto error;
1824         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1825         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1826                 goto error;
1827
1828         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1829
1830         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1831             (siba_get_revid(sc->sc_dev) <= 10)) {
1832                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1833                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1834                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1835                         goto error;
1836                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1837                         goto error;
1838         }
1839         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1840
1841         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1842         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1843                 goto error;
1844
1845         BWN_UNLOCK(sc);
1846         return (0);
1847 error:
1848         BWN_UNLOCK(sc);
1849         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1850         return (ENODEV);
1851 }
1852
1853 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1854 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1855
1856 static int
1857 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1858 {
1859         struct bwn_softc *sc = mac->mac_sc;
1860         struct ifnet *ifp = sc->sc_ifp;
1861         struct ieee80211com *ic = ifp->if_l2com;
1862
1863         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1864         ic->ic_nchans = 0;
1865
1866         if (have_bg)
1867                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1868                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1869         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1870                 if (have_a)
1871                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1872                             &ic->ic_nchans, &bwn_chantable_n,
1873                             IEEE80211_CHAN_HTA);
1874         } else {
1875                 if (have_a)
1876                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1877                             &ic->ic_nchans, &bwn_chantable_a,
1878                             IEEE80211_CHAN_A);
1879         }
1880
1881         mac->mac_phy.supports_2ghz = have_bg;
1882         mac->mac_phy.supports_5ghz = have_a;
1883
1884         return (ic->ic_nchans == 0 ? ENXIO : 0);
1885 }
1886
1887 static uint32_t
1888 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1889 {
1890         uint32_t ret;
1891
1892         BWN_ASSERT_LOCKED(mac->mac_sc);
1893
1894         if (way == BWN_SHARED) {
1895                 KASSERT((offset & 0x0001) == 0,
1896                     ("%s:%d warn", __func__, __LINE__));
1897                 if (offset & 0x0003) {
1898                         bwn_shm_ctlword(mac, way, offset >> 2);
1899                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1900                         ret <<= 16;
1901                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1902                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1903                         goto out;
1904                 }
1905                 offset >>= 2;
1906         }
1907         bwn_shm_ctlword(mac, way, offset);
1908         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1909 out:
1910         return (ret);
1911 }
1912
1913 static uint16_t
1914 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1915 {
1916         uint16_t ret;
1917
1918         BWN_ASSERT_LOCKED(mac->mac_sc);
1919
1920         if (way == BWN_SHARED) {
1921                 KASSERT((offset & 0x0001) == 0,
1922                     ("%s:%d warn", __func__, __LINE__));
1923                 if (offset & 0x0003) {
1924                         bwn_shm_ctlword(mac, way, offset >> 2);
1925                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1926                         goto out;
1927                 }
1928                 offset >>= 2;
1929         }
1930         bwn_shm_ctlword(mac, way, offset);
1931         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1932 out:
1933
1934         return (ret);
1935 }
1936
1937 static void
1938 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1939     uint16_t offset)
1940 {
1941         uint32_t control;
1942
1943         control = way;
1944         control <<= 16;
1945         control |= offset;
1946         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1947 }
1948
1949 static void
1950 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1951     uint32_t value)
1952 {
1953         BWN_ASSERT_LOCKED(mac->mac_sc);
1954
1955         if (way == BWN_SHARED) {
1956                 KASSERT((offset & 0x0001) == 0,
1957                     ("%s:%d warn", __func__, __LINE__));
1958                 if (offset & 0x0003) {
1959                         bwn_shm_ctlword(mac, way, offset >> 2);
1960                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1961                                     (value >> 16) & 0xffff);
1962                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1963                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1964                         return;
1965                 }
1966                 offset >>= 2;
1967         }
1968         bwn_shm_ctlword(mac, way, offset);
1969         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1970 }
1971
1972 static void
1973 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1974     uint16_t value)
1975 {
1976         BWN_ASSERT_LOCKED(mac->mac_sc);
1977
1978         if (way == BWN_SHARED) {
1979                 KASSERT((offset & 0x0001) == 0,
1980                     ("%s:%d warn", __func__, __LINE__));
1981                 if (offset & 0x0003) {
1982                         bwn_shm_ctlword(mac, way, offset >> 2);
1983                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1984                         return;
1985                 }
1986                 offset >>= 2;
1987         }
1988         bwn_shm_ctlword(mac, way, offset);
1989         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1990 }
1991
1992 static void
1993 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1994     int txpow)
1995 {
1996
1997         c->ic_freq = freq;
1998         c->ic_flags = flags;
1999         c->ic_ieee = ieee;
2000         c->ic_minpower = 0;
2001         c->ic_maxpower = 2 * txpow;
2002         c->ic_maxregpower = txpow;
2003 }
2004
2005 static void
2006 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2007     const struct bwn_channelinfo *ci, int flags)
2008 {
2009         struct ieee80211_channel *c;
2010         int i;
2011
2012         c = &chans[*nchans];
2013
2014         for (i = 0; i < ci->nchannels; i++) {
2015                 const struct bwn_channel *hc;
2016
2017                 hc = &ci->channels[i];
2018                 if (*nchans >= maxchans)
2019                         break;
2020                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2021                 c++, (*nchans)++;
2022                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2023                         /* g channel have a separate b-only entry */
2024                         if (*nchans >= maxchans)
2025                                 break;
2026                         c[0] = c[-1];
2027                         c[-1].ic_flags = IEEE80211_CHAN_B;
2028                         c++, (*nchans)++;
2029                 }
2030                 if (flags == IEEE80211_CHAN_HTG) {
2031                         /* HT g channel have a separate g-only entry */
2032                         if (*nchans >= maxchans)
2033                                 break;
2034                         c[-1].ic_flags = IEEE80211_CHAN_G;
2035                         c[0] = c[-1];
2036                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2037                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2038                         c++, (*nchans)++;
2039                 }
2040                 if (flags == IEEE80211_CHAN_HTA) {
2041                         /* HT a channel have a separate a-only entry */
2042                         if (*nchans >= maxchans)
2043                                 break;
2044                         c[-1].ic_flags = IEEE80211_CHAN_A;
2045                         c[0] = c[-1];
2046                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2047                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2048                         c++, (*nchans)++;
2049                 }
2050         }
2051 }
2052
2053 static int
2054 bwn_phy_g_attach(struct bwn_mac *mac)
2055 {
2056         struct bwn_softc *sc = mac->mac_sc;
2057         struct bwn_phy *phy = &mac->mac_phy;
2058         struct bwn_phy_g *pg = &phy->phy_g;
2059         unsigned int i;
2060         int16_t pab0, pab1, pab2;
2061         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2062         int8_t bg;
2063
2064         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2065         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2066         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2067         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2068
2069         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2070                 device_printf(sc->sc_dev, "not supported anymore\n");
2071
2072         pg->pg_flags = 0;
2073         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2074             pab2 == -1) {
2075                 pg->pg_idletssi = 52;
2076                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2077                 return (0);
2078         }
2079
2080         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2081         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2082         if (pg->pg_tssi2dbm == NULL) {
2083                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2084                 return (ENOMEM);
2085         }
2086         for (i = 0; i < 64; i++) {
2087                 int32_t m1, m2, f, q, delta;
2088                 int8_t j = 0;
2089
2090                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2091                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2092                 f = 256;
2093
2094                 do {
2095                         if (j > 15) {
2096                                 device_printf(sc->sc_dev,
2097                                     "failed to generate tssi2dBm\n");
2098                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2099                                 return (ENOMEM);
2100                         }
2101                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2102                             f, 2048);
2103                         delta = abs(q - f);
2104                         f = q;
2105                         j++;
2106                 } while (delta >= 2);
2107
2108                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2109                     128);
2110         }
2111
2112         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2113         return (0);
2114 }
2115
2116 static void
2117 bwn_phy_g_detach(struct bwn_mac *mac)
2118 {
2119         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2120
2121         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2122                 free(pg->pg_tssi2dbm, M_DEVBUF);
2123                 pg->pg_tssi2dbm = NULL;
2124         }
2125         pg->pg_flags = 0;
2126 }
2127
2128 static void
2129 bwn_phy_g_init_pre(struct bwn_mac *mac)
2130 {
2131         struct bwn_phy *phy = &mac->mac_phy;
2132         struct bwn_phy_g *pg = &phy->phy_g;
2133         void *tssi2dbm;
2134         int idletssi;
2135         unsigned int i;
2136
2137         tssi2dbm = pg->pg_tssi2dbm;
2138         idletssi = pg->pg_idletssi;
2139
2140         memset(pg, 0, sizeof(*pg));
2141
2142         pg->pg_tssi2dbm = tssi2dbm;
2143         pg->pg_idletssi = idletssi;
2144
2145         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2146
2147         for (i = 0; i < N(pg->pg_nrssi); i++)
2148                 pg->pg_nrssi[i] = -1000;
2149         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2150                 pg->pg_nrssi_lt[i] = i;
2151         pg->pg_lofcal = 0xffff;
2152         pg->pg_initval = 0xffff;
2153         pg->pg_immode = BWN_IMMODE_NONE;
2154         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2155         pg->pg_avgtssi = 0xff;
2156
2157         pg->pg_loctl.tx_bias = 0xff;
2158         TAILQ_INIT(&pg->pg_loctl.calib_list);
2159 }
2160
2161 static int
2162 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2163 {
2164         struct bwn_phy *phy = &mac->mac_phy;
2165         struct bwn_phy_g *pg = &phy->phy_g;
2166         struct bwn_softc *sc = mac->mac_sc;
2167         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2168         static const struct bwn_rfatt rfatt0[] = {
2169                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2170                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2171                 { 3, 1 }, { 4, 1 }
2172         };
2173         static const struct bwn_rfatt rfatt1[] = {
2174                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2175                 { 14, 1 }
2176         };
2177         static const struct bwn_rfatt rfatt2[] = {
2178                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2179                 { 9, 1 }
2180         };
2181         static const struct bwn_bbatt bbatt_0[] = {
2182                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2183         };
2184
2185         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2186
2187         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2188                 pg->pg_bbatt.att = 0;
2189         else
2190                 pg->pg_bbatt.att = 2;
2191
2192         /* prepare Radio Attenuation */
2193         pg->pg_rfatt.padmix = 0;
2194
2195         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2196             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2197                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2198                         pg->pg_rfatt.att = 2;
2199                         goto done;
2200                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2201                         pg->pg_rfatt.att = 3;
2202                         goto done;
2203                 }
2204         }
2205
2206         if (phy->type == BWN_PHYTYPE_A) {
2207                 pg->pg_rfatt.att = 0x60;
2208                 goto done;
2209         }
2210
2211         switch (phy->rf_ver) {
2212         case 0x2050:
2213                 switch (phy->rf_rev) {
2214                 case 0:
2215                         pg->pg_rfatt.att = 5;
2216                         goto done;
2217                 case 1:
2218                         if (phy->type == BWN_PHYTYPE_G) {
2219                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2220                                     SIBA_BOARDVENDOR_BCM &&
2221                                     siba_get_pci_subdevice(sc->sc_dev) ==
2222                                     SIBA_BOARD_BCM4309G &&
2223                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2224                                         pg->pg_rfatt.att = 3;
2225                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2226                                     SIBA_BOARDVENDOR_BCM &&
2227                                     siba_get_pci_subdevice(sc->sc_dev) ==
2228                                     SIBA_BOARD_BU4306)
2229                                         pg->pg_rfatt.att = 3;
2230                                 else
2231                                         pg->pg_rfatt.att = 1;
2232                         } else {
2233                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2234                                     SIBA_BOARDVENDOR_BCM &&
2235                                     siba_get_pci_subdevice(sc->sc_dev) ==
2236                                     SIBA_BOARD_BCM4309G &&
2237                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2238                                         pg->pg_rfatt.att = 7;
2239                                 else
2240                                         pg->pg_rfatt.att = 6;
2241                         }
2242                         goto done;
2243                 case 2:
2244                         if (phy->type == BWN_PHYTYPE_G) {
2245                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2246                                     SIBA_BOARDVENDOR_BCM &&
2247                                     siba_get_pci_subdevice(sc->sc_dev) ==
2248                                     SIBA_BOARD_BCM4309G &&
2249                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2250                                         pg->pg_rfatt.att = 3;
2251                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2252                                     SIBA_BOARDVENDOR_BCM &&
2253                                     siba_get_pci_subdevice(sc->sc_dev) ==
2254                                     SIBA_BOARD_BU4306)
2255                                         pg->pg_rfatt.att = 5;
2256                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2257                                         pg->pg_rfatt.att = 4;
2258                                 else
2259                                         pg->pg_rfatt.att = 3;
2260                         } else
2261                                 pg->pg_rfatt.att = 6;
2262                         goto done;
2263                 case 3:
2264                         pg->pg_rfatt.att = 5;
2265                         goto done;
2266                 case 4:
2267                 case 5:
2268                         pg->pg_rfatt.att = 1;
2269                         goto done;
2270                 case 6:
2271                 case 7:
2272                         pg->pg_rfatt.att = 5;
2273                         goto done;
2274                 case 8:
2275                         pg->pg_rfatt.att = 0xa;
2276                         pg->pg_rfatt.padmix = 1;
2277                         goto done;
2278                 case 9:
2279                 default:
2280                         pg->pg_rfatt.att = 5;
2281                         goto done;
2282                 }
2283                 break;
2284         case 0x2053:
2285                 switch (phy->rf_rev) {
2286                 case 1:
2287                         pg->pg_rfatt.att = 6;
2288                         goto done;
2289                 }
2290                 break;
2291         }
2292         pg->pg_rfatt.att = 5;
2293 done:
2294         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2295
2296         if (!bwn_has_hwpctl(mac)) {
2297                 lo->rfatt.array = rfatt0;
2298                 lo->rfatt.len = N(rfatt0);
2299                 lo->rfatt.min = 0;
2300                 lo->rfatt.max = 9;
2301                 goto genbbatt;
2302         }
2303         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2304                 lo->rfatt.array = rfatt1;
2305                 lo->rfatt.len = N(rfatt1);
2306                 lo->rfatt.min = 0;
2307                 lo->rfatt.max = 14;
2308                 goto genbbatt;
2309         }
2310         lo->rfatt.array = rfatt2;
2311         lo->rfatt.len = N(rfatt2);
2312         lo->rfatt.min = 0;
2313         lo->rfatt.max = 9;
2314 genbbatt:
2315         lo->bbatt.array = bbatt_0;
2316         lo->bbatt.len = N(bbatt_0);
2317         lo->bbatt.min = 0;
2318         lo->bbatt.max = 8;
2319
2320         BWN_READ_4(mac, BWN_MACCTL);
2321         if (phy->rev == 1) {
2322                 phy->gmode = 0;
2323                 bwn_reset_core(mac, 0);
2324                 bwn_phy_g_init_sub(mac);
2325                 phy->gmode = 1;
2326                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2327         }
2328         return (0);
2329 }
2330
2331 static uint16_t
2332 bwn_phy_g_txctl(struct bwn_mac *mac)
2333 {
2334         struct bwn_phy *phy = &mac->mac_phy;
2335
2336         if (phy->rf_ver != 0x2050)
2337                 return (0);
2338         if (phy->rf_rev == 1)
2339                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2340         if (phy->rf_rev < 6)
2341                 return (BWN_TXCTL_PA2DB);
2342         if (phy->rf_rev == 8)
2343                 return (BWN_TXCTL_TXMIX);
2344         return (0);
2345 }
2346
2347 static int
2348 bwn_phy_g_init(struct bwn_mac *mac)
2349 {
2350
2351         bwn_phy_g_init_sub(mac);
2352         return (0);
2353 }
2354
2355 static void
2356 bwn_phy_g_exit(struct bwn_mac *mac)
2357 {
2358         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2359         struct bwn_lo_calib *cal, *tmp;
2360
2361         if (lo == NULL)
2362                 return;
2363         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2364                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2365                 free(cal, M_DEVBUF);
2366         }
2367 }
2368
2369 static uint16_t
2370 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2371 {
2372
2373         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2374         return (BWN_READ_2(mac, BWN_PHYDATA));
2375 }
2376
2377 static void
2378 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2379 {
2380
2381         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2382         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2383 }
2384
2385 static uint16_t
2386 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2387 {
2388
2389         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2390         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2391         return (BWN_READ_2(mac, BWN_RFDATALO));
2392 }
2393
2394 static void
2395 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2396 {
2397
2398         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2399         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2400         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2401 }
2402
2403 static int
2404 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2405 {
2406
2407         return (mac->mac_phy.rev >= 6);
2408 }
2409
2410 static void
2411 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2412 {
2413         struct bwn_phy *phy = &mac->mac_phy;
2414         struct bwn_phy_g *pg = &phy->phy_g;
2415         unsigned int channel;
2416         uint16_t rfover, rfoverval;
2417
2418         if (on) {
2419                 if (phy->rf_on)
2420                         return;
2421
2422                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2423                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2424                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2425                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2426                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2427                             pg->pg_radioctx_over);
2428                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2429                             pg->pg_radioctx_overval);
2430                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2431                 }
2432                 channel = phy->chan;
2433                 bwn_phy_g_switch_chan(mac, 6, 1);
2434                 bwn_phy_g_switch_chan(mac, channel, 0);
2435                 return;
2436         }
2437
2438         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2439         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2440         pg->pg_radioctx_over = rfover;
2441         pg->pg_radioctx_overval = rfoverval;
2442         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2443         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2444         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2445 }
2446
2447 static int
2448 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2449 {
2450
2451         if ((newchan < 1) || (newchan > 14))
2452                 return (EINVAL);
2453         bwn_phy_g_switch_chan(mac, newchan, 0);
2454
2455         return (0);
2456 }
2457
2458 static uint32_t
2459 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2460 {
2461
2462         return (1);
2463 }
2464
2465 static void
2466 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2467 {
2468         struct bwn_phy *phy = &mac->mac_phy;
2469         uint64_t hf;
2470         int autodiv = 0;
2471         uint16_t tmp;
2472
2473         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2474                 autodiv = 1;
2475
2476         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2477         bwn_hf_write(mac, hf);
2478
2479         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2480             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2481             ((autodiv ? BWN_ANTAUTO1 : antenna)
2482                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2483
2484         if (autodiv) {
2485                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2486                 if (antenna == BWN_ANTAUTO1)
2487                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2488                 else
2489                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2490                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2491         }
2492         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2493         if (autodiv)
2494                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2495         else
2496                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2497         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2498         if (phy->rev >= 2) {
2499                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2500                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2501                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2502                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2503                     0x15);
2504                 if (phy->rev == 2)
2505                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2506                 else
2507                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2508                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2509                             8);
2510         }
2511         if (phy->rev >= 6)
2512                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2513
2514         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2515         bwn_hf_write(mac, hf);
2516 }
2517
2518 static int
2519 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2520 {
2521         struct bwn_phy *phy = &mac->mac_phy;
2522         struct bwn_phy_g *pg = &phy->phy_g;
2523
2524         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2525         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2526
2527         if (phy->rev == 0 || !phy->gmode)
2528                 return (ENODEV);
2529
2530         pg->pg_aci_wlan_automatic = 0;
2531         return (0);
2532 }
2533
2534 static int
2535 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2536 {
2537         struct bwn_phy *phy = &mac->mac_phy;
2538         struct bwn_phy_g *pg = &phy->phy_g;
2539         struct bwn_softc *sc = mac->mac_sc;
2540         unsigned int tssi;
2541         int cck, ofdm;
2542         int power;
2543         int rfatt, bbatt;
2544         unsigned int max;
2545
2546         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2547
2548         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2549         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2550         if (cck < 0 && ofdm < 0) {
2551                 if (ignore_tssi == 0)
2552                         return (BWN_TXPWR_RES_DONE);
2553                 cck = 0;
2554                 ofdm = 0;
2555         }
2556         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2557         if (pg->pg_avgtssi != 0xff)
2558                 tssi = (tssi + pg->pg_avgtssi) / 2;
2559         pg->pg_avgtssi = tssi;
2560         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2561
2562         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2563         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2564                 max -= 3;
2565         if (max >= 120) {
2566                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2567                 max = 80;
2568                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2569         }
2570
2571         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2572             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2573              tssi, 0x00), 0x3f)]);
2574         if (power == 0)
2575                 return (BWN_TXPWR_RES_DONE);
2576
2577         rfatt = -((power + 7) / 8);
2578         bbatt = (-(power / 2)) - (4 * rfatt);
2579         if ((rfatt == 0) && (bbatt == 0))
2580                 return (BWN_TXPWR_RES_DONE);
2581         pg->pg_bbatt_delta = bbatt;
2582         pg->pg_rfatt_delta = rfatt;
2583         return (BWN_TXPWR_RES_NEED_ADJUST);
2584 }
2585
2586 static void
2587 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2588 {
2589         struct bwn_phy *phy = &mac->mac_phy;
2590         struct bwn_phy_g *pg = &phy->phy_g;
2591         struct bwn_softc *sc = mac->mac_sc;
2592         int rfatt, bbatt;
2593         uint8_t txctl;
2594
2595         bwn_mac_suspend(mac);
2596
2597         BWN_ASSERT_LOCKED(sc);
2598
2599         bbatt = pg->pg_bbatt.att;
2600         bbatt += pg->pg_bbatt_delta;
2601         rfatt = pg->pg_rfatt.att;
2602         rfatt += pg->pg_rfatt_delta;
2603
2604         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2605         txctl = pg->pg_txctl;
2606         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2607                 if (rfatt <= 1) {
2608                         if (txctl == 0) {
2609                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2610                                 rfatt += 2;
2611                                 bbatt += 2;
2612                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2613                             BWN_BFL_PACTRL) {
2614                                 bbatt += 4 * (rfatt - 2);
2615                                 rfatt = 2;
2616                         }
2617                 } else if (rfatt > 4 && txctl) {
2618                         txctl = 0;
2619                         if (bbatt < 3) {
2620                                 rfatt -= 3;
2621                                 bbatt += 2;
2622                         } else {
2623                                 rfatt -= 2;
2624                                 bbatt -= 2;
2625                         }
2626                 }
2627         }
2628         pg->pg_txctl = txctl;
2629         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2630         pg->pg_rfatt.att = rfatt;
2631         pg->pg_bbatt.att = bbatt;
2632
2633         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2634
2635         bwn_phy_lock(mac);
2636         bwn_rf_lock(mac);
2637         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2638             pg->pg_txctl);
2639         bwn_rf_unlock(mac);
2640         bwn_phy_unlock(mac);
2641
2642         bwn_mac_enable(mac);
2643 }
2644
2645 static void
2646 bwn_phy_g_task_15s(struct bwn_mac *mac)
2647 {
2648         struct bwn_phy *phy = &mac->mac_phy;
2649         struct bwn_phy_g *pg = &phy->phy_g;
2650         struct bwn_softc *sc = mac->mac_sc;
2651         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2652         unsigned long expire, now;
2653         struct bwn_lo_calib *cal, *tmp;
2654         uint8_t expired = 0;
2655
2656         bwn_mac_suspend(mac);
2657
2658         if (lo == NULL)
2659                 goto fail;
2660
2661         BWN_GETTIME(now);
2662         if (bwn_has_hwpctl(mac)) {
2663                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2664                 if (time_before(lo->pwr_vec_read_time, expire)) {
2665                         bwn_lo_get_powervector(mac);
2666                         bwn_phy_g_dc_lookup_init(mac, 0);
2667                 }
2668                 goto fail;
2669         }
2670
2671         expire = now - BWN_LO_CALIB_EXPIRE;
2672         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2673                 if (!time_before(cal->calib_time, expire))
2674                         continue;
2675                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2676                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2677                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2678                         expired = 1;
2679                 }
2680
2681                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2682                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2683                     cal->ctl.i, cal->ctl.q);
2684
2685                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2686                 free(cal, M_DEVBUF);
2687         }
2688         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2689                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2690                     &pg->pg_rfatt);
2691                 if (cal == NULL) {
2692                         device_printf(sc->sc_dev,
2693                             "failed to recalibrate LO\n");
2694                         goto fail;
2695                 }
2696                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2697                 bwn_lo_write(mac, &cal->ctl);
2698         }
2699
2700 fail:
2701         bwn_mac_enable(mac);
2702 }
2703
2704 static void
2705 bwn_phy_g_task_60s(struct bwn_mac *mac)
2706 {
2707         struct bwn_phy *phy = &mac->mac_phy;
2708         struct bwn_softc *sc = mac->mac_sc;
2709         uint8_t old = phy->chan;
2710
2711         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2712                 return;
2713
2714         bwn_mac_suspend(mac);
2715         bwn_nrssi_slope_11g(mac);
2716         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2717                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2718                 bwn_switch_channel(mac, old);
2719         }
2720         bwn_mac_enable(mac);
2721 }
2722
2723 static void
2724 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2725 {
2726
2727         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2728 }
2729
2730 static int
2731 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2732         const struct ieee80211_bpf_params *params)
2733 {
2734         struct ieee80211com *ic = ni->ni_ic;
2735         struct ifnet *ifp = ic->ic_ifp;
2736         struct bwn_softc *sc = ifp->if_softc;
2737         struct bwn_mac *mac = sc->sc_curmac;
2738
2739         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2740             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2741                 ieee80211_free_node(ni);
2742                 m_freem(m);
2743                 return (ENETDOWN);
2744         }
2745
2746         BWN_LOCK(sc);
2747         if (bwn_tx_isfull(sc, m)) {
2748                 ieee80211_free_node(ni);
2749                 m_freem(m);
2750                 ifp->if_oerrors++;
2751                 BWN_UNLOCK(sc);
2752                 return (ENOBUFS);
2753         }
2754
2755         if (bwn_tx_start(sc, ni, m) != 0) {
2756                 if (ni != NULL)
2757                         ieee80211_free_node(ni);
2758                 ifp->if_oerrors++;
2759         }
2760         sc->sc_watchdog_timer = 5;
2761         BWN_UNLOCK(sc);
2762         return (0);
2763 }
2764
2765 /*
2766  * Callback from the 802.11 layer to update the slot time
2767  * based on the current setting.  We use it to notify the
2768  * firmware of ERP changes and the f/w takes care of things
2769  * like slot time and preamble.
2770  */
2771 static void
2772 bwn_updateslot(struct ifnet *ifp)
2773 {
2774         struct bwn_softc *sc = ifp->if_softc;
2775         struct ieee80211com *ic = ifp->if_l2com;
2776         struct bwn_mac *mac;
2777
2778         BWN_LOCK(sc);
2779         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2780                 mac = (struct bwn_mac *)sc->sc_curmac;
2781                 bwn_set_slot_time(mac,
2782                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2783         }
2784         BWN_UNLOCK(sc);
2785 }
2786
2787 /*
2788  * Callback from the 802.11 layer after a promiscuous mode change.
2789  * Note this interface does not check the operating mode as this
2790  * is an internal callback and we are expected to honor the current
2791  * state (e.g. this is used for setting the interface in promiscuous
2792  * mode when operating in hostap mode to do ACS).
2793  */
2794 static void
2795 bwn_update_promisc(struct ifnet *ifp)
2796 {
2797         struct bwn_softc *sc = ifp->if_softc;
2798         struct bwn_mac *mac = sc->sc_curmac;
2799
2800         BWN_LOCK(sc);
2801         mac = sc->sc_curmac;
2802         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2803                 if (ifp->if_flags & IFF_PROMISC)
2804                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2805                 else
2806                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2807                 bwn_set_opmode(mac);
2808         }
2809         BWN_UNLOCK(sc);
2810 }
2811
2812 /*
2813  * Callback from the 802.11 layer to update WME parameters.
2814  */
2815 static int
2816 bwn_wme_update(struct ieee80211com *ic)
2817 {
2818         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2819         struct bwn_mac *mac = sc->sc_curmac;
2820         struct wmeParams *wmep;
2821         int i;
2822
2823         BWN_LOCK(sc);
2824         mac = sc->sc_curmac;
2825         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2826                 bwn_mac_suspend(mac);
2827                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2828                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2829                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2830                 }
2831                 bwn_mac_enable(mac);
2832         }
2833         BWN_UNLOCK(sc);
2834         return (0);
2835 }
2836
2837 static void
2838 bwn_scan_start(struct ieee80211com *ic)
2839 {
2840         struct ifnet *ifp = ic->ic_ifp;
2841         struct bwn_softc *sc = ifp->if_softc;
2842         struct bwn_mac *mac;
2843
2844         BWN_LOCK(sc);
2845         mac = sc->sc_curmac;
2846         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2848                 bwn_set_opmode(mac);
2849                 /* disable CFP update during scan */
2850                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2851         }
2852         BWN_UNLOCK(sc);
2853 }
2854
2855 static void
2856 bwn_scan_end(struct ieee80211com *ic)
2857 {
2858         struct ifnet *ifp = ic->ic_ifp;
2859         struct bwn_softc *sc = ifp->if_softc;
2860         struct bwn_mac *mac;
2861
2862         BWN_LOCK(sc);
2863         mac = sc->sc_curmac;
2864         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2865                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2866                 bwn_set_opmode(mac);
2867                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2868         }
2869         BWN_UNLOCK(sc);
2870 }
2871
2872 static void
2873 bwn_set_channel(struct ieee80211com *ic)
2874 {
2875         struct ifnet *ifp = ic->ic_ifp;
2876         struct bwn_softc *sc = ifp->if_softc;
2877         struct bwn_mac *mac = sc->sc_curmac;
2878         struct bwn_phy *phy = &mac->mac_phy;
2879         int chan, error;
2880
2881         BWN_LOCK(sc);
2882
2883         error = bwn_switch_band(sc, ic->ic_curchan);
2884         if (error)
2885                 goto fail;;
2886         bwn_mac_suspend(mac);
2887         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2888         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2889         if (chan != phy->chan)
2890                 bwn_switch_channel(mac, chan);
2891
2892         /* TX power level */
2893         if (ic->ic_curchan->ic_maxpower != 0 &&
2894             ic->ic_curchan->ic_maxpower != phy->txpower) {
2895                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2896                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2897                     BWN_TXPWR_IGNORE_TSSI);
2898         }
2899
2900         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2901         if (phy->set_antenna)
2902                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2903
2904         if (sc->sc_rf_enabled != phy->rf_on) {
2905                 if (sc->sc_rf_enabled) {
2906                         bwn_rf_turnon(mac);
2907                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2908                                 device_printf(sc->sc_dev,
2909                                     "please turns on the RF switch\n");
2910                 } else
2911                         bwn_rf_turnoff(mac);
2912         }
2913
2914         bwn_mac_enable(mac);
2915
2916 fail:
2917         /*
2918          * Setup radio tap channel freq and flags
2919          */
2920         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2921                 htole16(ic->ic_curchan->ic_freq);
2922         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2923                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2924
2925         BWN_UNLOCK(sc);
2926 }
2927
2928 static struct ieee80211vap *
2929 bwn_vap_create(struct ieee80211com *ic,
2930         const char name[IFNAMSIZ], int unit, int opmode, int flags,
2931         const uint8_t bssid[IEEE80211_ADDR_LEN],
2932         const uint8_t mac0[IEEE80211_ADDR_LEN])
2933 {
2934         struct ifnet *ifp = ic->ic_ifp;
2935         struct bwn_softc *sc = ifp->if_softc;
2936         struct ieee80211vap *vap;
2937         struct bwn_vap *bvp;
2938         uint8_t mac[IEEE80211_ADDR_LEN];
2939
2940         IEEE80211_ADDR_COPY(mac, mac0);
2941         switch (opmode) {
2942         case IEEE80211_M_HOSTAP:
2943         case IEEE80211_M_MBSS:
2944         case IEEE80211_M_STA:
2945         case IEEE80211_M_WDS:
2946         case IEEE80211_M_MONITOR:
2947         case IEEE80211_M_IBSS:
2948         case IEEE80211_M_AHDEMO:
2949                 break;
2950         default:
2951                 return (NULL);
2952         }
2953
2954         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2955
2956         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2957             M_80211_VAP, M_NOWAIT | M_ZERO);
2958         if (bvp == NULL) {
2959                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2960                 return (NULL);
2961         }
2962         vap = &bvp->bv_vap;
2963         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2964         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2965         /* override with driver methods */
2966         bvp->bv_newstate = vap->iv_newstate;
2967         vap->iv_newstate = bwn_newstate;
2968
2969         /* override max aid so sta's cannot assoc when we're out of sta id's */
2970         vap->iv_max_aid = BWN_STAID_MAX;
2971
2972         ieee80211_ratectl_init(vap);
2973
2974         /* complete setup */
2975         ieee80211_vap_attach(vap, ieee80211_media_change,
2976             ieee80211_media_status);
2977         return (vap);
2978 }
2979
2980 static void
2981 bwn_vap_delete(struct ieee80211vap *vap)
2982 {
2983         struct bwn_vap *bvp = BWN_VAP(vap);
2984
2985         ieee80211_ratectl_deinit(vap);
2986         ieee80211_vap_detach(vap);
2987         free(bvp, M_80211_VAP);
2988 }
2989
2990 static void
2991 bwn_init(void *arg)
2992 {
2993         struct bwn_softc *sc = arg;
2994         struct ifnet *ifp = sc->sc_ifp;
2995         struct ieee80211com *ic = ifp->if_l2com;
2996         int error = 0;
2997
2998         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2999                 __func__, ifp->if_flags);
3000
3001         BWN_LOCK(sc);
3002         error = bwn_init_locked(sc);
3003         BWN_UNLOCK(sc);
3004
3005         if (error == 0)
3006                 ieee80211_start_all(ic);        /* start all vap's */
3007 }
3008
3009 static int
3010 bwn_init_locked(struct bwn_softc *sc)
3011 {
3012         struct bwn_mac *mac;
3013         struct ifnet *ifp = sc->sc_ifp;
3014         int error;
3015
3016         BWN_ASSERT_LOCKED(sc);
3017
3018         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3019         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3020         sc->sc_filters = 0;
3021         bwn_wme_clear(sc);
3022         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3023         sc->sc_rf_enabled = 1;
3024
3025         mac = sc->sc_curmac;
3026         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3027                 error = bwn_core_init(mac);
3028                 if (error != 0)
3029                         return (error);
3030         }
3031         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3032                 bwn_core_start(mac);
3033
3034         bwn_set_opmode(mac);
3035         bwn_set_pretbtt(mac);
3036         bwn_spu_setdelay(mac, 0);
3037         bwn_set_macaddr(mac);
3038
3039         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3040         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3041         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3042
3043         return (0);
3044 }
3045
3046 static void
3047 bwn_stop(struct bwn_softc *sc, int statechg)
3048 {
3049
3050         BWN_LOCK(sc);
3051         bwn_stop_locked(sc, statechg);
3052         BWN_UNLOCK(sc);
3053 }
3054
3055 static void
3056 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3057 {
3058         struct bwn_mac *mac = sc->sc_curmac;
3059         struct ifnet *ifp = sc->sc_ifp;
3060
3061         BWN_ASSERT_LOCKED(sc);
3062
3063         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3064                 /* XXX FIXME opmode not based on VAP */
3065                 bwn_set_opmode(mac);
3066                 bwn_set_macaddr(mac);
3067         }
3068
3069         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3070                 bwn_core_stop(mac);
3071
3072         callout_stop(&sc->sc_led_blink_ch);
3073         sc->sc_led_blinking = 0;
3074
3075         bwn_core_exit(mac);
3076         sc->sc_rf_enabled = 0;
3077
3078         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3079 }
3080
3081 static void
3082 bwn_wme_clear(struct bwn_softc *sc)
3083 {
3084 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3085         struct wmeParams *p;
3086         unsigned int i;
3087
3088         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3089             ("%s:%d: fail", __func__, __LINE__));
3090
3091         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3092                 p = &(sc->sc_wmeParams[i]);
3093
3094                 switch (bwn_wme_shm_offsets[i]) {
3095                 case BWN_WME_VOICE:
3096                         p->wmep_txopLimit = 0;
3097                         p->wmep_aifsn = 2;
3098                         /* XXX FIXME: log2(cwmin) */
3099                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3100                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3101                         break;
3102                 case BWN_WME_VIDEO:
3103                         p->wmep_txopLimit = 0;
3104                         p->wmep_aifsn = 2;
3105                         /* XXX FIXME: log2(cwmin) */
3106                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3107                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3108                         break;
3109                 case BWN_WME_BESTEFFORT:
3110                         p->wmep_txopLimit = 0;
3111                         p->wmep_aifsn = 3;
3112                         /* XXX FIXME: log2(cwmin) */
3113                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3114                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3115                         break;
3116                 case BWN_WME_BACKGROUND:
3117                         p->wmep_txopLimit = 0;
3118                         p->wmep_aifsn = 7;
3119                         /* XXX FIXME: log2(cwmin) */
3120                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3121                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3122                         break;
3123                 default:
3124                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3125                 }
3126         }
3127 }
3128
3129 static int
3130 bwn_core_init(struct bwn_mac *mac)
3131 {
3132         struct bwn_softc *sc = mac->mac_sc;
3133         uint64_t hf;
3134         int error;
3135
3136         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3137             ("%s:%d: fail", __func__, __LINE__));
3138
3139         siba_powerup(sc->sc_dev, 0);
3140         if (!siba_dev_isup(sc->sc_dev))
3141                 bwn_reset_core(mac,
3142                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3143
3144         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3145         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3146         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3147         BWN_GETTIME(mac->mac_phy.nexttime);
3148         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3149         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3150         mac->mac_stats.link_noise = -95;
3151         mac->mac_reason_intr = 0;
3152         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3153         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3154 #ifdef BWN_DEBUG
3155         if (sc->sc_debug & BWN_DEBUG_XMIT)
3156                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3157 #endif
3158         mac->mac_suspended = 1;
3159         mac->mac_task_state = 0;
3160         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3161
3162         mac->mac_phy.init_pre(mac);
3163
3164         siba_pcicore_intr(sc->sc_dev);
3165
3166         siba_fix_imcfglobug(sc->sc_dev);
3167         bwn_bt_disable(mac);
3168         if (mac->mac_phy.prepare_hw) {
3169                 error = mac->mac_phy.prepare_hw(mac);
3170                 if (error)
3171                         goto fail0;
3172         }
3173         error = bwn_chip_init(mac);
3174         if (error)
3175                 goto fail0;
3176         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3177             siba_get_revid(sc->sc_dev));
3178         hf = bwn_hf_read(mac);
3179         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3180                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3181                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3182                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3183                 if (mac->mac_phy.rev == 1)
3184                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3185         }
3186         if (mac->mac_phy.rf_ver == 0x2050) {
3187                 if (mac->mac_phy.rf_rev < 6)
3188                         hf |= BWN_HF_FORCE_VCO_RECALC;
3189                 if (mac->mac_phy.rf_rev == 6)
3190                         hf |= BWN_HF_4318_TSSI;
3191         }
3192         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3193                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3194         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3195             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3196                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3197         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3198         bwn_hf_write(mac, hf);
3199
3200         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3201         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3202         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3203         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3204
3205         bwn_rate_init(mac);
3206         bwn_set_phytxctl(mac);
3207
3208         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3209             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3210         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3211
3212         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3213                 bwn_pio_init(mac);
3214         else
3215                 bwn_dma_init(mac);
3216         if (error)
3217                 goto fail1;
3218         bwn_wme_init(mac);
3219         bwn_spu_setdelay(mac, 1);
3220         bwn_bt_enable(mac);
3221
3222         siba_powerup(sc->sc_dev,
3223             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3224         bwn_set_macaddr(mac);
3225         bwn_crypt_init(mac);
3226
3227         /* XXX LED initializatin */
3228
3229         mac->mac_status = BWN_MAC_STATUS_INITED;
3230
3231         return (error);
3232
3233 fail1:
3234         bwn_chip_exit(mac);
3235 fail0:
3236         siba_powerdown(sc->sc_dev);
3237         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3238             ("%s:%d: fail", __func__, __LINE__));
3239         return (error);
3240 }
3241
3242 static void
3243 bwn_core_start(struct bwn_mac *mac)
3244 {
3245         struct bwn_softc *sc = mac->mac_sc;
3246         uint32_t tmp;
3247
3248         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3249             ("%s:%d: fail", __func__, __LINE__));
3250
3251         if (siba_get_revid(sc->sc_dev) < 5)
3252                 return;
3253
3254         while (1) {
3255                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3256                 if (!(tmp & 0x00000001))
3257                         break;
3258                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3259         }
3260
3261         bwn_mac_enable(mac);
3262         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3263         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3264
3265         mac->mac_status = BWN_MAC_STATUS_STARTED;
3266 }
3267
3268 static void
3269 bwn_core_exit(struct bwn_mac *mac)
3270 {
3271         struct bwn_softc *sc = mac->mac_sc;
3272         uint32_t macctl;
3273
3274         BWN_ASSERT_LOCKED(mac->mac_sc);
3275
3276         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3277             ("%s:%d: fail", __func__, __LINE__));
3278
3279         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3280                 return;
3281         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3282
3283         macctl = BWN_READ_4(mac, BWN_MACCTL);
3284         macctl &= ~BWN_MACCTL_MCODE_RUN;
3285         macctl |= BWN_MACCTL_MCODE_JMP0;
3286         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3287
3288         bwn_dma_stop(mac);
3289         bwn_pio_stop(mac);
3290         bwn_chip_exit(mac);
3291         mac->mac_phy.switch_analog(mac, 0);
3292         siba_dev_down(sc->sc_dev, 0);
3293         siba_powerdown(sc->sc_dev);
3294 }
3295
3296 static void
3297 bwn_bt_disable(struct bwn_mac *mac)
3298 {
3299         struct bwn_softc *sc = mac->mac_sc;
3300
3301         (void)sc;
3302         /* XXX do nothing yet */
3303 }
3304
3305 static int
3306 bwn_chip_init(struct bwn_mac *mac)
3307 {
3308         struct bwn_softc *sc = mac->mac_sc;
3309         struct bwn_phy *phy = &mac->mac_phy;
3310         uint32_t macctl;
3311         int error;
3312
3313         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3314         if (phy->gmode)
3315                 macctl |= BWN_MACCTL_GMODE;
3316         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3317
3318         error = bwn_fw_fillinfo(mac);
3319         if (error)
3320                 return (error);
3321         error = bwn_fw_loaducode(mac);
3322         if (error)
3323                 return (error);
3324
3325         error = bwn_gpio_init(mac);
3326         if (error)
3327                 return (error);
3328
3329         error = bwn_fw_loadinitvals(mac);
3330         if (error) {
3331                 siba_gpio_set(sc->sc_dev, 0);
3332                 return (error);
3333         }
3334         phy->switch_analog(mac, 1);
3335         error = bwn_phy_init(mac);
3336         if (error) {
3337                 siba_gpio_set(sc->sc_dev, 0);
3338                 return (error);
3339         }
3340         if (phy->set_im)
3341                 phy->set_im(mac, BWN_IMMODE_NONE);
3342         if (phy->set_antenna)
3343                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3344         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3345
3346         if (phy->type == BWN_PHYTYPE_B)
3347                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3348         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3349         if (siba_get_revid(sc->sc_dev) < 5)
3350                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3351
3352         BWN_WRITE_4(mac, BWN_MACCTL,
3353             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3354         BWN_WRITE_4(mac, BWN_MACCTL,
3355             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3356         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3357
3358         bwn_set_opmode(mac);
3359         if (siba_get_revid(sc->sc_dev) < 3) {
3360                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3361                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3362                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3363                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3364         } else {
3365                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3366                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3367         }
3368         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3369         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3370         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3371         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3372         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3373         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3374         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3375         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3376             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3377         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3378         return (error);
3379 }
3380
3381 /* read hostflags */
3382 static uint64_t
3383 bwn_hf_read(struct bwn_mac *mac)
3384 {
3385         uint64_t ret;
3386
3387         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3388         ret <<= 16;
3389         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3390         ret <<= 16;
3391         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3392         return (ret);
3393 }
3394
3395 static void
3396 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3397 {
3398
3399         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3400             (value & 0x00000000ffffull));
3401         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3402             (value & 0x0000ffff0000ull) >> 16);
3403         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3404             (value & 0xffff00000000ULL) >> 32);
3405 }
3406
3407 static void
3408 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3409 {
3410
3411         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3412         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3413 }
3414
3415 static void
3416 bwn_rate_init(struct bwn_mac *mac)
3417 {
3418
3419         switch (mac->mac_phy.type) {
3420         case BWN_PHYTYPE_A:
3421         case BWN_PHYTYPE_G:
3422         case BWN_PHYTYPE_LP:
3423         case BWN_PHYTYPE_N:
3424                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3425                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3426                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3427                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3428                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3429                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3430                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3431                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3432                         break;
3433                 /* FALLTHROUGH */
3434         case BWN_PHYTYPE_B:
3435                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3436                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3437                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3438                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3439                 break;
3440         default:
3441                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3442         }
3443 }
3444
3445 static void
3446 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3447 {
3448         uint16_t offset;
3449
3450         if (ofdm) {
3451                 offset = 0x480;
3452                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3453         } else {
3454                 offset = 0x4c0;
3455                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3456         }
3457         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3458             bwn_shm_read_2(mac, BWN_SHARED, offset));
3459 }
3460
3461 static uint8_t
3462 bwn_plcp_getcck(const uint8_t bitrate)
3463 {
3464
3465         switch (bitrate) {
3466         case BWN_CCK_RATE_1MB:
3467                 return (0x0a);
3468         case BWN_CCK_RATE_2MB:
3469                 return (0x14);
3470         case BWN_CCK_RATE_5MB:
3471                 return (0x37);
3472         case BWN_CCK_RATE_11MB:
3473                 return (0x6e);
3474         }
3475         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3476         return (0);
3477 }
3478
3479 static uint8_t
3480 bwn_plcp_getofdm(const uint8_t bitrate)
3481 {
3482
3483         switch (bitrate) {
3484         case BWN_OFDM_RATE_6MB:
3485                 return (0xb);
3486         case BWN_OFDM_RATE_9MB:
3487                 return (0xf);
3488         case BWN_OFDM_RATE_12MB:
3489                 return (0xa);
3490         case BWN_OFDM_RATE_18MB:
3491                 return (0xe);
3492         case BWN_OFDM_RATE_24MB:
3493                 return (0x9);
3494         case BWN_OFDM_RATE_36MB:
3495                 return (0xd);
3496         case BWN_OFDM_RATE_48MB:
3497                 return (0x8);
3498         case BWN_OFDM_RATE_54MB:
3499                 return (0xc);
3500         }
3501         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3502         return (0);
3503 }
3504
3505 static void
3506 bwn_set_phytxctl(struct bwn_mac *mac)
3507 {
3508         uint16_t ctl;
3509
3510         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3511             BWN_TX_PHY_TXPWR);
3512         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3513         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3514         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3515 }
3516
3517 static void
3518 bwn_pio_init(struct bwn_mac *mac)
3519 {
3520         struct bwn_pio *pio = &mac->mac_method.pio;
3521
3522         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3523             & ~BWN_MACCTL_BIGENDIAN);
3524         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3525
3526         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3527         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3528         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3529         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3530         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3531         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3532 }
3533
3534 static void
3535 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3536     int index)
3537 {
3538         struct bwn_pio_txpkt *tp;
3539         struct bwn_softc *sc = mac->mac_sc;
3540         unsigned int i;
3541
3542         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3543         tq->tq_index = index;
3544
3545         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3546         if (siba_get_revid(sc->sc_dev) >= 8)
3547                 tq->tq_size = 1920;
3548         else {
3549                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3550                 tq->tq_size -= 80;
3551         }
3552
3553         TAILQ_INIT(&tq->tq_pktlist);
3554         for (i = 0; i < N(tq->tq_pkts); i++) {
3555                 tp = &(tq->tq_pkts[i]);
3556                 tp->tp_index = i;
3557                 tp->tp_queue = tq;
3558                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3559         }
3560 }
3561
3562 static uint16_t
3563 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3564 {
3565         struct bwn_softc *sc = mac->mac_sc;
3566         static const uint16_t bases[] = {
3567                 BWN_PIO_BASE0,
3568                 BWN_PIO_BASE1,
3569                 BWN_PIO_BASE2,
3570                 BWN_PIO_BASE3,
3571                 BWN_PIO_BASE4,
3572                 BWN_PIO_BASE5,
3573                 BWN_PIO_BASE6,
3574                 BWN_PIO_BASE7,
3575         };
3576         static const uint16_t bases_rev11[] = {
3577                 BWN_PIO11_BASE0,
3578                 BWN_PIO11_BASE1,
3579                 BWN_PIO11_BASE2,
3580                 BWN_PIO11_BASE3,
3581                 BWN_PIO11_BASE4,
3582                 BWN_PIO11_BASE5,
3583         };
3584
3585         if (siba_get_revid(sc->sc_dev) >= 11) {
3586                 if (index >= N(bases_rev11))
3587                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3588                 return (bases_rev11[index]);
3589         }
3590         if (index >= N(bases))
3591                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3592         return (bases[index]);
3593 }
3594
3595 static void
3596 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3597     int index)
3598 {
3599         struct bwn_softc *sc = mac->mac_sc;
3600
3601         prq->prq_mac = mac;
3602         prq->prq_rev = siba_get_revid(sc->sc_dev);
3603         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3604         bwn_dma_rxdirectfifo(mac, index, 1);
3605 }
3606
3607 static void
3608 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3609 {
3610         if (tq == NULL)
3611                 return;
3612         bwn_pio_cancel_tx_packets(tq);
3613 }
3614
3615 static void
3616 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3617 {
3618
3619         bwn_destroy_pioqueue_tx(pio);
3620 }
3621
3622 static uint16_t
3623 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3624     uint16_t offset)
3625 {
3626
3627         return (BWN_READ_2(mac, tq->tq_base + offset));
3628 }
3629
3630 static void
3631 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3632 {
3633         uint32_t ctl;
3634         int type;
3635         uint16_t base;
3636
3637         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3638         base = bwn_dma_base(type, idx);
3639         if (type == BWN_DMA_64BIT) {
3640                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3641                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3642                 if (enable)
3643                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3644                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3645         } else {
3646                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3647                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3648                 if (enable)
3649                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3650                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3651         }
3652 }
3653
3654 static uint64_t
3655 bwn_dma_mask(struct bwn_mac *mac)
3656 {
3657         uint32_t tmp;
3658         uint16_t base;
3659
3660         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3661         if (tmp & SIBA_TGSHIGH_DMA64)
3662                 return (BWN_DMA_BIT_MASK(64));
3663         base = bwn_dma_base(0, 0);
3664         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3665         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3666         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3667                 return (BWN_DMA_BIT_MASK(32));
3668
3669         return (BWN_DMA_BIT_MASK(30));
3670 }
3671
3672 static int
3673 bwn_dma_mask2type(uint64_t dmamask)
3674 {
3675
3676         if (dmamask == BWN_DMA_BIT_MASK(30))
3677                 return (BWN_DMA_30BIT);
3678         if (dmamask == BWN_DMA_BIT_MASK(32))
3679                 return (BWN_DMA_32BIT);
3680         if (dmamask == BWN_DMA_BIT_MASK(64))
3681                 return (BWN_DMA_64BIT);
3682         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3683         return (BWN_DMA_30BIT);
3684 }
3685
3686 static void
3687 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3688 {
3689         struct bwn_pio_txpkt *tp;
3690         unsigned int i;
3691
3692         for (i = 0; i < N(tq->tq_pkts); i++) {
3693                 tp = &(tq->tq_pkts[i]);
3694                 if (tp->tp_m) {
3695                         m_freem(tp->tp_m);
3696                         tp->tp_m = NULL;
3697                 }
3698         }
3699 }
3700
3701 static uint16_t
3702 bwn_dma_base(int type, int controller_idx)
3703 {
3704         static const uint16_t map64[] = {
3705                 BWN_DMA64_BASE0,
3706                 BWN_DMA64_BASE1,
3707                 BWN_DMA64_BASE2,
3708                 BWN_DMA64_BASE3,
3709                 BWN_DMA64_BASE4,
3710                 BWN_DMA64_BASE5,
3711         };
3712         static const uint16_t map32[] = {
3713                 BWN_DMA32_BASE0,
3714                 BWN_DMA32_BASE1,
3715                 BWN_DMA32_BASE2,
3716                 BWN_DMA32_BASE3,
3717                 BWN_DMA32_BASE4,
3718                 BWN_DMA32_BASE5,
3719         };
3720
3721         if (type == BWN_DMA_64BIT) {
3722                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3723                     ("%s:%d: fail", __func__, __LINE__));
3724                 return (map64[controller_idx]);
3725         }
3726         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3727             ("%s:%d: fail", __func__, __LINE__));
3728         return (map32[controller_idx]);
3729 }
3730
3731 static void
3732 bwn_dma_init(struct bwn_mac *mac)
3733 {
3734         struct bwn_dma *dma = &mac->mac_method.dma;
3735
3736         /* setup TX DMA channels. */
3737         bwn_dma_setup(dma->wme[WME_AC_BK]);
3738         bwn_dma_setup(dma->wme[WME_AC_BE]);
3739         bwn_dma_setup(dma->wme[WME_AC_VI]);
3740         bwn_dma_setup(dma->wme[WME_AC_VO]);
3741         bwn_dma_setup(dma->mcast);
3742         /* setup RX DMA channel. */
3743         bwn_dma_setup(dma->rx);
3744 }
3745
3746 static struct bwn_dma_ring *
3747 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3748     int for_tx, int type)
3749 {
3750         struct bwn_dma *dma = &mac->mac_method.dma;
3751         struct bwn_dma_ring *dr;
3752         struct bwn_dmadesc_generic *desc;
3753         struct bwn_dmadesc_meta *mt;
3754         struct bwn_softc *sc = mac->mac_sc;
3755         int error, i;
3756
3757         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3758         if (dr == NULL)
3759                 goto out;
3760         dr->dr_numslots = BWN_RXRING_SLOTS;
3761         if (for_tx)
3762                 dr->dr_numslots = BWN_TXRING_SLOTS;
3763
3764         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3765             M_DEVBUF, M_NOWAIT | M_ZERO);
3766         if (dr->dr_meta == NULL)
3767                 goto fail0;
3768
3769         dr->dr_type = type;
3770         dr->dr_mac = mac;
3771         dr->dr_base = bwn_dma_base(type, controller_index);
3772         dr->dr_index = controller_index;
3773         if (type == BWN_DMA_64BIT) {
3774                 dr->getdesc = bwn_dma_64_getdesc;
3775                 dr->setdesc = bwn_dma_64_setdesc;
3776                 dr->start_transfer = bwn_dma_64_start_transfer;
3777                 dr->suspend = bwn_dma_64_suspend;
3778                 dr->resume = bwn_dma_64_resume;
3779                 dr->get_curslot = bwn_dma_64_get_curslot;
3780                 dr->set_curslot = bwn_dma_64_set_curslot;
3781         } else {
3782                 dr->getdesc = bwn_dma_32_getdesc;
3783                 dr->setdesc = bwn_dma_32_setdesc;
3784                 dr->start_transfer = bwn_dma_32_start_transfer;
3785                 dr->suspend = bwn_dma_32_suspend;
3786                 dr->resume = bwn_dma_32_resume;
3787                 dr->get_curslot = bwn_dma_32_get_curslot;
3788                 dr->set_curslot = bwn_dma_32_set_curslot;
3789         }
3790         if (for_tx) {
3791                 dr->dr_tx = 1;
3792                 dr->dr_curslot = -1;
3793         } else {
3794                 if (dr->dr_index == 0) {
3795                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3796                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3797                 } else
3798                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3799         }
3800
3801         error = bwn_dma_allocringmemory(dr);
3802         if (error)
3803                 goto fail2;
3804
3805         if (for_tx) {
3806                 /*
3807                  * Assumption: BWN_TXRING_SLOTS can be divided by
3808                  * BWN_TX_SLOTS_PER_FRAME
3809                  */
3810                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3811                     ("%s:%d: fail", __func__, __LINE__));
3812
3813                 dr->dr_txhdr_cache =
3814                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3815                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3816                 KASSERT(dr->dr_txhdr_cache != NULL,
3817                     ("%s:%d: fail", __func__, __LINE__));
3818
3819                 /*
3820                  * Create TX ring DMA stuffs
3821                  */
3822                 error = bus_dma_tag_create(dma->parent_dtag,
3823                                     BWN_ALIGN, 0,
3824                                     BUS_SPACE_MAXADDR,
3825                                     BUS_SPACE_MAXADDR,
3826                                     NULL, NULL,
3827                                     BWN_HDRSIZE(mac),
3828                                     1,
3829                                     BUS_SPACE_MAXSIZE_32BIT,
3830                                     0,
3831                                     NULL, NULL,
3832                                     &dr->dr_txring_dtag);
3833                 if (error) {
3834                         device_printf(sc->sc_dev,
3835                             "can't create TX ring DMA tag: TODO frees\n");
3836                         goto fail1;
3837                 }
3838
3839                 for (i = 0; i < dr->dr_numslots; i += 2) {
3840                         dr->getdesc(dr, i, &desc, &mt);
3841
3842                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3843                         mt->mt_m = NULL;
3844                         mt->mt_ni = NULL;
3845                         mt->mt_islast = 0;
3846                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3847                             &mt->mt_dmap);
3848                         if (error) {
3849                                 device_printf(sc->sc_dev,
3850                                      "can't create RX buf DMA map\n");
3851                                 goto fail1;
3852                         }
3853
3854                         dr->getdesc(dr, i + 1, &desc, &mt);
3855
3856                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3857                         mt->mt_m = NULL;
3858                         mt->mt_ni = NULL;
3859                         mt->mt_islast = 1;
3860                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3861                             &mt->mt_dmap);
3862                         if (error) {
3863                                 device_printf(sc->sc_dev,
3864                                      "can't create RX buf DMA map\n");
3865                                 goto fail1;
3866                         }
3867                 }
3868         } else {
3869                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3870                     &dr->dr_spare_dmap);
3871                 if (error) {
3872                         device_printf(sc->sc_dev,
3873                             "can't create RX buf DMA map\n");
3874                         goto out;               /* XXX wrong! */
3875                 }
3876
3877                 for (i = 0; i < dr->dr_numslots; i++) {
3878                         dr->getdesc(dr, i, &desc, &mt);
3879
3880                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3881                             &mt->mt_dmap);
3882                         if (error) {
3883                                 device_printf(sc->sc_dev,
3884                                     "can't create RX buf DMA map\n");
3885                                 goto out;       /* XXX wrong! */
3886                         }
3887                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3888                         if (error) {
3889                                 device_printf(sc->sc_dev,
3890                                     "failed to allocate RX buf\n");
3891                                 goto out;       /* XXX wrong! */
3892                         }
3893                 }
3894
3895                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3896                     BUS_DMASYNC_PREWRITE);
3897
3898                 dr->dr_usedslot = dr->dr_numslots;
3899         }
3900
3901       out:
3902         return (dr);
3903
3904 fail2:
3905         free(dr->dr_txhdr_cache, M_DEVBUF);
3906 fail1:
3907         free(dr->dr_meta, M_DEVBUF);
3908 fail0:
3909         free(dr, M_DEVBUF);
3910         return (NULL);
3911 }
3912
3913 static void
3914 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3915 {
3916
3917         if (dr == NULL)
3918                 return;
3919
3920         bwn_dma_free_descbufs(*dr);
3921         bwn_dma_free_ringmemory(*dr);
3922
3923         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3924         free((*dr)->dr_meta, M_DEVBUF);
3925         free(*dr, M_DEVBUF);
3926
3927         *dr = NULL;
3928 }
3929
3930 static void
3931 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3932     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3933 {
3934         struct bwn_dmadesc32 *desc;
3935
3936         *meta = &(dr->dr_meta[slot]);
3937         desc = dr->dr_ring_descbase;
3938         desc = &(desc[slot]);
3939
3940         *gdesc = (struct bwn_dmadesc_generic *)desc;
3941 }
3942
3943 static void
3944 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3945     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3946     int start, int end, int irq)
3947 {
3948         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3949         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3950         uint32_t addr, addrext, ctl;
3951         int slot;
3952
3953         slot = (int)(&(desc->dma.dma32) - descbase);
3954         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3955             ("%s:%d: fail", __func__, __LINE__));
3956
3957         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3958         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3959         addr |= siba_dma_translation(sc->sc_dev);
3960         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3961         if (slot == dr->dr_numslots - 1)
3962                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3963         if (start)
3964                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3965         if (end)
3966                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3967         if (irq)
3968                 ctl |= BWN_DMA32_DCTL_IRQ;
3969         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3970             & BWN_DMA32_DCTL_ADDREXT_MASK;
3971
3972         desc->dma.dma32.control = htole32(ctl);
3973         desc->dma.dma32.address = htole32(addr);
3974 }
3975
3976 static void
3977 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3978 {
3979
3980         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3981             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3982 }
3983
3984 static void
3985 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3986 {
3987
3988         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3989             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3990 }
3991
3992 static void
3993 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3994 {
3995
3996         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3997             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3998 }
3999
4000 static int
4001 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4002 {
4003         uint32_t val;
4004
4005         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4006         val &= BWN_DMA32_RXDPTR;
4007
4008         return (val / sizeof(struct bwn_dmadesc32));
4009 }
4010
4011 static void
4012 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4013 {
4014
4015         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4016             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4017 }
4018
4019 static void
4020 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4021     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4022 {
4023         struct bwn_dmadesc64 *desc;
4024
4025         *meta = &(dr->dr_meta[slot]);
4026         desc = dr->dr_ring_descbase;
4027         desc = &(desc[slot]);
4028
4029         *gdesc = (struct bwn_dmadesc_generic *)desc;
4030 }
4031
4032 static void
4033 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4034     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4035     int start, int end, int irq)
4036 {
4037         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4038         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4039         int slot;
4040         uint32_t ctl0 = 0, ctl1 = 0;
4041         uint32_t addrlo, addrhi;
4042         uint32_t addrext;
4043
4044         slot = (int)(&(desc->dma.dma64) - descbase);
4045         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4046             ("%s:%d: fail", __func__, __LINE__));
4047
4048         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4049         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4050         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4051             30;
4052         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4053         if (slot == dr->dr_numslots - 1)
4054                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4055         if (start)
4056                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4057         if (end)
4058                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4059         if (irq)
4060                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4061         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4062         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4063             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4064
4065         desc->dma.dma64.control0 = htole32(ctl0);
4066         desc->dma.dma64.control1 = htole32(ctl1);
4067         desc->dma.dma64.address_low = htole32(addrlo);
4068         desc->dma.dma64.address_high = htole32(addrhi);
4069 }
4070
4071 static void
4072 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4073 {
4074
4075         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4076             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4077 }
4078
4079 static void
4080 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4081 {
4082
4083         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4084             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4085 }
4086
4087 static void
4088 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4089 {
4090
4091         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4092             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4093 }
4094
4095 static int
4096 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4097 {
4098         uint32_t val;
4099
4100         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4101         val &= BWN_DMA64_RXSTATDPTR;
4102
4103         return (val / sizeof(struct bwn_dmadesc64));
4104 }
4105
4106 static void
4107 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4108 {
4109
4110         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4111             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4112 }
4113
4114 static int
4115 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4116 {
4117         struct bwn_mac *mac = dr->dr_mac;
4118         struct bwn_dma *dma = &mac->mac_method.dma;
4119         struct bwn_softc *sc = mac->mac_sc;
4120         int error;
4121
4122         error = bus_dma_tag_create(dma->parent_dtag,
4123                             BWN_ALIGN, 0,
4124                             BUS_SPACE_MAXADDR,
4125                             BUS_SPACE_MAXADDR,
4126                             NULL, NULL,
4127                             BWN_DMA_RINGMEMSIZE,
4128                             1,
4129                             BUS_SPACE_MAXSIZE_32BIT,
4130                             0,
4131                             NULL, NULL,
4132                             &dr->dr_ring_dtag);
4133         if (error) {
4134                 device_printf(sc->sc_dev,
4135                     "can't create TX ring DMA tag: TODO frees\n");
4136                 return (-1);
4137         }
4138
4139         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4140             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4141             &dr->dr_ring_dmap);
4142         if (error) {
4143                 device_printf(sc->sc_dev,
4144                     "can't allocate DMA mem: TODO frees\n");
4145                 return (-1);
4146         }
4147         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4148             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4149             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4150         if (error) {
4151                 device_printf(sc->sc_dev,
4152                     "can't load DMA mem: TODO free\n");
4153                 return (-1);
4154         }
4155
4156         return (0);
4157 }
4158
4159 static void
4160 bwn_dma_setup(struct bwn_dma_ring *dr)
4161 {
4162         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4163         uint64_t ring64;
4164         uint32_t addrext, ring32, value;
4165         uint32_t trans = siba_dma_translation(sc->sc_dev);
4166
4167         if (dr->dr_tx) {
4168                 dr->dr_curslot = -1;
4169
4170                 if (dr->dr_type == BWN_DMA_64BIT) {
4171                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4172                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4173                             >> 30;
4174                         value = BWN_DMA64_TXENABLE;
4175                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4176                             & BWN_DMA64_TXADDREXT_MASK;
4177                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4178                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4179                             (ring64 & 0xffffffff));
4180                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4181                             ((ring64 >> 32) &
4182                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4183                 } else {
4184                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4185                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4186                         value = BWN_DMA32_TXENABLE;
4187                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4188                             & BWN_DMA32_TXADDREXT_MASK;
4189                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4190                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4191                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4192                 }
4193                 return;
4194         }
4195
4196         /*
4197          * set for RX
4198          */
4199         dr->dr_usedslot = dr->dr_numslots;
4200
4201         if (dr->dr_type == BWN_DMA_64BIT) {
4202                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4203                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4204                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4205                 value |= BWN_DMA64_RXENABLE;
4206                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4207                     & BWN_DMA64_RXADDREXT_MASK;
4208                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4209                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4210                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4211                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4212                     | (trans << 1));
4213                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4214                     sizeof(struct bwn_dmadesc64));
4215         } else {
4216                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4217                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4218                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4219                 value |= BWN_DMA32_RXENABLE;
4220                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4221                     & BWN_DMA32_RXADDREXT_MASK;
4222                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4223                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4224                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4225                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4226                     sizeof(struct bwn_dmadesc32));
4227         }
4228 }
4229
4230 static void
4231 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4232 {
4233
4234         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4235         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4236             dr->dr_ring_dmap);
4237 }
4238
4239 static void
4240 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4241 {
4242
4243         if (dr->dr_tx) {
4244                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4245                 if (dr->dr_type == BWN_DMA_64BIT) {
4246                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4247                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4248                 } else
4249                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4250         } else {
4251                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4252                 if (dr->dr_type == BWN_DMA_64BIT) {
4253                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4254                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4255                 } else
4256                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4257         }
4258 }
4259
4260 static void
4261 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4262 {
4263         struct bwn_dmadesc_generic *desc;
4264         struct bwn_dmadesc_meta *meta;
4265         struct bwn_mac *mac = dr->dr_mac;
4266         struct bwn_dma *dma = &mac->mac_method.dma;
4267         struct bwn_softc *sc = mac->mac_sc;
4268         int i;
4269
4270         if (!dr->dr_usedslot)
4271                 return;
4272         for (i = 0; i < dr->dr_numslots; i++) {
4273                 dr->getdesc(dr, i, &desc, &meta);
4274
4275                 if (meta->mt_m == NULL) {
4276                         if (!dr->dr_tx)
4277                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4278                                     __func__);
4279                         continue;
4280                 }
4281                 if (dr->dr_tx) {
4282                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4283                                 bus_dmamap_unload(dr->dr_txring_dtag,
4284                                     meta->mt_dmap);
4285                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4286                                 bus_dmamap_unload(dma->txbuf_dtag,
4287                                     meta->mt_dmap);
4288                 } else
4289                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4290                 bwn_dma_free_descbuf(dr, meta);
4291         }
4292 }
4293
4294 static int
4295 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4296     int type)
4297 {
4298         struct bwn_softc *sc = mac->mac_sc;
4299         uint32_t value;
4300         int i;
4301         uint16_t offset;
4302
4303         for (i = 0; i < 10; i++) {
4304                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4305                     BWN_DMA32_TXSTATUS;
4306                 value = BWN_READ_4(mac, base + offset);
4307                 if (type == BWN_DMA_64BIT) {
4308                         value &= BWN_DMA64_TXSTAT;
4309                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4310                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4311                             value == BWN_DMA64_TXSTAT_STOPPED)
4312                                 break;
4313                 } else {
4314                         value &= BWN_DMA32_TXSTATE;
4315                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4316                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4317                             value == BWN_DMA32_TXSTAT_STOPPED)
4318                                 break;
4319                 }
4320                 DELAY(1000);
4321         }
4322         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4323         BWN_WRITE_4(mac, base + offset, 0);
4324         for (i = 0; i < 10; i++) {
4325                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4326                                                    BWN_DMA32_TXSTATUS;
4327                 value = BWN_READ_4(mac, base + offset);
4328                 if (type == BWN_DMA_64BIT) {
4329                         value &= BWN_DMA64_TXSTAT;
4330                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4331                                 i = -1;
4332                                 break;
4333                         }
4334                 } else {
4335                         value &= BWN_DMA32_TXSTATE;
4336                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4337                                 i = -1;
4338                                 break;
4339                         }
4340                 }
4341                 DELAY(1000);
4342         }
4343         if (i != -1) {
4344                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4345                 return (ENODEV);
4346         }
4347         DELAY(1000);
4348
4349         return (0);
4350 }
4351
4352 static int
4353 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4354     int type)
4355 {
4356         struct bwn_softc *sc = mac->mac_sc;
4357         uint32_t value;
4358         int i;
4359         uint16_t offset;
4360
4361         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4362         BWN_WRITE_4(mac, base + offset, 0);
4363         for (i = 0; i < 10; i++) {
4364                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4365                     BWN_DMA32_RXSTATUS;
4366                 value = BWN_READ_4(mac, base + offset);
4367                 if (type == BWN_DMA_64BIT) {
4368                         value &= BWN_DMA64_RXSTAT;
4369                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4370                                 i = -1;
4371                                 break;
4372                         }
4373                 } else {
4374                         value &= BWN_DMA32_RXSTATE;
4375                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4376                                 i = -1;
4377                                 break;
4378                         }
4379                 }
4380                 DELAY(1000);
4381         }
4382         if (i != -1) {
4383                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4384                 return (ENODEV);
4385         }
4386
4387         return (0);
4388 }
4389
4390 static void
4391 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4392     struct bwn_dmadesc_meta *meta)
4393 {
4394
4395         if (meta->mt_m != NULL) {
4396                 m_freem(meta->mt_m);
4397                 meta->mt_m = NULL;
4398         }
4399         if (meta->mt_ni != NULL) {
4400                 ieee80211_free_node(meta->mt_ni);
4401                 meta->mt_ni = NULL;
4402         }
4403 }
4404
4405 static void
4406 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4407 {
4408         struct bwn_rxhdr4 *rxhdr;
4409         unsigned char *frame;
4410
4411         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4412         rxhdr->frame_len = 0;
4413
4414         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4415             sizeof(struct bwn_plcp6) + 2,
4416             ("%s:%d: fail", __func__, __LINE__));
4417         frame = mtod(m, char *) + dr->dr_frameoffset;
4418         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4419 }
4420
4421 static uint8_t
4422 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4423 {
4424         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4425
4426         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4427             == 0xff);
4428 }
4429
4430 static void
4431 bwn_wme_init(struct bwn_mac *mac)
4432 {
4433
4434         bwn_wme_load(mac);
4435
4436         /* enable WME support. */
4437         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4438         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4439             BWN_IFSCTL_USE_EDCF);
4440 }
4441
4442 static void
4443 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4444 {
4445         struct bwn_softc *sc = mac->mac_sc;
4446         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4447         uint16_t delay; /* microsec */
4448
4449         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4450         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4451                 delay = 500;
4452         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4453                 delay = max(delay, (uint16_t)2400);
4454
4455         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4456 }
4457
4458 static void
4459 bwn_bt_enable(struct bwn_mac *mac)
4460 {
4461         struct bwn_softc *sc = mac->mac_sc;
4462         uint64_t hf;
4463
4464         if (bwn_bluetooth == 0)
4465                 return;
4466         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4467                 return;
4468         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4469                 return;
4470
4471         hf = bwn_hf_read(mac);
4472         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4473                 hf |= BWN_HF_BT_COEXISTALT;
4474         else
4475                 hf |= BWN_HF_BT_COEXIST;
4476         bwn_hf_write(mac, hf);
4477 }
4478
4479 static void
4480 bwn_set_macaddr(struct bwn_mac *mac)
4481 {
4482
4483         bwn_mac_write_bssid(mac);
4484         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4485 }
4486
4487 static void
4488 bwn_clear_keys(struct bwn_mac *mac)
4489 {
4490         int i;
4491
4492         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4493                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4494                     ("%s:%d: fail", __func__, __LINE__));
4495
4496                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4497                     NULL, BWN_SEC_KEYSIZE, NULL);
4498                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4499                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4500                             NULL, BWN_SEC_KEYSIZE, NULL);
4501                 }
4502                 mac->mac_key[i].keyconf = NULL;
4503         }
4504 }
4505
4506 static void
4507 bwn_crypt_init(struct bwn_mac *mac)
4508 {
4509         struct bwn_softc *sc = mac->mac_sc;
4510
4511         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4512         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4513             ("%s:%d: fail", __func__, __LINE__));
4514         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4515         mac->mac_ktp *= 2;
4516         if (siba_get_revid(sc->sc_dev) >= 5)
4517                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4518         bwn_clear_keys(mac);
4519 }
4520
4521 static void
4522 bwn_chip_exit(struct bwn_mac *mac)
4523 {
4524         struct bwn_softc *sc = mac->mac_sc;
4525
4526         bwn_phy_exit(mac);
4527         siba_gpio_set(sc->sc_dev, 0);
4528 }
4529
4530 static int
4531 bwn_fw_fillinfo(struct bwn_mac *mac)
4532 {
4533         int error;
4534
4535         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4536         if (error == 0)
4537                 return (0);
4538         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4539         if (error == 0)
4540                 return (0);
4541         return (error);
4542 }
4543
4544 static int
4545 bwn_gpio_init(struct bwn_mac *mac)
4546 {
4547         struct bwn_softc *sc = mac->mac_sc;
4548         uint32_t mask = 0x1f, set = 0xf, value;
4549
4550         BWN_WRITE_4(mac, BWN_MACCTL,
4551             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4552         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4553             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4554
4555         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4556                 mask |= 0x0060;
4557                 set |= 0x0060;
4558         }
4559         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4560                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4561                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4562                 mask |= 0x0200;
4563                 set |= 0x0200;
4564         }
4565         if (siba_get_revid(sc->sc_dev) >= 2)
4566                 mask |= 0x0010;
4567
4568         value = siba_gpio_get(sc->sc_dev);
4569         if (value == -1)
4570                 return (0);
4571         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4572
4573         return (0);
4574 }
4575
4576 static int
4577 bwn_fw_loadinitvals(struct bwn_mac *mac)
4578 {
4579 #define GETFWOFFSET(fwp, offset)                                \
4580         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4581         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4582         const struct bwn_fwhdr *hdr;
4583         struct bwn_fw *fw = &mac->mac_fw;
4584         int error;
4585
4586         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4587         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4588             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4589         if (error)
4590                 return (error);
4591         if (fw->initvals_band.fw) {
4592                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4593                 error = bwn_fwinitvals_write(mac,
4594                     GETFWOFFSET(fw->initvals_band, hdr_len),
4595                     be32toh(hdr->size),
4596                     fw->initvals_band.fw->datasize - hdr_len);
4597         }
4598         return (error);
4599 #undef GETFWOFFSET
4600 }
4601
4602 static int
4603 bwn_phy_init(struct bwn_mac *mac)
4604 {
4605         struct bwn_softc *sc = mac->mac_sc;
4606         int error;
4607
4608         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4609         mac->mac_phy.rf_onoff(mac, 1);
4610         error = mac->mac_phy.init(mac);
4611         if (error) {
4612                 device_printf(sc->sc_dev, "PHY init failed\n");
4613                 goto fail0;
4614         }
4615         error = bwn_switch_channel(mac,
4616             mac->mac_phy.get_default_chan(mac));
4617         if (error) {
4618                 device_printf(sc->sc_dev,
4619                     "failed to switch default channel\n");
4620                 goto fail1;
4621         }
4622         return (0);
4623 fail1:
4624         if (mac->mac_phy.exit)
4625                 mac->mac_phy.exit(mac);
4626 fail0:
4627         mac->mac_phy.rf_onoff(mac, 0);
4628
4629         return (error);
4630 }
4631
4632 static void
4633 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4634 {
4635         uint16_t ant;
4636         uint16_t tmp;
4637
4638         ant = bwn_ant2phy(antenna);
4639
4640         /* For ACK/CTS */
4641         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4642         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4643         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4644         /* For Probe Resposes */
4645         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4646         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4647         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4648 }
4649
4650 static void
4651 bwn_set_opmode(struct bwn_mac *mac)
4652 {
4653         struct bwn_softc *sc = mac->mac_sc;
4654         struct ifnet *ifp = sc->sc_ifp;
4655         struct ieee80211com *ic = ifp->if_l2com;
4656         uint32_t ctl;
4657         uint16_t cfp_pretbtt;
4658
4659         ctl = BWN_READ_4(mac, BWN_MACCTL);
4660         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4661             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4662             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4663         ctl |= BWN_MACCTL_STA;
4664
4665         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4666             ic->ic_opmode == IEEE80211_M_MBSS)
4667                 ctl |= BWN_MACCTL_HOSTAP;
4668         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4669                 ctl &= ~BWN_MACCTL_STA;
4670         ctl |= sc->sc_filters;
4671
4672         if (siba_get_revid(sc->sc_dev) <= 4)
4673                 ctl |= BWN_MACCTL_PROMISC;
4674
4675         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4676
4677         cfp_pretbtt = 2;
4678         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4679                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4680                     siba_get_chiprev(sc->sc_dev) == 3)
4681                         cfp_pretbtt = 100;
4682                 else
4683                         cfp_pretbtt = 50;
4684         }
4685         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4686 }
4687
4688 static int
4689 bwn_dma_gettype(struct bwn_mac *mac)
4690 {
4691         uint32_t tmp;
4692         uint16_t base;
4693
4694         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4695         if (tmp & SIBA_TGSHIGH_DMA64)
4696                 return (BWN_DMA_64BIT);
4697         base = bwn_dma_base(0, 0);
4698         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4699         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4700         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4701                 return (BWN_DMA_32BIT);
4702
4703         return (BWN_DMA_30BIT);
4704 }
4705
4706 static void
4707 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4708 {
4709         if (!error) {
4710                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4711                 *((bus_addr_t *)arg) = seg->ds_addr;
4712         }
4713 }
4714
4715 static void
4716 bwn_phy_g_init_sub(struct bwn_mac *mac)
4717 {
4718         struct bwn_phy *phy = &mac->mac_phy;
4719         struct bwn_phy_g *pg = &phy->phy_g;
4720         struct bwn_softc *sc = mac->mac_sc;
4721         uint16_t i, tmp;
4722
4723         if (phy->rev == 1)
4724                 bwn_phy_init_b5(mac);
4725         else
4726                 bwn_phy_init_b6(mac);
4727
4728         if (phy->rev >= 2 || phy->gmode)
4729                 bwn_phy_init_a(mac);
4730
4731         if (phy->rev >= 2) {
4732                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4733                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4734         }
4735         if (phy->rev == 2) {
4736                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4737                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4738         }
4739         if (phy->rev > 5) {
4740                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4741                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4742         }
4743         if (phy->gmode || phy->rev >= 2) {
4744                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4745                 tmp &= BWN_PHYVER_VERSION;
4746                 if (tmp == 3 || tmp == 5) {
4747                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4748                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4749                 }
4750                 if (tmp == 5) {
4751                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4752                             0x1f00);
4753                 }
4754         }
4755         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4756                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4757         if (phy->rf_rev == 8) {
4758                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4759                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4760         }
4761         if (BWN_HAS_LOOPBACK(phy))
4762                 bwn_loopback_calcgain(mac);
4763
4764         if (phy->rf_rev != 8) {
4765                 if (pg->pg_initval == 0xffff)
4766                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4767                 else
4768                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4769         }
4770         bwn_lo_g_init(mac);
4771         if (BWN_HAS_TXMAG(phy)) {
4772                 BWN_RF_WRITE(mac, 0x52,
4773                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4774                     | pg->pg_loctl.tx_bias |
4775                     pg->pg_loctl.tx_magn);
4776         } else {
4777                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4778         }
4779         if (phy->rev >= 6) {
4780                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4781                     (pg->pg_loctl.tx_bias << 12));
4782         }
4783         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4784                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4785         else
4786                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4787         if (phy->rev < 2)
4788                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4789         else
4790                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4791         if (phy->gmode || phy->rev >= 2) {
4792                 bwn_lo_g_adjust(mac);
4793                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4794         }
4795
4796         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4797                 for (i = 0; i < 64; i++) {
4798                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4799                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4800                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4801                             -32), 31));
4802                 }
4803                 bwn_nrssi_threshold(mac);
4804         } else if (phy->gmode || phy->rev >= 2) {
4805                 if (pg->pg_nrssi[0] == -1000) {
4806                         KASSERT(pg->pg_nrssi[1] == -1000,
4807                             ("%s:%d: fail", __func__, __LINE__));
4808                         bwn_nrssi_slope_11g(mac);
4809                 } else
4810                         bwn_nrssi_threshold(mac);
4811         }
4812         if (phy->rf_rev == 8)
4813                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4814         bwn_phy_hwpctl_init(mac);
4815         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4816              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4817                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4818                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4819         }
4820 }
4821
4822 static uint8_t
4823 bwn_has_hwpctl(struct bwn_mac *mac)
4824 {
4825
4826         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4827                 return (0);
4828         return (mac->mac_phy.use_hwpctl(mac));
4829 }
4830
4831 static void
4832 bwn_phy_init_b5(struct bwn_mac *mac)
4833 {
4834         struct bwn_phy *phy = &mac->mac_phy;
4835         struct bwn_phy_g *pg = &phy->phy_g;
4836         struct bwn_softc *sc = mac->mac_sc;
4837         uint16_t offset, value;
4838         uint8_t old_channel;
4839
4840         if (phy->analog == 1)
4841                 BWN_RF_SET(mac, 0x007a, 0x0050);
4842         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4843             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4844                 value = 0x2120;
4845                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4846                         BWN_PHY_WRITE(mac, offset, value);
4847                         value += 0x202;
4848                 }
4849         }
4850         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4851         if (phy->rf_ver == 0x2050)
4852                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4853
4854         if (phy->gmode || phy->rev >= 2) {
4855                 if (phy->rf_ver == 0x2050) {
4856                         BWN_RF_SET(mac, 0x007a, 0x0020);
4857                         BWN_RF_SET(mac, 0x0051, 0x0004);
4858                 }
4859                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4860
4861                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4862                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4863
4864                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4865
4866                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4867                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4868                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4869         }
4870
4871         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4872                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4873
4874         if (phy->analog == 1) {
4875                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4876                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4877                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4878                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4879                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4880         } else
4881                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4882         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4883         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4884
4885         if (phy->analog == 1)
4886                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4887         else
4888                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4889
4890         if (phy->analog == 0)
4891                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4892
4893         old_channel = phy->chan;
4894         bwn_phy_g_switch_chan(mac, 7, 0);
4895
4896         if (phy->rf_ver != 0x2050) {
4897                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4898                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4899         }
4900
4901         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4902         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4903
4904         if (phy->rf_ver == 0x2050) {
4905                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4906                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4907         }
4908
4909         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4910         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4911         BWN_RF_SET(mac, 0x007a, 0x0007);
4912
4913         bwn_phy_g_switch_chan(mac, old_channel, 0);
4914         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4915         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4916         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4917
4918         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4919             pg->pg_txctl);
4920
4921         if (phy->rf_ver == 0x2050)
4922                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4923
4924         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4925 }
4926
4927 static void
4928 bwn_loopback_calcgain(struct bwn_mac *mac)
4929 {
4930         struct bwn_phy *phy = &mac->mac_phy;
4931         struct bwn_phy_g *pg = &phy->phy_g;
4932         struct bwn_softc *sc = mac->mac_sc;
4933         uint16_t backup_phy[16] = { 0 };
4934         uint16_t backup_radio[3];
4935         uint16_t backup_bband;
4936         uint16_t i, j, loop_i_max;
4937         uint16_t trsw_rx;
4938         uint16_t loop1_outer_done, loop1_inner_done;
4939
4940         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4941         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4942         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4943         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4944         if (phy->rev != 1) {
4945                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4946                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4947         }
4948         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4949         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4950         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4951         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4952         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4953         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4954         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4955         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4956         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4957         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4958         backup_bband = pg->pg_bbatt.att;
4959         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4960         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4961         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4962
4963         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4964         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4965         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4966         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4967         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4968         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4969         if (phy->rev != 1) {
4970                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4971                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4972                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4973                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4974         }
4975         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4976         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4977         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4978         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4979
4980         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4981         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4982         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4983
4984         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4985         if (phy->rev != 1) {
4986                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4987                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4988         }
4989         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4990
4991         if (phy->rf_rev == 8)
4992                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4993         else {
4994                 BWN_RF_WRITE(mac, 0x52, 0);
4995                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4996         }
4997         bwn_phy_g_set_bbatt(mac, 11);
4998
4999         if (phy->rev >= 3)
5000                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5001         else
5002                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5003         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5004
5005         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5006         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5007
5008         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5009         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5010
5011         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5012                 if (phy->rev >= 7) {
5013                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5014                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5015                 }
5016         }
5017         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5018
5019         j = 0;
5020         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5021         for (i = 0; i < loop_i_max; i++) {
5022                 for (j = 0; j < 16; j++) {
5023                         BWN_RF_WRITE(mac, 0x43, i);
5024                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5025                             (j << 8));
5026                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5027                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5028                         DELAY(20);
5029                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5030                                 goto done0;
5031                 }
5032         }
5033 done0:
5034         loop1_outer_done = i;
5035         loop1_inner_done = j;
5036         if (j >= 8) {
5037                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5038                 trsw_rx = 0x1b;
5039                 for (j = j - 8; j < 16; j++) {
5040                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5041                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5042                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5043                         DELAY(20);
5044                         trsw_rx -= 3;
5045                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5046                                 goto done1;
5047                 }
5048         } else
5049                 trsw_rx = 0x18;
5050 done1:
5051
5052         if (phy->rev != 1) {
5053                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5054                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5055         }
5056         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5057         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5058         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5059         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5060         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5061         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5062         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5063         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5064         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5065
5066         bwn_phy_g_set_bbatt(mac, backup_bband);
5067
5068         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5069         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5070         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5071
5072         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5073         DELAY(10);
5074         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5075         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5076         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5077         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5078
5079         pg->pg_max_lb_gain =
5080             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5081         pg->pg_trsw_rx_gain = trsw_rx * 2;
5082 }
5083
5084 static uint16_t
5085 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5086 {
5087         struct bwn_phy *phy = &mac->mac_phy;
5088         uint32_t tmp1 = 0, tmp2 = 0;
5089         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5090             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5091             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5092         static const uint8_t rcc_table[] = {
5093                 0x02, 0x03, 0x01, 0x0f,
5094                 0x06, 0x07, 0x05, 0x0f,
5095                 0x0a, 0x0b, 0x09, 0x0f,
5096                 0x0e, 0x0f, 0x0d, 0x0f,
5097         };
5098
5099         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5100             rfoverval = rfover = cck3 = 0;
5101         radio0 = BWN_RF_READ(mac, 0x43);
5102         radio1 = BWN_RF_READ(mac, 0x51);
5103         radio2 = BWN_RF_READ(mac, 0x52);
5104         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5105         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5106         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5107         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5108
5109         if (phy->type == BWN_PHYTYPE_B) {
5110                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5111                 reg0 = BWN_READ_2(mac, 0x3ec);
5112
5113                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5114                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5115         } else if (phy->gmode || phy->rev >= 2) {
5116                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5117                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5118                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5119                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5120                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5121                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5122
5123                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5124                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5125                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5126                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5127                 if (BWN_HAS_LOOPBACK(phy)) {
5128                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5129                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5130                         if (phy->rev >= 3)
5131                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5132                         else
5133                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5134                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5135                 }
5136
5137                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5138                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5139                         BWN_LPD(0, 1, 1)));
5140                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5141                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5142         }
5143         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5144
5145         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5146         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5147         reg1 = BWN_READ_2(mac, 0x3e6);
5148         reg2 = BWN_READ_2(mac, 0x3f4);
5149
5150         if (phy->analog == 0)
5151                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5152         else {
5153                 if (phy->analog >= 2)
5154                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5155                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5156                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5157         }
5158
5159         reg = BWN_RF_READ(mac, 0x60);
5160         index = (reg & 0x001e) >> 1;
5161         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5162
5163         if (phy->type == BWN_PHYTYPE_B)
5164                 BWN_RF_WRITE(mac, 0x78, 0x26);
5165         if (phy->gmode || phy->rev >= 2) {
5166                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5167                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5168                         BWN_LPD(0, 1, 1)));
5169         }
5170         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5171         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5172         if (phy->gmode || phy->rev >= 2) {
5173                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5174                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5175                         BWN_LPD(0, 0, 1)));
5176         }
5177         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5178         BWN_RF_SET(mac, 0x51, 0x0004);
5179         if (phy->rf_rev == 8)
5180                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5181         else {
5182                 BWN_RF_WRITE(mac, 0x52, 0);
5183                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5184         }
5185         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5186
5187         for (i = 0; i < 16; i++) {
5188                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5189                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5190                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5191                 if (phy->gmode || phy->rev >= 2) {
5192                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5193                             bwn_rf_2050_rfoverval(mac,
5194                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5195                 }
5196                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5197                 DELAY(10);
5198                 if (phy->gmode || phy->rev >= 2) {
5199                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5200                             bwn_rf_2050_rfoverval(mac,
5201                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5202                 }
5203                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5204                 DELAY(10);
5205                 if (phy->gmode || phy->rev >= 2) {
5206                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5207                             bwn_rf_2050_rfoverval(mac,
5208                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5209                 }
5210                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5211                 DELAY(20);
5212                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5213                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5214                 if (phy->gmode || phy->rev >= 2) {
5215                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5216                             bwn_rf_2050_rfoverval(mac,
5217                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5218                 }
5219                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5220         }
5221         DELAY(10);
5222
5223         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5224         tmp1++;
5225         tmp1 >>= 9;
5226
5227         for (i = 0; i < 16; i++) {
5228                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5229                 BWN_RF_WRITE(mac, 0x78, radio78);
5230                 DELAY(10);
5231                 for (j = 0; j < 16; j++) {
5232                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5233                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5234                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5235                         if (phy->gmode || phy->rev >= 2) {
5236                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5237                                     bwn_rf_2050_rfoverval(mac,
5238                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5239                         }
5240                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5241                         DELAY(10);
5242                         if (phy->gmode || phy->rev >= 2) {
5243                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5244                                     bwn_rf_2050_rfoverval(mac,
5245                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5246                         }
5247                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5248                         DELAY(10);
5249                         if (phy->gmode || phy->rev >= 2) {
5250                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5251                                     bwn_rf_2050_rfoverval(mac,
5252                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5253                         }
5254                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5255                         DELAY(10);
5256                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5257                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5258                         if (phy->gmode || phy->rev >= 2) {
5259                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5260                                     bwn_rf_2050_rfoverval(mac,
5261                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5262                         }
5263                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5264                 }
5265                 tmp2++;
5266                 tmp2 >>= 8;
5267                 if (tmp1 < tmp2)
5268                         break;
5269         }
5270
5271         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5272         BWN_RF_WRITE(mac, 0x51, radio1);
5273         BWN_RF_WRITE(mac, 0x52, radio2);
5274         BWN_RF_WRITE(mac, 0x43, radio0);
5275         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5276         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5277         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5278         BWN_WRITE_2(mac, 0x3e6, reg1);
5279         if (phy->analog != 0)
5280                 BWN_WRITE_2(mac, 0x3f4, reg2);
5281         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5282         bwn_spu_workaround(mac, phy->chan);
5283         if (phy->type == BWN_PHYTYPE_B) {
5284                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5285                 BWN_WRITE_2(mac, 0x3ec, reg0);
5286         } else if (phy->gmode) {
5287                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5288                             BWN_READ_2(mac, BWN_PHY_RADIO)
5289                             & 0x7fff);
5290                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5291                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5292                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5293                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5294                               analogoverval);
5295                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5296                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5297                 if (BWN_HAS_LOOPBACK(phy)) {
5298                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5299                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5300                 }
5301         }
5302
5303         return ((i > 15) ? radio78 : rcc);
5304 }
5305
5306 static void
5307 bwn_phy_init_b6(struct bwn_mac *mac)
5308 {
5309         struct bwn_phy *phy = &mac->mac_phy;
5310         struct bwn_phy_g *pg = &phy->phy_g;
5311         struct bwn_softc *sc = mac->mac_sc;
5312         uint16_t offset, val;
5313         uint8_t old_channel;
5314
5315         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5316             ("%s:%d: fail", __func__, __LINE__));
5317
5318         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5319         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5320         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5321                 BWN_RF_WRITE(mac, 0x51, 0x37);
5322                 BWN_RF_WRITE(mac, 0x52, 0x70);
5323                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5324                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5325                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5326                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5327                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5328                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5329                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5330                 bwn_hf_write(mac,
5331                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5332         }
5333         if (phy->rf_rev == 8) {
5334                 BWN_RF_WRITE(mac, 0x51, 0);
5335                 BWN_RF_WRITE(mac, 0x52, 0x40);
5336                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5337                 BWN_RF_WRITE(mac, 0x54, 0x98);
5338                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5339                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5340                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5341                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5342                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5343                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5344                 } else {
5345                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5346                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5347                 }
5348                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5349                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5350                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5351                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5352         }
5353         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5354                 BWN_PHY_WRITE(mac, offset, val);
5355                 val -= 0x0202;
5356         }
5357         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5358                 BWN_PHY_WRITE(mac, offset, val);
5359                 val -= 0x0202;
5360         }
5361         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5362                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5363                 val += 0x0202;
5364         }
5365         if (phy->type == BWN_PHYTYPE_G) {
5366                 BWN_RF_SET(mac, 0x007a, 0x0020);
5367                 BWN_RF_SET(mac, 0x0051, 0x0004);
5368                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5369                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5370                 BWN_PHY_WRITE(mac, 0x5b, 0);
5371                 BWN_PHY_WRITE(mac, 0x5c, 0);
5372         }
5373
5374         old_channel = phy->chan;
5375         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5376
5377         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5378         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5379         DELAY(40);
5380         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5381                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5382                 BWN_RF_WRITE(mac, 0x50, 0x20);
5383         }
5384         if (phy->rf_rev <= 2) {
5385                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5386                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5387                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5388                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5389         }
5390         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5391
5392         bwn_phy_g_switch_chan(mac, old_channel, 0);
5393
5394         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5395         if (phy->rf_rev >= 6)
5396                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5397         else
5398                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5399         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5400         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5401             pg->pg_txctl);
5402         if (phy->rf_rev <= 5)
5403                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5404         if (phy->rf_rev <= 2)
5405                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5406
5407         if (phy->analog == 4) {
5408                 BWN_WRITE_2(mac, 0x3e4, 9);
5409                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5410         } else
5411                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5412         if (phy->type == BWN_PHYTYPE_B)
5413                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5414         else if (phy->type == BWN_PHYTYPE_G)
5415                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5416 }
5417
5418 static void
5419 bwn_phy_init_a(struct bwn_mac *mac)
5420 {
5421         struct bwn_phy *phy = &mac->mac_phy;
5422         struct bwn_softc *sc = mac->mac_sc;
5423
5424         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5425             ("%s:%d: fail", __func__, __LINE__));
5426
5427         if (phy->rev >= 6) {
5428                 if (phy->type == BWN_PHYTYPE_A)
5429                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5430                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5431                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5432                 else
5433                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5434         }
5435
5436         bwn_wa_init(mac);
5437
5438         if (phy->type == BWN_PHYTYPE_G &&
5439             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5440                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5441 }
5442
5443 static void
5444 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5445 {
5446         int i;
5447
5448         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5449                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5450 }
5451
5452 static void
5453 bwn_wa_agc(struct bwn_mac *mac)
5454 {
5455         struct bwn_phy *phy = &mac->mac_phy;
5456
5457         if (phy->rev == 1) {
5458                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5460                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5461                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5462                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5463                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5464                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5465                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5466                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5467         } else {
5468                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5469                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5470                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5471                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5472         }
5473
5474         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5475             0x5700);
5476         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5477         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5478         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5479         BWN_RF_SET(mac, 0x7a, 0x0008);
5480         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5481         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5482         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5483         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5484         if (phy->rev == 1)
5485                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5486         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5487         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5488         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5491         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5492         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5493         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5494         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5495         if (phy->rev == 1) {
5496                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5497                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5498         } else {
5499                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5500                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5501                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5502                 if (phy->rev >= 6) {
5503                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5504                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5505                             (uint16_t)~0xf000, 0x3000);
5506                 }
5507         }
5508         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5509         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5510         if (phy->rev == 1) {
5511                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5512                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5513                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5514                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5515                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5516                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5517                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5518                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5519         } else {
5520                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5521                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5522                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5523                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5524         }
5525         if (phy->rev >= 6) {
5526                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5527                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5528         }
5529         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5530 }
5531
5532 static void
5533 bwn_wa_grev1(struct bwn_mac *mac)
5534 {
5535         struct bwn_phy *phy = &mac->mac_phy;
5536         int i;
5537         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5538         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5539         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5540
5541         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5542
5543         /* init CRSTHRES and ANTDWELL */
5544         if (phy->rev == 1) {
5545                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5546         } else if (phy->rev == 2) {
5547                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5548                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5549                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5550         } else {
5551                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5552                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5553                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5554                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5555         }
5556         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5557         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5558         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5559
5560         /* XXX support PHY-A??? */
5561         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5562                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5563                     bwn_tab_finefreqg[i]);
5564
5565         /* XXX support PHY-A??? */
5566         if (phy->rev == 1)
5567                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5568                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5569                             bwn_tab_noise_g1[i]);
5570         else
5571                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5572                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5573                             bwn_tab_noise_g2[i]);
5574
5575
5576         for (i = 0; i < N(bwn_tab_rotor); i++)
5577                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5578                     bwn_tab_rotor[i]);
5579
5580         /* XXX support PHY-A??? */
5581         if (phy->rev >= 6) {
5582                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5583                     BWN_PHY_ENCORE_EN)
5584                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5585                 else
5586                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5587         } else
5588                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5589
5590         for (i = 0; i < N(bwn_tab_retard); i++)
5591                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5592                     bwn_tab_retard[i]);
5593
5594         if (phy->rev == 1) {
5595                 for (i = 0; i < 16; i++)
5596                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5597                             i, 0x0020);
5598         } else {
5599                 for (i = 0; i < 32; i++)
5600                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5601         }
5602
5603         bwn_wa_agc(mac);
5604 }
5605
5606 static void
5607 bwn_wa_grev26789(struct bwn_mac *mac)
5608 {
5609         struct bwn_phy *phy = &mac->mac_phy;
5610         int i;
5611         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5612         uint16_t ofdmrev;
5613
5614         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5615
5616         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5617
5618         /* init CRSTHRES and ANTDWELL */
5619         if (phy->rev == 1)
5620                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5621         else if (phy->rev == 2) {
5622                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5623                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5624                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5625         } else {
5626                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5627                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5628                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5629                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5630         }
5631
5632         for (i = 0; i < 64; i++)
5633                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5634
5635         /* XXX support PHY-A??? */
5636         if (phy->rev == 1)
5637                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5638                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5639                             bwn_tab_noise_g1[i]);
5640         else
5641                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5642                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5643                             bwn_tab_noise_g2[i]);
5644
5645         /* XXX support PHY-A??? */
5646         if (phy->rev >= 6) {
5647                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5648                     BWN_PHY_ENCORE_EN)
5649                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5650                 else
5651                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5652         } else
5653                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5654
5655         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5656                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5657                     bwn_tab_sigmasqr2[i]);
5658
5659         if (phy->rev == 1) {
5660                 for (i = 0; i < 16; i++)
5661                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5662                             0x0020);
5663         } else {
5664                 for (i = 0; i < 32; i++)
5665                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5666         }
5667
5668         bwn_wa_agc(mac);
5669
5670         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5671         if (ofdmrev > 2) {
5672                 if (phy->type == BWN_PHYTYPE_A)
5673                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5674                 else
5675                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5676         } else {
5677                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5678                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5679                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5680         }
5681
5682         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5683         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5684 }
5685
5686 static void
5687 bwn_wa_init(struct bwn_mac *mac)
5688 {
5689         struct bwn_phy *phy = &mac->mac_phy;
5690         struct bwn_softc *sc = mac->mac_sc;
5691
5692         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5693
5694         switch (phy->rev) {
5695         case 1:
5696                 bwn_wa_grev1(mac);
5697                 break;
5698         case 2:
5699         case 6:
5700         case 7:
5701         case 8:
5702         case 9:
5703                 bwn_wa_grev26789(mac);
5704                 break;
5705         default:
5706                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5707         }
5708
5709         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5710             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5711             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5712                 if (phy->rev < 2) {
5713                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5714                             0x0002);
5715                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5716                             0x0001);
5717                 } else {
5718                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5719                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5720                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5721                              BWN_BFL_EXTLNA) &&
5722                             (phy->rev >= 7)) {
5723                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5724                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5725                                     0x0020, 0x0001);
5726                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5727                                     0x0021, 0x0001);
5728                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5729                                     0x0022, 0x0001);
5730                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5731                                     0x0023, 0x0000);
5732                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5733                                     0x0000, 0x0000);
5734                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5735                                     0x0003, 0x0002);
5736                         }
5737                 }
5738         }
5739         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5740                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5741                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5742         }
5743
5744         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5745         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5746 }
5747
5748 static void
5749 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5750     uint16_t value)
5751 {
5752         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5753         uint16_t addr;
5754
5755         addr = table + offset;
5756         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5757             (addr - 1 != pg->pg_ofdmtab_addr)) {
5758                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5759                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5760         }
5761         pg->pg_ofdmtab_addr = addr;
5762         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5763 }
5764
5765 static void
5766 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5767     uint32_t value)
5768 {
5769         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5770         uint16_t addr;
5771
5772         addr = table + offset;
5773         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5774             (addr - 1 != pg->pg_ofdmtab_addr)) {
5775                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5776                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5777         }
5778         pg->pg_ofdmtab_addr = addr;
5779
5780         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5781         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5782 }
5783
5784 static void
5785 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5786     uint16_t value)
5787 {
5788
5789         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5790         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5791 }
5792
5793 static void
5794 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5795 {
5796         struct bwn_phy *phy = &mac->mac_phy;
5797         struct bwn_softc *sc = mac->mac_sc;
5798         unsigned int i, max_loop;
5799         uint16_t value;
5800         uint32_t buffer[5] = {
5801                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5802         };
5803
5804         if (ofdm) {
5805                 max_loop = 0x1e;
5806                 buffer[0] = 0x000201cc;
5807         } else {
5808                 max_loop = 0xfa;
5809                 buffer[0] = 0x000b846e;
5810         }
5811
5812         BWN_ASSERT_LOCKED(mac->mac_sc);
5813
5814         for (i = 0; i < 5; i++)
5815                 bwn_ram_write(mac, i * 4, buffer[i]);
5816
5817         BWN_WRITE_2(mac, 0x0568, 0x0000);
5818         BWN_WRITE_2(mac, 0x07c0,
5819             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5820         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5821         BWN_WRITE_2(mac, 0x050c, value);
5822         if (phy->type == BWN_PHYTYPE_LP)
5823                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5824         BWN_WRITE_2(mac, 0x0508, 0x0000);
5825         BWN_WRITE_2(mac, 0x050a, 0x0000);
5826         BWN_WRITE_2(mac, 0x054c, 0x0000);
5827         BWN_WRITE_2(mac, 0x056a, 0x0014);
5828         BWN_WRITE_2(mac, 0x0568, 0x0826);
5829         BWN_WRITE_2(mac, 0x0500, 0x0000);
5830         if (phy->type == BWN_PHYTYPE_LP)
5831                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5832         else
5833                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5834
5835         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5836                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5837         for (i = 0x00; i < max_loop; i++) {
5838                 value = BWN_READ_2(mac, 0x050e);
5839                 if (value & 0x0080)
5840                         break;
5841                 DELAY(10);
5842         }
5843         for (i = 0x00; i < 0x0a; i++) {
5844                 value = BWN_READ_2(mac, 0x050e);
5845                 if (value & 0x0400)
5846                         break;
5847                 DELAY(10);
5848         }
5849         for (i = 0x00; i < 0x19; i++) {
5850                 value = BWN_READ_2(mac, 0x0690);
5851                 if (!(value & 0x0100))
5852                         break;
5853                 DELAY(10);
5854         }
5855         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5856                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5857 }
5858
5859 static void
5860 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5861 {
5862         uint32_t macctl;
5863
5864         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5865
5866         macctl = BWN_READ_4(mac, BWN_MACCTL);
5867         if (macctl & BWN_MACCTL_BIGENDIAN)
5868                 printf("TODO: need swap\n");
5869
5870         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5871         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5872         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5873 }
5874
5875 static void
5876 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5877 {
5878         uint16_t value;
5879
5880         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5881             ("%s:%d: fail", __func__, __LINE__));
5882
5883         value = (uint8_t) (ctl->q);
5884         value |= ((uint8_t) (ctl->i)) << 8;
5885         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5886 }
5887
5888 static uint16_t
5889 bwn_lo_calcfeed(struct bwn_mac *mac,
5890     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5891 {
5892         struct bwn_phy *phy = &mac->mac_phy;
5893         struct bwn_softc *sc = mac->mac_sc;
5894         uint16_t rfover;
5895         uint16_t feedthrough;
5896
5897         if (phy->gmode) {
5898                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5899                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5900
5901                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5902                     ("%s:%d: fail", __func__, __LINE__));
5903                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5904                     ("%s:%d: fail", __func__, __LINE__));
5905
5906                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5907
5908                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5909                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5910                     phy->rev > 6)
5911                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5912
5913                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5914                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5915                 DELAY(10);
5916                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5917                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5918                 DELAY(10);
5919                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5920                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5921                 DELAY(10);
5922                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5923         } else {
5924                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5925                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5926                 DELAY(10);
5927                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5928                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5929                 DELAY(10);
5930                 pga |= BWN_PHY_PGACTL_LPF;
5931                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5932         }
5933         DELAY(21);
5934         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5935
5936         return (feedthrough);
5937 }
5938
5939 static uint16_t
5940 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5941     uint16_t *value, uint16_t *pad_mix_gain)
5942 {
5943         struct bwn_phy *phy = &mac->mac_phy;
5944         uint16_t reg, v, padmix;
5945
5946         if (phy->type == BWN_PHYTYPE_B) {
5947                 v = 0x30;
5948                 if (phy->rf_rev <= 5) {
5949                         reg = 0x43;
5950                         padmix = 0;
5951                 } else {
5952                         reg = 0x52;
5953                         padmix = 5;
5954                 }
5955         } else {
5956                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5957                         reg = 0x43;
5958                         v = 0x10;
5959                         padmix = 2;
5960                 } else {
5961                         reg = 0x52;
5962                         v = 0x30;
5963                         padmix = 5;
5964                 }
5965         }
5966         if (value)
5967                 *value = v;
5968         if (pad_mix_gain)
5969                 *pad_mix_gain = padmix;
5970
5971         return (reg);
5972 }
5973
5974 static void
5975 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5976 {
5977         struct bwn_phy *phy = &mac->mac_phy;
5978         struct bwn_phy_g *pg = &phy->phy_g;
5979         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5980         uint16_t reg, mask;
5981         uint16_t trsw_rx, pga;
5982         uint16_t rf_pctl_reg;
5983
5984         static const uint8_t tx_bias_values[] = {
5985                 0x09, 0x08, 0x0a, 0x01, 0x00,
5986                 0x02, 0x05, 0x04, 0x06,
5987         };
5988         static const uint8_t tx_magn_values[] = {
5989                 0x70, 0x40,
5990         };
5991
5992         if (!BWN_HAS_LOOPBACK(phy)) {
5993                 rf_pctl_reg = 6;
5994                 trsw_rx = 2;
5995                 pga = 0;
5996         } else {
5997                 int lb_gain;
5998
5999                 trsw_rx = 0;
6000                 lb_gain = pg->pg_max_lb_gain / 2;
6001                 if (lb_gain > 10) {
6002                         rf_pctl_reg = 0;
6003                         pga = abs(10 - lb_gain) / 6;
6004                         pga = MIN(MAX(pga, 0), 15);
6005                 } else {
6006                         int cmp_val;
6007                         int tmp;
6008
6009                         pga = 0;
6010                         cmp_val = 0x24;
6011                         if ((phy->rev >= 2) &&
6012                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6013                                 cmp_val = 0x3c;
6014                         tmp = lb_gain;
6015                         if ((10 - lb_gain) < cmp_val)
6016                                 tmp = (10 - lb_gain);
6017                         if (tmp < 0)
6018                                 tmp += 6;
6019                         else
6020                                 tmp += 3;
6021                         cmp_val /= 4;
6022                         tmp /= 4;
6023                         if (tmp >= cmp_val)
6024                                 rf_pctl_reg = cmp_val;
6025                         else
6026                                 rf_pctl_reg = tmp;
6027                 }
6028         }
6029         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6030         bwn_phy_g_set_bbatt(mac, 2);
6031
6032         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6033         mask = ~mask;
6034         BWN_RF_MASK(mac, reg, mask);
6035
6036         if (BWN_HAS_TXMAG(phy)) {
6037                 int i, j;
6038                 int feedthrough;
6039                 int min_feedth = 0xffff;
6040                 uint8_t tx_magn, tx_bias;
6041
6042                 for (i = 0; i < N(tx_magn_values); i++) {
6043                         tx_magn = tx_magn_values[i];
6044                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6045                         for (j = 0; j < N(tx_bias_values); j++) {
6046                                 tx_bias = tx_bias_values[j];
6047                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6048                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6049                                     trsw_rx);
6050                                 if (feedthrough < min_feedth) {
6051                                         lo->tx_bias = tx_bias;
6052                                         lo->tx_magn = tx_magn;
6053                                         min_feedth = feedthrough;
6054                                 }
6055                                 if (lo->tx_bias == 0)
6056                                         break;
6057                         }
6058                         BWN_RF_WRITE(mac, 0x52,
6059                                           (BWN_RF_READ(mac, 0x52)
6060                                            & 0xff00) | lo->tx_bias | lo->
6061                                           tx_magn);
6062                 }
6063         } else {
6064                 lo->tx_magn = 0;
6065                 lo->tx_bias = 0;
6066                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6067         }
6068
6069         BWN_GETTIME(lo->txctl_measured_time);
6070 }
6071
6072 static void
6073 bwn_lo_get_powervector(struct bwn_mac *mac)
6074 {
6075         struct bwn_phy *phy = &mac->mac_phy;
6076         struct bwn_phy_g *pg = &phy->phy_g;
6077         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6078         int i;
6079         uint64_t tmp;
6080         uint64_t power_vector = 0;
6081
6082         for (i = 0; i < 8; i += 2) {
6083                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6084                 power_vector |= (tmp << (i * 8));
6085                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6086         }
6087         if (power_vector)
6088                 lo->power_vector = power_vector;
6089
6090         BWN_GETTIME(lo->pwr_vec_read_time);
6091 }
6092
6093 static void
6094 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6095     int use_trsw_rx)
6096 {
6097         struct bwn_phy *phy = &mac->mac_phy;
6098         struct bwn_phy_g *pg = &phy->phy_g;
6099         uint16_t tmp;
6100
6101         if (max_rx_gain < 0)
6102                 max_rx_gain = 0;
6103
6104         if (BWN_HAS_LOOPBACK(phy)) {
6105                 int trsw_rx = 0;
6106                 int trsw_rx_gain;
6107
6108                 if (use_trsw_rx) {
6109                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6110                         if (max_rx_gain >= trsw_rx_gain) {
6111                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6112                                 trsw_rx = 0x20;
6113                         }
6114                 } else
6115                         trsw_rx_gain = max_rx_gain;
6116                 if (trsw_rx_gain < 9) {
6117                         pg->pg_lna_lod_gain = 0;
6118                 } else {
6119                         pg->pg_lna_lod_gain = 1;
6120                         trsw_rx_gain -= 8;
6121                 }
6122                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6123                 pg->pg_pga_gain = trsw_rx_gain / 3;
6124                 if (pg->pg_pga_gain >= 5) {
6125                         pg->pg_pga_gain -= 5;
6126                         pg->pg_lna_gain = 2;
6127                 } else
6128                         pg->pg_lna_gain = 0;
6129         } else {
6130                 pg->pg_lna_gain = 0;
6131                 pg->pg_trsw_rx_gain = 0x20;
6132                 if (max_rx_gain >= 0x14) {
6133                         pg->pg_lna_lod_gain = 1;
6134                         pg->pg_pga_gain = 2;
6135                 } else if (max_rx_gain >= 0x12) {
6136                         pg->pg_lna_lod_gain = 1;
6137                         pg->pg_pga_gain = 1;
6138                 } else if (max_rx_gain >= 0xf) {
6139                         pg->pg_lna_lod_gain = 1;
6140                         pg->pg_pga_gain = 0;
6141                 } else {
6142                         pg->pg_lna_lod_gain = 0;
6143                         pg->pg_pga_gain = 0;
6144                 }
6145         }
6146
6147         tmp = BWN_RF_READ(mac, 0x7a);
6148         if (pg->pg_lna_lod_gain == 0)
6149                 tmp &= ~0x0008;
6150         else
6151                 tmp |= 0x0008;
6152         BWN_RF_WRITE(mac, 0x7a, tmp);
6153 }
6154
6155 static void
6156 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6157 {
6158         struct bwn_phy *phy = &mac->mac_phy;
6159         struct bwn_phy_g *pg = &phy->phy_g;
6160         struct bwn_softc *sc = mac->mac_sc;
6161         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6162         struct timespec ts;
6163         uint16_t tmp;
6164
6165         if (bwn_has_hwpctl(mac)) {
6166                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6167                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6168                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6169                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6170                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6171
6172                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6173                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6174                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6175                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6176         }
6177         if (phy->type == BWN_PHYTYPE_B &&
6178             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6179                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6180                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6181         }
6182         if (phy->rev >= 2) {
6183                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6184                 sav->phy_analogoverval =
6185                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6186                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6187                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6188                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6189                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6190                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6191
6192                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6193                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6194                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6195                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6196                 if (phy->type == BWN_PHYTYPE_G) {
6197                         if ((phy->rev >= 7) &&
6198                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6199                              BWN_BFL_EXTLNA)) {
6200                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6201                         } else {
6202                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6203                         }
6204                 } else {
6205                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6206                 }
6207                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6208         }
6209         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6210         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6211         sav->rf0 = BWN_RF_READ(mac, 0x43);
6212         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6213         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6214         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6215         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6216         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6217
6218         if (!BWN_HAS_TXMAG(phy)) {
6219                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6220                 sav->rf2 &= 0x00f0;
6221         }
6222         if (phy->type == BWN_PHYTYPE_B) {
6223                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6224                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6225                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6226                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6227         } else {
6228                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6229                             | 0x8000);
6230         }
6231         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6232                     & 0xf000);
6233
6234         tmp =
6235             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6236         BWN_PHY_WRITE(mac, tmp, 0x007f);
6237
6238         tmp = sav->phy_syncctl;
6239         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6240         tmp = sav->rf1;
6241         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6242
6243         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6244         if (phy->type == BWN_PHYTYPE_G ||
6245             (phy->type == BWN_PHYTYPE_B &&
6246              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6247                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6248         } else
6249                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6250         if (phy->rev >= 2)
6251                 bwn_dummy_transmission(mac, 0, 1);
6252         bwn_phy_g_switch_chan(mac, 6, 0);
6253         BWN_RF_READ(mac, 0x51);
6254         if (phy->type == BWN_PHYTYPE_G)
6255                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6256
6257         nanouptime(&ts);
6258         if (time_before(lo->txctl_measured_time,
6259             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6260                 bwn_lo_measure_txctl_values(mac);
6261
6262         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6263                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6264         else {
6265                 if (phy->type == BWN_PHYTYPE_B)
6266                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6267                 else
6268                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6269         }
6270 }
6271
6272 static void
6273 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6274 {
6275         struct bwn_phy *phy = &mac->mac_phy;
6276         struct bwn_phy_g *pg = &phy->phy_g;
6277         uint16_t tmp;
6278
6279         if (phy->rev >= 2) {
6280                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6281                 tmp = (pg->pg_pga_gain << 8);
6282                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6283                 DELAY(5);
6284                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6285                 DELAY(2);
6286                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6287         } else {
6288                 tmp = (pg->pg_pga_gain | 0xefa0);
6289                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6290         }
6291         if (phy->type == BWN_PHYTYPE_G) {
6292                 if (phy->rev >= 3)
6293                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6294                 else
6295                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6296                 if (phy->rev >= 2)
6297                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6298                 else
6299                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6300         }
6301         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6302         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6303         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6304         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6305         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6306         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6307         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6308         if (!BWN_HAS_TXMAG(phy)) {
6309                 tmp = sav->rf2;
6310                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6311         }
6312         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6313         if (phy->type == BWN_PHYTYPE_B &&
6314             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6315                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6316                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6317         }
6318         if (phy->rev >= 2) {
6319                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6320                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6321                               sav->phy_analogoverval);
6322                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6323                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6324                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6325                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6326                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6327         }
6328         if (bwn_has_hwpctl(mac)) {
6329                 tmp = (sav->phy_lomask & 0xbfff);
6330                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6331                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6332                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6333                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6334                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6335         }
6336         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6337 }
6338
6339 static int
6340 bwn_lo_probe_loctl(struct bwn_mac *mac,
6341     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6342 {
6343         struct bwn_phy *phy = &mac->mac_phy;
6344         struct bwn_phy_g *pg = &phy->phy_g;
6345         struct bwn_loctl orig, test;
6346         struct bwn_loctl prev = { -100, -100 };
6347         static const struct bwn_loctl modifiers[] = {
6348                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6349                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6350         };
6351         int begin, end, lower = 0, i;
6352         uint16_t feedth;
6353
6354         if (d->curstate == 0) {
6355                 begin = 1;
6356                 end = 8;
6357         } else if (d->curstate % 2 == 0) {
6358                 begin = d->curstate - 1;
6359                 end = d->curstate + 1;
6360         } else {
6361                 begin = d->curstate - 2;
6362                 end = d->curstate + 2;
6363         }
6364         if (begin < 1)
6365                 begin += 8;
6366         if (end > 8)
6367                 end -= 8;
6368
6369         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6370         i = begin;
6371         d->curstate = i;
6372         while (1) {
6373                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6374                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6375                 test.i += modifiers[i - 1].i * d->multipler;
6376                 test.q += modifiers[i - 1].q * d->multipler;
6377                 if ((test.i != prev.i || test.q != prev.q) &&
6378                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6379                         bwn_lo_write(mac, &test);
6380                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6381                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6382                         if (feedth < d->feedth) {
6383                                 memcpy(probe, &test,
6384                                     sizeof(struct bwn_loctl));
6385                                 lower = 1;
6386                                 d->feedth = feedth;
6387                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6388                                         break;
6389                         }
6390                 }
6391                 memcpy(&prev, &test, sizeof(prev));
6392                 if (i == end)
6393                         break;
6394                 if (i == 8)
6395                         i = 1;
6396                 else
6397                         i++;
6398                 d->curstate = i;
6399         }
6400
6401         return (lower);
6402 }
6403
6404 static void
6405 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6406 {
6407         struct bwn_phy *phy = &mac->mac_phy;
6408         struct bwn_phy_g *pg = &phy->phy_g;
6409         struct bwn_lo_g_sm d;
6410         struct bwn_loctl probe;
6411         int lower, repeat, cnt = 0;
6412         uint16_t feedth;
6413
6414         d.nmeasure = 0;
6415         d.multipler = 1;
6416         if (BWN_HAS_LOOPBACK(phy))
6417                 d.multipler = 3;
6418
6419         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6420         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6421
6422         do {
6423                 bwn_lo_write(mac, &d.loctl);
6424                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6425                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6426                 if (feedth < 0x258) {
6427                         if (feedth >= 0x12c)
6428                                 *rxgain += 6;
6429                         else
6430                                 *rxgain += 3;
6431                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6432                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6433                 }
6434                 d.feedth = feedth;
6435                 d.curstate = 0;
6436                 do {
6437                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6438                             ("%s:%d: fail", __func__, __LINE__));
6439                         memcpy(&probe, &d.loctl,
6440                                sizeof(struct bwn_loctl));
6441                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6442                         if (!lower)
6443                                 break;
6444                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6445                                 break;
6446                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6447                         d.nmeasure++;
6448                 } while (d.nmeasure < 24);
6449                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6450
6451                 if (BWN_HAS_LOOPBACK(phy)) {
6452                         if (d.feedth > 0x1194)
6453                                 *rxgain -= 6;
6454                         else if (d.feedth < 0x5dc)
6455                                 *rxgain += 3;
6456                         if (cnt == 0) {
6457                                 if (d.feedth <= 0x5dc) {
6458                                         d.multipler = 1;
6459                                         cnt++;
6460                                 } else
6461                                         d.multipler = 2;
6462                         } else if (cnt == 2)
6463                                 d.multipler = 1;
6464                 }
6465                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6466         } while (++cnt < repeat);
6467 }
6468
6469 static struct bwn_lo_calib *
6470 bwn_lo_calibset(struct bwn_mac *mac,
6471     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6472 {
6473         struct bwn_phy *phy = &mac->mac_phy;
6474         struct bwn_phy_g *pg = &phy->phy_g;
6475         struct bwn_loctl loctl = { 0, 0 };
6476         struct bwn_lo_calib *cal;
6477         struct bwn_lo_g_value sval = { 0 };
6478         int rxgain;
6479         uint16_t pad, reg, value;
6480
6481         sval.old_channel = phy->chan;
6482         bwn_mac_suspend(mac);
6483         bwn_lo_save(mac, &sval);
6484
6485         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6486         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6487         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6488
6489         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6490         if (rfatt->padmix)
6491                 rxgain -= pad;
6492         if (BWN_HAS_LOOPBACK(phy))
6493                 rxgain += pg->pg_max_lb_gain;
6494         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6495         bwn_phy_g_set_bbatt(mac, bbatt->att);
6496         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6497
6498         bwn_lo_restore(mac, &sval);
6499         bwn_mac_enable(mac);
6500
6501         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6502         if (!cal) {
6503                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6504                 return (NULL);
6505         }
6506         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6507         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6508         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6509
6510         BWN_GETTIME(cal->calib_time);
6511
6512         return (cal);
6513 }
6514
6515 static struct bwn_lo_calib *
6516 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6517     const struct bwn_rfatt *rfatt)
6518 {
6519         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6520         struct bwn_lo_calib *c;
6521
6522         TAILQ_FOREACH(c, &lo->calib_list, list) {
6523                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6524                         continue;
6525                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6526                         continue;
6527                 return (c);
6528         }
6529
6530         c = bwn_lo_calibset(mac, bbatt, rfatt);
6531         if (!c)
6532                 return (NULL);
6533         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6534
6535         return (c);
6536 }
6537
6538 static void
6539 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6540 {
6541         struct bwn_phy *phy = &mac->mac_phy;
6542         struct bwn_phy_g *pg = &phy->phy_g;
6543         struct bwn_softc *sc = mac->mac_sc;
6544         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6545         const struct bwn_rfatt *rfatt;
6546         const struct bwn_bbatt *bbatt;
6547         uint64_t pvector;
6548         int i;
6549         int rf_offset, bb_offset;
6550         uint8_t changed = 0;
6551
6552         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6553         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6554             ("%s:%d: fail", __func__, __LINE__));
6555
6556         pvector = lo->power_vector;
6557         if (!update && !pvector)
6558                 return;
6559
6560         bwn_mac_suspend(mac);
6561
6562         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6563                 struct bwn_lo_calib *cal;
6564                 int idx;
6565                 uint16_t val;
6566
6567                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6568                         continue;
6569                 bb_offset = i / lo->rfatt.len;
6570                 rf_offset = i % lo->rfatt.len;
6571                 bbatt = &(lo->bbatt.array[bb_offset]);
6572                 rfatt = &(lo->rfatt.array[rf_offset]);
6573
6574                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6575                 if (!cal) {
6576                         device_printf(sc->sc_dev, "LO: Could not "
6577                             "calibrate DC table entry\n");
6578                         continue;
6579                 }
6580                 val = (uint8_t)(cal->ctl.q);
6581                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6582                 free(cal, M_DEVBUF);
6583
6584                 idx = i / 2;
6585                 if (i % 2)
6586                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6587                             | ((val & 0x00ff) << 8);
6588                 else
6589                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6590                             | (val & 0x00ff);
6591                 changed = 1;
6592         }
6593         if (changed) {
6594                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6595                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6596         }
6597         bwn_mac_enable(mac);
6598 }
6599
6600 static void
6601 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6602 {
6603
6604         if (!rf->padmix)
6605                 return;
6606         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6607                 rf->att = 4;
6608 }
6609
6610 static void
6611 bwn_lo_g_adjust(struct bwn_mac *mac)
6612 {
6613         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6614         struct bwn_lo_calib *cal;
6615         struct bwn_rfatt rf;
6616
6617         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6618         bwn_lo_fixup_rfatt(&rf);
6619
6620         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6621         if (!cal)
6622                 return;
6623         bwn_lo_write(mac, &cal->ctl);
6624 }
6625
6626 static void
6627 bwn_lo_g_init(struct bwn_mac *mac)
6628 {
6629
6630         if (!bwn_has_hwpctl(mac))
6631                 return;
6632
6633         bwn_lo_get_powervector(mac);
6634         bwn_phy_g_dc_lookup_init(mac, 1);
6635 }
6636
6637 static void
6638 bwn_mac_suspend(struct bwn_mac *mac)
6639 {
6640         struct bwn_softc *sc = mac->mac_sc;
6641         int i;
6642         uint32_t tmp;
6643
6644         KASSERT(mac->mac_suspended >= 0,
6645             ("%s:%d: fail", __func__, __LINE__));
6646
6647         if (mac->mac_suspended == 0) {
6648                 bwn_psctl(mac, BWN_PS_AWAKE);
6649                 BWN_WRITE_4(mac, BWN_MACCTL,
6650                             BWN_READ_4(mac, BWN_MACCTL)
6651                             & ~BWN_MACCTL_ON);
6652                 BWN_READ_4(mac, BWN_MACCTL);
6653                 for (i = 35; i; i--) {
6654                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6655                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6656                                 goto out;
6657                         DELAY(10);
6658                 }
6659                 for (i = 40; i; i--) {
6660                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6661                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6662                                 goto out;
6663                         DELAY(1000);
6664                 }
6665                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6666         }
6667 out:
6668         mac->mac_suspended++;
6669 }
6670
6671 static void
6672 bwn_mac_enable(struct bwn_mac *mac)
6673 {
6674         struct bwn_softc *sc = mac->mac_sc;
6675         uint16_t state;
6676
6677         state = bwn_shm_read_2(mac, BWN_SHARED,
6678             BWN_SHARED_UCODESTAT);
6679         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6680             state != BWN_SHARED_UCODESTAT_SLEEP)
6681                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6682
6683         mac->mac_suspended--;
6684         KASSERT(mac->mac_suspended >= 0,
6685             ("%s:%d: fail", __func__, __LINE__));
6686         if (mac->mac_suspended == 0) {
6687                 BWN_WRITE_4(mac, BWN_MACCTL,
6688                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6689                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6690                 BWN_READ_4(mac, BWN_MACCTL);
6691                 BWN_READ_4(mac, BWN_INTR_REASON);
6692                 bwn_psctl(mac, 0);
6693         }
6694 }
6695
6696 static void
6697 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6698 {
6699         struct bwn_softc *sc = mac->mac_sc;
6700         int i;
6701         uint16_t ucstat;
6702
6703         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6704             ("%s:%d: fail", __func__, __LINE__));
6705         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6706             ("%s:%d: fail", __func__, __LINE__));
6707
6708         /* XXX forcibly awake and hwps-off */
6709
6710         BWN_WRITE_4(mac, BWN_MACCTL,
6711             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6712             ~BWN_MACCTL_HWPS);
6713         BWN_READ_4(mac, BWN_MACCTL);
6714         if (siba_get_revid(sc->sc_dev) >= 5) {
6715                 for (i = 0; i < 100; i++) {
6716                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6717                             BWN_SHARED_UCODESTAT);
6718                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6719                                 break;
6720                         DELAY(10);
6721                 }
6722         }
6723 }
6724
6725 static int16_t
6726 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6727 {
6728
6729         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6730         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6731 }
6732
6733 static void
6734 bwn_nrssi_threshold(struct bwn_mac *mac)
6735 {
6736         struct bwn_phy *phy = &mac->mac_phy;
6737         struct bwn_phy_g *pg = &phy->phy_g;
6738         struct bwn_softc *sc = mac->mac_sc;
6739         int32_t a, b;
6740         int16_t tmp16;
6741         uint16_t tmpu16;
6742
6743         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6744
6745         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6746                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6747                         a = 0x13;
6748                         b = 0x12;
6749                 } else {
6750                         a = 0xe;
6751                         b = 0x11;
6752                 }
6753
6754                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6755                 a += (pg->pg_nrssi[0] << 6);
6756                 a += (a < 32) ? 31 : 32;
6757                 a = a >> 6;
6758                 a = MIN(MAX(a, -31), 31);
6759
6760                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6761                 b += (pg->pg_nrssi[0] << 6);
6762                 if (b < 32)
6763                         b += 31;
6764                 else
6765                         b += 32;
6766                 b = b >> 6;
6767                 b = MIN(MAX(b, -31), 31);
6768
6769                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6770                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6771                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6772                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6773                 return;
6774         }
6775
6776         tmp16 = bwn_nrssi_read(mac, 0x20);
6777         if (tmp16 >= 0x20)
6778                 tmp16 -= 0x40;
6779         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6780 }
6781
6782 static void
6783 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6784 {
6785 #define SAVE_RF_MAX             3
6786 #define SAVE_PHY_COMM_MAX       4
6787 #define SAVE_PHY3_MAX           8
6788         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6789                 { 0x7a, 0x52, 0x43 };
6790         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6791                 { 0x15, 0x5a, 0x59, 0x58 };
6792         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6793                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6794                 0x0801, 0x0060, 0x0014, 0x0478
6795         };
6796         struct bwn_phy *phy = &mac->mac_phy;
6797         struct bwn_phy_g *pg = &phy->phy_g;
6798         int32_t i, tmp32, phy3_idx = 0;
6799         uint16_t delta, tmp;
6800         uint16_t save_rf[SAVE_RF_MAX];
6801         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6802         uint16_t save_phy3[SAVE_PHY3_MAX];
6803         uint16_t ant_div, phy0, chan_ex;
6804         int16_t nrssi0, nrssi1;
6805
6806         KASSERT(phy->type == BWN_PHYTYPE_G,
6807             ("%s:%d: fail", __func__, __LINE__));
6808
6809         if (phy->rf_rev >= 9)
6810                 return;
6811         if (phy->rf_rev == 8)
6812                 bwn_nrssi_offset(mac);
6813
6814         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6815         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6816
6817         /*
6818          * Save RF/PHY registers for later restoration
6819          */
6820         ant_div = BWN_READ_2(mac, 0x03e2);
6821         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6822         for (i = 0; i < SAVE_RF_MAX; ++i)
6823                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6824         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6825                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6826
6827         phy0 = BWN_READ_2(mac, BWN_PHY0);
6828         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6829         if (phy->rev >= 3) {
6830                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6831                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6832                 BWN_PHY_WRITE(mac, 0x002e, 0);
6833                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6834                 switch (phy->rev) {
6835                 case 4:
6836                 case 6:
6837                 case 7:
6838                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6839                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6840                         break;
6841                 case 3:
6842                 case 5:
6843                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6844                         break;
6845                 }
6846                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6847                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6848         }
6849         /*
6850          * Calculate nrssi0
6851          */
6852         BWN_RF_SET(mac, 0x007a, 0x0070);
6853         bwn_set_all_gains(mac, 0, 8, 0);
6854         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6855         if (phy->rev >= 2) {
6856                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6857                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6858         }
6859         BWN_RF_SET(mac, 0x007a, 0x0080);
6860         DELAY(20);
6861
6862         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6863         if (nrssi0 >= 0x0020)
6864                 nrssi0 -= 0x0040;
6865
6866         /*
6867          * Calculate nrssi1
6868          */
6869         BWN_RF_MASK(mac, 0x007a, 0x007f);
6870         if (phy->rev >= 2)
6871                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6872
6873         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6874             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6875         BWN_RF_SET(mac, 0x007a, 0x000f);
6876         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6877         if (phy->rev >= 2) {
6878                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6879                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6880         }
6881
6882         bwn_set_all_gains(mac, 3, 0, 1);
6883         if (phy->rf_rev == 8) {
6884                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6885         } else {
6886                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6887                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6888                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6889                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6890         }
6891         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6892         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6893         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6894         DELAY(20);
6895         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6896
6897         /*
6898          * Install calculated narrow RSSI values
6899          */
6900         if (nrssi1 >= 0x0020)
6901                 nrssi1 -= 0x0040;
6902         if (nrssi0 == nrssi1)
6903                 pg->pg_nrssi_slope = 0x00010000;
6904         else
6905                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6906         if (nrssi0 >= -4) {
6907                 pg->pg_nrssi[0] = nrssi1;
6908                 pg->pg_nrssi[1] = nrssi0;
6909         }
6910
6911         /*
6912          * Restore saved RF/PHY registers
6913          */
6914         if (phy->rev >= 3) {
6915                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6916                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6917                             save_phy3[phy3_idx]);
6918                 }
6919         }
6920         if (phy->rev >= 2) {
6921                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6922                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6923         }
6924
6925         for (i = 0; i < SAVE_RF_MAX; ++i)
6926                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6927
6928         BWN_WRITE_2(mac, 0x03e2, ant_div);
6929         BWN_WRITE_2(mac, 0x03e6, phy0);
6930         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6931
6932         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6933                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6934
6935         bwn_spu_workaround(mac, phy->chan);
6936         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6937         bwn_set_original_gains(mac);
6938         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6939         if (phy->rev >= 3) {
6940                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6941                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6942                             save_phy3[phy3_idx]);
6943                 }
6944         }
6945
6946         delta = 0x1f - pg->pg_nrssi[0];
6947         for (i = 0; i < 64; i++) {
6948                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6949                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6950                 pg->pg_nrssi_lt[i] = tmp32;
6951         }
6952
6953         bwn_nrssi_threshold(mac);
6954 #undef SAVE_RF_MAX
6955 #undef SAVE_PHY_COMM_MAX
6956 #undef SAVE_PHY3_MAX
6957 }
6958
6959 static void
6960 bwn_nrssi_offset(struct bwn_mac *mac)
6961 {
6962 #define SAVE_RF_MAX             2
6963 #define SAVE_PHY_COMM_MAX       10
6964 #define SAVE_PHY6_MAX           8
6965         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6966                 { 0x7a, 0x43 };
6967         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6968                 0x0001, 0x0811, 0x0812, 0x0814,
6969                 0x0815, 0x005a, 0x0059, 0x0058,
6970                 0x000a, 0x0003
6971         };
6972         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6973                 0x002e, 0x002f, 0x080f, 0x0810,
6974                 0x0801, 0x0060, 0x0014, 0x0478
6975         };
6976         struct bwn_phy *phy = &mac->mac_phy;
6977         int i, phy6_idx = 0;
6978         uint16_t save_rf[SAVE_RF_MAX];
6979         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6980         uint16_t save_phy6[SAVE_PHY6_MAX];
6981         int16_t nrssi;
6982         uint16_t saved = 0xffff;
6983
6984         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6985                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6986         for (i = 0; i < SAVE_RF_MAX; ++i)
6987                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6988
6989         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6990         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6991         BWN_PHY_SET(mac, 0x0811, 0x000c);
6992         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6993         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6994         if (phy->rev >= 6) {
6995                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6996                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6997
6998                 BWN_PHY_WRITE(mac, 0x002e, 0);
6999                 BWN_PHY_WRITE(mac, 0x002f, 0);
7000                 BWN_PHY_WRITE(mac, 0x080f, 0);
7001                 BWN_PHY_WRITE(mac, 0x0810, 0);
7002                 BWN_PHY_SET(mac, 0x0478, 0x0100);
7003                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7004                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7005                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7006         }
7007         BWN_RF_SET(mac, 0x007a, 0x0070);
7008         BWN_RF_SET(mac, 0x007a, 0x0080);
7009         DELAY(30);
7010
7011         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7012         if (nrssi >= 0x20)
7013                 nrssi -= 0x40;
7014         if (nrssi == 31) {
7015                 for (i = 7; i >= 4; i--) {
7016                         BWN_RF_WRITE(mac, 0x007b, i);
7017                         DELAY(20);
7018                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7019                             0x003f);
7020                         if (nrssi >= 0x20)
7021                                 nrssi -= 0x40;
7022                         if (nrssi < 31 && saved == 0xffff)
7023                                 saved = i;
7024                 }
7025                 if (saved == 0xffff)
7026                         saved = 4;
7027         } else {
7028                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7029                 if (phy->rev != 1) {
7030                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7031                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7032                 }
7033                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7034                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7035                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7036                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7037                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7038                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7039                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7040                 if (phy->rev == 0)
7041                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7042                 else
7043                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7044                 if (phy->rev != 1) {
7045                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7046                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7047                 }
7048                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7049                 BWN_RF_SET(mac, 0x007a, 0x000f);
7050                 bwn_set_all_gains(mac, 3, 0, 1);
7051                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7052                 DELAY(30);
7053                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7054                 if (nrssi >= 0x20)
7055                         nrssi -= 0x40;
7056                 if (nrssi == -32) {
7057                         for (i = 0; i < 4; i++) {
7058                                 BWN_RF_WRITE(mac, 0x007b, i);
7059                                 DELAY(20);
7060                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7061                                     0x047f) >> 8) & 0x003f);
7062                                 if (nrssi >= 0x20)
7063                                         nrssi -= 0x40;
7064                                 if (nrssi > -31 && saved == 0xffff)
7065                                         saved = i;
7066                         }
7067                         if (saved == 0xffff)
7068                                 saved = 3;
7069                 } else
7070                         saved = 0;
7071         }
7072         BWN_RF_WRITE(mac, 0x007b, saved);
7073
7074         /*
7075          * Restore saved RF/PHY registers
7076          */
7077         if (phy->rev >= 6) {
7078                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7079                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7080                             save_phy6[phy6_idx]);
7081                 }
7082         }
7083         if (phy->rev != 1) {
7084                 for (i = 3; i < 5; i++)
7085                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7086                             save_phy_comm[i]);
7087         }
7088         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7089                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7090
7091         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7092                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7093
7094         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7095         BWN_PHY_SET(mac, 0x0429, 0x8000);
7096         bwn_set_original_gains(mac);
7097         if (phy->rev >= 6) {
7098                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7099                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7100                             save_phy6[phy6_idx]);
7101                 }
7102         }
7103
7104         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7105         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7106         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7107 }
7108
7109 static void
7110 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7111     int16_t third)
7112 {
7113         struct bwn_phy *phy = &mac->mac_phy;
7114         uint16_t i;
7115         uint16_t start = 0x08, end = 0x18;
7116         uint16_t tmp;
7117         uint16_t table;
7118
7119         if (phy->rev <= 1) {
7120                 start = 0x10;
7121                 end = 0x20;
7122         }
7123
7124         table = BWN_OFDMTAB_GAINX;
7125         if (phy->rev <= 1)
7126                 table = BWN_OFDMTAB_GAINX_R1;
7127         for (i = 0; i < 4; i++)
7128                 bwn_ofdmtab_write_2(mac, table, i, first);
7129
7130         for (i = start; i < end; i++)
7131                 bwn_ofdmtab_write_2(mac, table, i, second);
7132
7133         if (third != -1) {
7134                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7135                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7136                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7137                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7138         }
7139         bwn_dummy_transmission(mac, 0, 1);
7140 }
7141
7142 static void
7143 bwn_set_original_gains(struct bwn_mac *mac)
7144 {
7145         struct bwn_phy *phy = &mac->mac_phy;
7146         uint16_t i, tmp;
7147         uint16_t table;
7148         uint16_t start = 0x0008, end = 0x0018;
7149
7150         if (phy->rev <= 1) {
7151                 start = 0x0010;
7152                 end = 0x0020;
7153         }
7154
7155         table = BWN_OFDMTAB_GAINX;
7156         if (phy->rev <= 1)
7157                 table = BWN_OFDMTAB_GAINX_R1;
7158         for (i = 0; i < 4; i++) {
7159                 tmp = (i & 0xfffc);
7160                 tmp |= (i & 0x0001) << 1;
7161                 tmp |= (i & 0x0002) >> 1;
7162
7163                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7164         }
7165
7166         for (i = start; i < end; i++)
7167                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7168
7169         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7170         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7171         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7172         bwn_dummy_transmission(mac, 0, 1);
7173 }
7174
7175 static void
7176 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7177 {
7178         struct bwn_phy *phy = &mac->mac_phy;
7179         struct bwn_phy_g *pg = &phy->phy_g;
7180         struct bwn_rfatt old_rfatt, rfatt;
7181         struct bwn_bbatt old_bbatt, bbatt;
7182         struct bwn_softc *sc = mac->mac_sc;
7183         uint8_t old_txctl = 0;
7184
7185         KASSERT(phy->type == BWN_PHYTYPE_G,
7186             ("%s:%d: fail", __func__, __LINE__));
7187
7188         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7189             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7190                 return;
7191
7192         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7193
7194         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7195
7196         if (!phy->gmode)
7197                 return;
7198         bwn_hwpctl_early_init(mac);
7199         if (pg->pg_curtssi == 0) {
7200                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7201                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7202                 } else {
7203                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7204                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7205                         old_txctl = pg->pg_txctl;
7206
7207                         bbatt.att = 11;
7208                         if (phy->rf_rev == 8) {
7209                                 rfatt.att = 15;
7210                                 rfatt.padmix = 1;
7211                         } else {
7212                                 rfatt.att = 9;
7213                                 rfatt.padmix = 0;
7214                         }
7215                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7216                 }
7217                 bwn_dummy_transmission(mac, 0, 1);
7218                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7219                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7220                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7221                 else
7222                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7223                             &old_rfatt, old_txctl);
7224         }
7225         bwn_hwpctl_init_gphy(mac);
7226
7227         /* clear TSSI */
7228         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7229         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7230         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7231         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7232 }
7233
7234 static void
7235 bwn_hwpctl_early_init(struct bwn_mac *mac)
7236 {
7237         struct bwn_phy *phy = &mac->mac_phy;
7238
7239         if (!bwn_has_hwpctl(mac)) {
7240                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7241                 return;
7242         }
7243
7244         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7245         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7246         BWN_PHY_SET(mac, 0x047c, 0x0002);
7247         BWN_PHY_SET(mac, 0x047a, 0xf000);
7248         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7249                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7250                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7251                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7252                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7253                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7254         } else {
7255                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7256                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7257                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7258                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7259                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7260                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7261                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7262         }
7263 }
7264
7265 static void
7266 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7267 {
7268         struct bwn_phy *phy = &mac->mac_phy;
7269         struct bwn_phy_g *pg = &phy->phy_g;
7270         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7271         int i;
7272         uint16_t nr_written = 0, tmp, value;
7273         uint8_t rf, bb;
7274
7275         if (!bwn_has_hwpctl(mac)) {
7276                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7277                 return;
7278         }
7279
7280         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7281             (pg->pg_idletssi - pg->pg_curtssi));
7282         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7283             (pg->pg_idletssi - pg->pg_curtssi));
7284
7285         for (i = 0; i < 32; i++)
7286                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7287         for (i = 32; i < 64; i++)
7288                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7289         for (i = 0; i < 64; i += 2) {
7290                 value = (uint16_t) pg->pg_tssi2dbm[i];
7291                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7292                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7293         }
7294
7295         for (rf = 0; rf < lo->rfatt.len; rf++) {
7296                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7297                         if (nr_written >= 0x40)
7298                                 return;
7299                         tmp = lo->bbatt.array[bb].att;
7300                         tmp <<= 8;
7301                         if (phy->rf_rev == 8)
7302                                 tmp |= 0x50;
7303                         else
7304                                 tmp |= 0x40;
7305                         tmp |= lo->rfatt.array[rf].att;
7306                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7307                         nr_written++;
7308                 }
7309         }
7310
7311         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7312         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7313
7314         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7315         BWN_PHY_SET(mac, 0x0478, 0x0800);
7316         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7317         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7318
7319         bwn_phy_g_dc_lookup_init(mac, 1);
7320         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7321 }
7322
7323 static void
7324 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7325 {
7326         struct bwn_softc *sc = mac->mac_sc;
7327
7328         if (spu != 0)
7329                 bwn_spu_workaround(mac, channel);
7330
7331         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7332
7333         if (channel == 14) {
7334                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7335                         bwn_hf_write(mac,
7336                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7337                 else
7338                         bwn_hf_write(mac,
7339                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7340                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7341                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7342                 return;
7343         }
7344
7345         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7346             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7347 }
7348
7349 static uint16_t
7350 bwn_phy_g_chan2freq(uint8_t channel)
7351 {
7352         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7353
7354         KASSERT(channel >= 1 && channel <= 14,
7355             ("%s:%d: fail", __func__, __LINE__));
7356
7357         return (bwn_phy_g_rf_channels[channel - 1]);
7358 }
7359
7360 static void
7361 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7362     const struct bwn_rfatt *rfatt, uint8_t txctl)
7363 {
7364         struct bwn_phy *phy = &mac->mac_phy;
7365         struct bwn_phy_g *pg = &phy->phy_g;
7366         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7367         uint16_t bb, rf;
7368         uint16_t tx_bias, tx_magn;
7369
7370         bb = bbatt->att;
7371         rf = rfatt->att;
7372         tx_bias = lo->tx_bias;
7373         tx_magn = lo->tx_magn;
7374         if (tx_bias == 0xff)
7375                 tx_bias = 0;
7376
7377         pg->pg_txctl = txctl;
7378         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7379         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7380         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7381         bwn_phy_g_set_bbatt(mac, bb);
7382         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7383         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7384                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7385         else {
7386                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7387                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7388         }
7389         if (BWN_HAS_TXMAG(phy))
7390                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7391         else
7392                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7393         bwn_lo_g_adjust(mac);
7394 }
7395
7396 static void
7397 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7398     uint16_t bbatt)
7399 {
7400         struct bwn_phy *phy = &mac->mac_phy;
7401
7402         if (phy->analog == 0) {
7403                 BWN_WRITE_2(mac, BWN_PHY0,
7404                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7405                 return;
7406         }
7407         if (phy->analog > 1) {
7408                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7409                 return;
7410         }
7411         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7412 }
7413
7414 static uint16_t
7415 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7416 {
7417         struct bwn_phy *phy = &mac->mac_phy;
7418         struct bwn_phy_g *pg = &phy->phy_g;
7419         struct bwn_softc *sc = mac->mac_sc;
7420         int max_lb_gain;
7421         uint16_t extlna;
7422         uint16_t i;
7423
7424         if (phy->gmode == 0)
7425                 return (0);
7426
7427         if (BWN_HAS_LOOPBACK(phy)) {
7428                 max_lb_gain = pg->pg_max_lb_gain;
7429                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7430                 if (max_lb_gain >= 0x46) {
7431                         extlna = 0x3000;
7432                         max_lb_gain -= 0x46;
7433                 } else if (max_lb_gain >= 0x3a) {
7434                         extlna = 0x1000;
7435                         max_lb_gain -= 0x3a;
7436                 } else if (max_lb_gain >= 0x2e) {
7437                         extlna = 0x2000;
7438                         max_lb_gain -= 0x2e;
7439                 } else {
7440                         extlna = 0;
7441                         max_lb_gain -= 0x10;
7442                 }
7443
7444                 for (i = 0; i < 16; i++) {
7445                         max_lb_gain -= (i * 6);
7446                         if (max_lb_gain < 6)
7447                                 break;
7448                 }
7449
7450                 if ((phy->rev < 7) ||
7451                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7452                         if (reg == BWN_PHY_RFOVER) {
7453                                 return (0x1b3);
7454                         } else if (reg == BWN_PHY_RFOVERVAL) {
7455                                 extlna |= (i << 8);
7456                                 switch (lpd) {
7457                                 case BWN_LPD(0, 1, 1):
7458                                         return (0x0f92);
7459                                 case BWN_LPD(0, 0, 1):
7460                                 case BWN_LPD(1, 0, 1):
7461                                         return (0x0092 | extlna);
7462                                 case BWN_LPD(1, 0, 0):
7463                                         return (0x0093 | extlna);
7464                                 }
7465                                 KASSERT(0 == 1,
7466                                     ("%s:%d: fail", __func__, __LINE__));
7467                         }
7468                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7469                 } else {
7470                         if (reg == BWN_PHY_RFOVER)
7471                                 return (0x9b3);
7472                         if (reg == BWN_PHY_RFOVERVAL) {
7473                                 if (extlna)
7474                                         extlna |= 0x8000;
7475                                 extlna |= (i << 8);
7476                                 switch (lpd) {
7477                                 case BWN_LPD(0, 1, 1):
7478                                         return (0x8f92);
7479                                 case BWN_LPD(0, 0, 1):
7480                                         return (0x8092 | extlna);
7481                                 case BWN_LPD(1, 0, 1):
7482                                         return (0x2092 | extlna);
7483                                 case BWN_LPD(1, 0, 0):
7484                                         return (0x2093 | extlna);
7485                                 }
7486                                 KASSERT(0 == 1,
7487                                     ("%s:%d: fail", __func__, __LINE__));
7488                         }
7489                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7490                 }
7491                 return (0);
7492         }
7493
7494         if ((phy->rev < 7) ||
7495             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7496                 if (reg == BWN_PHY_RFOVER) {
7497                         return (0x1b3);
7498                 } else if (reg == BWN_PHY_RFOVERVAL) {
7499                         switch (lpd) {
7500                         case BWN_LPD(0, 1, 1):
7501                                 return (0x0fb2);
7502                         case BWN_LPD(0, 0, 1):
7503                                 return (0x00b2);
7504                         case BWN_LPD(1, 0, 1):
7505                                 return (0x30b2);
7506                         case BWN_LPD(1, 0, 0):
7507                                 return (0x30b3);
7508                         }
7509                         KASSERT(0 == 1,
7510                             ("%s:%d: fail", __func__, __LINE__));
7511                 }
7512                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7513         } else {
7514                 if (reg == BWN_PHY_RFOVER) {
7515                         return (0x9b3);
7516                 } else if (reg == BWN_PHY_RFOVERVAL) {
7517                         switch (lpd) {
7518                         case BWN_LPD(0, 1, 1):
7519                                 return (0x8fb2);
7520                         case BWN_LPD(0, 0, 1):
7521                                 return (0x80b2);
7522                         case BWN_LPD(1, 0, 1):
7523                                 return (0x20b2);
7524                         case BWN_LPD(1, 0, 0):
7525                                 return (0x20b3);
7526                         }
7527                         KASSERT(0 == 1,
7528                             ("%s:%d: fail", __func__, __LINE__));
7529                 }
7530                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7531         }
7532         return (0);
7533 }
7534
7535 static void
7536 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7537 {
7538
7539         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7540                 return;
7541         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7542             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7543         DELAY(1000);
7544         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7545 }
7546
7547 static int
7548 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7549 {
7550         struct bwn_softc *sc = mac->mac_sc;
7551         struct bwn_fw *fw = &mac->mac_fw;
7552         const uint8_t rev = siba_get_revid(sc->sc_dev);
7553         const char *filename;
7554         uint32_t high;
7555         int error;
7556
7557         /* microcode */
7558         if (rev >= 5 && rev <= 10)
7559                 filename = "ucode5";
7560         else if (rev >= 11 && rev <= 12)
7561                 filename = "ucode11";
7562         else if (rev == 13)
7563                 filename = "ucode13";
7564         else if (rev == 14)
7565                 filename = "ucode14";
7566         else if (rev >= 15)
7567                 filename = "ucode15";
7568         else {
7569                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7570                 bwn_release_firmware(mac);
7571                 return (EOPNOTSUPP);
7572         }
7573         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7574         if (error) {
7575                 bwn_release_firmware(mac);
7576                 return (error);
7577         }
7578
7579         /* PCM */
7580         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7581         if (rev >= 5 && rev <= 10) {
7582                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7583                 if (error == ENOENT)
7584                         fw->no_pcmfile = 1;
7585                 else if (error) {
7586                         bwn_release_firmware(mac);
7587                         return (error);
7588                 }
7589         } else if (rev < 11) {
7590                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7591                 return (EOPNOTSUPP);
7592         }
7593
7594         /* initvals */
7595         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7596         switch (mac->mac_phy.type) {
7597         case BWN_PHYTYPE_A:
7598                 if (rev < 5 || rev > 10)
7599                         goto fail1;
7600                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7601                         filename = "a0g1initvals5";
7602                 else
7603                         filename = "a0g0initvals5";
7604                 break;
7605         case BWN_PHYTYPE_G:
7606                 if (rev >= 5 && rev <= 10)
7607                         filename = "b0g0initvals5";
7608                 else if (rev >= 13)
7609                         filename = "b0g0initvals13";
7610                 else
7611                         goto fail1;
7612                 break;
7613         case BWN_PHYTYPE_LP:
7614                 if (rev == 13)
7615                         filename = "lp0initvals13";
7616                 else if (rev == 14)
7617                         filename = "lp0initvals14";
7618                 else if (rev >= 15)
7619                         filename = "lp0initvals15";
7620                 else
7621                         goto fail1;
7622                 break;
7623         case BWN_PHYTYPE_N:
7624                 if (rev >= 11 && rev <= 12)
7625                         filename = "n0initvals11";
7626                 else
7627                         goto fail1;
7628                 break;
7629         default:
7630                 goto fail1;
7631         }
7632         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7633         if (error) {
7634                 bwn_release_firmware(mac);
7635                 return (error);
7636         }
7637
7638         /* bandswitch initvals */
7639         switch (mac->mac_phy.type) {
7640         case BWN_PHYTYPE_A:
7641                 if (rev >= 5 && rev <= 10) {
7642                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7643                                 filename = "a0g1bsinitvals5";
7644                         else
7645                                 filename = "a0g0bsinitvals5";
7646                 } else if (rev >= 11)
7647                         filename = NULL;
7648                 else
7649                         goto fail1;
7650                 break;
7651         case BWN_PHYTYPE_G:
7652                 if (rev >= 5 && rev <= 10)
7653                         filename = "b0g0bsinitvals5";
7654                 else if (rev >= 11)
7655                         filename = NULL;
7656                 else
7657                         goto fail1;
7658                 break;
7659         case BWN_PHYTYPE_LP:
7660                 if (rev == 13)
7661                         filename = "lp0bsinitvals13";
7662                 else if (rev == 14)
7663                         filename = "lp0bsinitvals14";
7664                 else if (rev >= 15)
7665                         filename = "lp0bsinitvals15";
7666                 else
7667                         goto fail1;
7668                 break;
7669         case BWN_PHYTYPE_N:
7670                 if (rev >= 11 && rev <= 12)
7671                         filename = "n0bsinitvals11";
7672                 else
7673                         goto fail1;
7674                 break;
7675         default:
7676                 goto fail1;
7677         }
7678         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7679         if (error) {
7680                 bwn_release_firmware(mac);
7681                 return (error);
7682         }
7683         return (0);
7684 fail1:
7685         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7686         bwn_release_firmware(mac);
7687         return (EOPNOTSUPP);
7688 }
7689
7690 static int
7691 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7692     const char *name, struct bwn_fwfile *bfw)
7693 {
7694         const struct bwn_fwhdr *hdr;
7695         struct bwn_softc *sc = mac->mac_sc;
7696         const struct firmware *fw;
7697         char namebuf[64];
7698
7699         if (name == NULL) {
7700                 bwn_do_release_fw(bfw);
7701                 return (0);
7702         }
7703         if (bfw->filename != NULL) {
7704                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7705                         return (0);
7706                 bwn_do_release_fw(bfw);
7707         }
7708
7709         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7710             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7711             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7712         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7713         fw = firmware_get(namebuf);
7714         if (fw == NULL) {
7715                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7716                     namebuf);
7717                 return (ENOENT);
7718         }
7719         if (fw->datasize < sizeof(struct bwn_fwhdr))
7720                 goto fail;
7721         hdr = (const struct bwn_fwhdr *)(fw->data);
7722         switch (hdr->type) {
7723         case BWN_FWTYPE_UCODE:
7724         case BWN_FWTYPE_PCM:
7725                 if (be32toh(hdr->size) !=
7726                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7727                         goto fail;
7728                 /* FALLTHROUGH */
7729         case BWN_FWTYPE_IV:
7730                 if (hdr->ver != 1)
7731                         goto fail;
7732                 break;
7733         default:
7734                 goto fail;
7735         }
7736         bfw->filename = name;
7737         bfw->fw = fw;
7738         bfw->type = type;
7739         return (0);
7740 fail:
7741         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7742         if (fw != NULL)
7743                 firmware_put(fw, FIRMWARE_UNLOAD);
7744         return (EPROTO);
7745 }
7746
7747 static void
7748 bwn_release_firmware(struct bwn_mac *mac)
7749 {
7750
7751         bwn_do_release_fw(&mac->mac_fw.ucode);
7752         bwn_do_release_fw(&mac->mac_fw.pcm);
7753         bwn_do_release_fw(&mac->mac_fw.initvals);
7754         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7755 }
7756
7757 static void
7758 bwn_do_release_fw(struct bwn_fwfile *bfw)
7759 {
7760
7761         if (bfw->fw != NULL)
7762                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7763         bfw->fw = NULL;
7764         bfw->filename = NULL;
7765 }
7766
7767 static int
7768 bwn_fw_loaducode(struct bwn_mac *mac)
7769 {
7770 #define GETFWOFFSET(fwp, offset)        \
7771         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7772 #define GETFWSIZE(fwp, offset)  \
7773         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7774         struct bwn_softc *sc = mac->mac_sc;
7775         const uint32_t *data;
7776         unsigned int i;
7777         uint32_t ctl;
7778         uint16_t date, fwcaps, time;
7779         int error = 0;
7780
7781         ctl = BWN_READ_4(mac, BWN_MACCTL);
7782         ctl |= BWN_MACCTL_MCODE_JMP0;
7783         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7784             __LINE__));
7785         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7786         for (i = 0; i < 64; i++)
7787                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7788         for (i = 0; i < 4096; i += 2)
7789                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7790
7791         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7792         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7793         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7794              i++) {
7795                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7796                 DELAY(10);
7797         }
7798
7799         if (mac->mac_fw.pcm.fw) {
7800                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7801                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7802                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7803                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7804                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7805                     sizeof(struct bwn_fwhdr)); i++) {
7806                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7807                         DELAY(10);
7808                 }
7809         }
7810
7811         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7812         BWN_WRITE_4(mac, BWN_MACCTL,
7813             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7814             BWN_MACCTL_MCODE_RUN);
7815
7816         for (i = 0; i < 21; i++) {
7817                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7818                         break;
7819                 if (i >= 20) {
7820                         device_printf(sc->sc_dev, "ucode timeout\n");
7821                         error = ENXIO;
7822                         goto error;
7823                 }
7824                 DELAY(50000);
7825         }
7826         BWN_READ_4(mac, BWN_INTR_REASON);
7827
7828         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7829         if (mac->mac_fw.rev <= 0x128) {
7830                 device_printf(sc->sc_dev, "the firmware is too old\n");
7831                 error = EOPNOTSUPP;
7832                 goto error;
7833         }
7834         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7835             BWN_SHARED_UCODE_PATCH);
7836         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7837         mac->mac_fw.opensource = (date == 0xffff);
7838         if (bwn_wme != 0)
7839                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7840         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7841
7842         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7843         if (mac->mac_fw.opensource == 0) {
7844                 device_printf(sc->sc_dev,
7845                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7846                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7847                 if (mac->mac_fw.no_pcmfile)
7848                         device_printf(sc->sc_dev,
7849                             "no HW crypto acceleration due to pcm5\n");
7850         } else {
7851                 mac->mac_fw.patch = time;
7852                 fwcaps = bwn_fwcaps_read(mac);
7853                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7854                         device_printf(sc->sc_dev,
7855                             "disabling HW crypto acceleration\n");
7856                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7857                 }
7858                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7859                         device_printf(sc->sc_dev, "disabling WME support\n");
7860                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7861                 }
7862         }
7863
7864         if (BWN_ISOLDFMT(mac))
7865                 device_printf(sc->sc_dev, "using old firmware image\n");
7866
7867         return (0);
7868
7869 error:
7870         BWN_WRITE_4(mac, BWN_MACCTL,
7871             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7872             BWN_MACCTL_MCODE_JMP0);
7873
7874         return (error);
7875 #undef GETFWSIZE
7876 #undef GETFWOFFSET
7877 }
7878
7879 /* OpenFirmware only */
7880 static uint16_t
7881 bwn_fwcaps_read(struct bwn_mac *mac)
7882 {
7883
7884         KASSERT(mac->mac_fw.opensource == 1,
7885             ("%s:%d: fail", __func__, __LINE__));
7886         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7887 }
7888
7889 static int
7890 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7891     size_t count, size_t array_size)
7892 {
7893 #define GET_NEXTIV16(iv)                                                \
7894         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7895             sizeof(uint16_t) + sizeof(uint16_t)))
7896 #define GET_NEXTIV32(iv)                                                \
7897         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7898             sizeof(uint16_t) + sizeof(uint32_t)))
7899         struct bwn_softc *sc = mac->mac_sc;
7900         const struct bwn_fwinitvals *iv;
7901         uint16_t offset;
7902         size_t i;
7903         uint8_t bit32;
7904
7905         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7906             ("%s:%d: fail", __func__, __LINE__));
7907         iv = ivals;
7908         for (i = 0; i < count; i++) {
7909                 if (array_size < sizeof(iv->offset_size))
7910                         goto fail;
7911                 array_size -= sizeof(iv->offset_size);
7912                 offset = be16toh(iv->offset_size);
7913                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7914                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7915                 if (offset >= 0x1000)
7916                         goto fail;
7917                 if (bit32) {
7918                         if (array_size < sizeof(iv->data.d32))
7919                                 goto fail;
7920                         array_size -= sizeof(iv->data.d32);
7921                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7922                         iv = GET_NEXTIV32(iv);
7923                 } else {
7924
7925                         if (array_size < sizeof(iv->data.d16))
7926                                 goto fail;
7927                         array_size -= sizeof(iv->data.d16);
7928                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7929
7930                         iv = GET_NEXTIV16(iv);
7931                 }
7932         }
7933         if (array_size != 0)
7934                 goto fail;
7935         return (0);
7936 fail:
7937         device_printf(sc->sc_dev, "initvals: invalid format\n");
7938         return (EPROTO);
7939 #undef GET_NEXTIV16
7940 #undef GET_NEXTIV32
7941 }
7942
7943 static int
7944 bwn_switch_channel(struct bwn_mac *mac, int chan)
7945 {
7946         struct bwn_phy *phy = &(mac->mac_phy);
7947         struct bwn_softc *sc = mac->mac_sc;
7948         struct ifnet *ifp = sc->sc_ifp;
7949         struct ieee80211com *ic = ifp->if_l2com;
7950         uint16_t channelcookie, savedcookie;
7951         int error;
7952
7953         if (chan == 0xffff)
7954                 chan = phy->get_default_chan(mac);
7955
7956         channelcookie = chan;
7957         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7958                 channelcookie |= 0x100;
7959         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7960         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7961         error = phy->switch_channel(mac, chan);
7962         if (error)
7963                 goto fail;
7964
7965         mac->mac_phy.chan = chan;
7966         DELAY(8000);
7967         return (0);
7968 fail:
7969         device_printf(sc->sc_dev, "failed to switch channel\n");
7970         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7971         return (error);
7972 }
7973
7974 static uint16_t
7975 bwn_ant2phy(int antenna)
7976 {
7977
7978         switch (antenna) {
7979         case BWN_ANT0:
7980                 return (BWN_TX_PHY_ANT0);
7981         case BWN_ANT1:
7982                 return (BWN_TX_PHY_ANT1);
7983         case BWN_ANT2:
7984                 return (BWN_TX_PHY_ANT2);
7985         case BWN_ANT3:
7986                 return (BWN_TX_PHY_ANT3);
7987         case BWN_ANTAUTO:
7988                 return (BWN_TX_PHY_ANT01AUTO);
7989         }
7990         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7991         return (0);
7992 }
7993
7994 static void
7995 bwn_wme_load(struct bwn_mac *mac)
7996 {
7997         struct bwn_softc *sc = mac->mac_sc;
7998         int i;
7999
8000         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8001             ("%s:%d: fail", __func__, __LINE__));
8002
8003         bwn_mac_suspend(mac);
8004         for (i = 0; i < N(sc->sc_wmeParams); i++)
8005                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8006                     bwn_wme_shm_offsets[i]);
8007         bwn_mac_enable(mac);
8008 }
8009
8010 static void
8011 bwn_wme_loadparams(struct bwn_mac *mac,
8012     const struct wmeParams *p, uint16_t shm_offset)
8013 {
8014 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8015         struct bwn_softc *sc = mac->mac_sc;
8016         uint16_t params[BWN_NR_WMEPARAMS];
8017         int slot, tmp;
8018         unsigned int i;
8019
8020         slot = BWN_READ_2(mac, BWN_RNG) &
8021             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8022
8023         memset(&params, 0, sizeof(params));
8024
8025         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8026             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8027             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8028
8029         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8030         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8031         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8032         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8033         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8034         params[BWN_WMEPARAM_BSLOTS] = slot;
8035         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8036
8037         for (i = 0; i < N(params); i++) {
8038                 if (i == BWN_WMEPARAM_STATUS) {
8039                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8040                             shm_offset + (i * 2));
8041                         tmp |= 0x100;
8042                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8043                             tmp);
8044                 } else {
8045                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8046                             params[i]);
8047                 }
8048         }
8049 }
8050
8051 static void
8052 bwn_mac_write_bssid(struct bwn_mac *mac)
8053 {
8054         struct bwn_softc *sc = mac->mac_sc;
8055         uint32_t tmp;
8056         int i;
8057         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8058
8059         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8060         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8061         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8062             IEEE80211_ADDR_LEN);
8063
8064         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8065                 tmp = (uint32_t) (mac_bssid[i + 0]);
8066                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8067                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8068                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8069                 bwn_ram_write(mac, 0x20 + i, tmp);
8070         }
8071 }
8072
8073 static void
8074 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8075     const uint8_t *macaddr)
8076 {
8077         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8078         uint16_t data;
8079
8080         if (!mac)
8081                 macaddr = zero;
8082
8083         offset |= 0x0020;
8084         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8085
8086         data = macaddr[0];
8087         data |= macaddr[1] << 8;
8088         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8089         data = macaddr[2];
8090         data |= macaddr[3] << 8;
8091         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8092         data = macaddr[4];
8093         data |= macaddr[5] << 8;
8094         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8095 }
8096
8097 static void
8098 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8099     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8100 {
8101         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8102         uint8_t per_sta_keys_start = 8;
8103
8104         if (BWN_SEC_NEWAPI(mac))
8105                 per_sta_keys_start = 4;
8106
8107         KASSERT(index < mac->mac_max_nr_keys,
8108             ("%s:%d: fail", __func__, __LINE__));
8109         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8110             ("%s:%d: fail", __func__, __LINE__));
8111
8112         if (index >= per_sta_keys_start)
8113                 bwn_key_macwrite(mac, index, NULL);
8114         if (key)
8115                 memcpy(buf, key, key_len);
8116         bwn_key_write(mac, index, algorithm, buf);
8117         if (index >= per_sta_keys_start)
8118                 bwn_key_macwrite(mac, index, mac_addr);
8119
8120         mac->mac_key[index].algorithm = algorithm;
8121 }
8122
8123 static void
8124 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8125 {
8126         struct bwn_softc *sc = mac->mac_sc;
8127         uint32_t addrtmp[2] = { 0, 0 };
8128         uint8_t start = 8;
8129
8130         if (BWN_SEC_NEWAPI(mac))
8131                 start = 4;
8132
8133         KASSERT(index >= start,
8134             ("%s:%d: fail", __func__, __LINE__));
8135         index -= start;
8136
8137         if (addr) {
8138                 addrtmp[0] = addr[0];
8139                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8140                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8141                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8142                 addrtmp[1] = addr[4];
8143                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8144         }
8145
8146         if (siba_get_revid(sc->sc_dev) >= 5) {
8147                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8148                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8149         } else {
8150                 if (index >= 8) {
8151                         bwn_shm_write_4(mac, BWN_SHARED,
8152                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8153                         bwn_shm_write_2(mac, BWN_SHARED,
8154                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8155                 }
8156         }
8157 }
8158
8159 static void
8160 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8161     const uint8_t *key)
8162 {
8163         unsigned int i;
8164         uint32_t offset;
8165         uint16_t kidx, value;
8166
8167         kidx = BWN_SEC_KEY2FW(mac, index);
8168         bwn_shm_write_2(mac, BWN_SHARED,
8169             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8170
8171         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8172         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8173                 value = key[i];
8174                 value |= (uint16_t)(key[i + 1]) << 8;
8175                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8176         }
8177 }
8178
8179 static void
8180 bwn_phy_exit(struct bwn_mac *mac)
8181 {
8182
8183         mac->mac_phy.rf_onoff(mac, 0);
8184         if (mac->mac_phy.exit != NULL)
8185                 mac->mac_phy.exit(mac);
8186 }
8187
8188 static void
8189 bwn_dma_free(struct bwn_mac *mac)
8190 {
8191         struct bwn_dma *dma;
8192
8193         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8194                 return;
8195         dma = &mac->mac_method.dma;
8196
8197         bwn_dma_ringfree(&dma->rx);
8198         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8199         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8200         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8201         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8202         bwn_dma_ringfree(&dma->mcast);
8203 }
8204
8205 static void
8206 bwn_core_stop(struct bwn_mac *mac)
8207 {
8208         struct bwn_softc *sc = mac->mac_sc;
8209
8210         BWN_ASSERT_LOCKED(sc);
8211
8212         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8213                 return;
8214
8215         callout_stop(&sc->sc_rfswitch_ch);
8216         callout_stop(&sc->sc_task_ch);
8217         callout_stop(&sc->sc_watchdog_ch);
8218         sc->sc_watchdog_timer = 0;
8219         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8220         BWN_READ_4(mac, BWN_INTR_MASK);
8221         bwn_mac_suspend(mac);
8222
8223         mac->mac_status = BWN_MAC_STATUS_INITED;
8224 }
8225
8226 static int
8227 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8228 {
8229         struct bwn_mac *up_dev = NULL;
8230         struct bwn_mac *down_dev;
8231         struct bwn_mac *mac;
8232         int err, status;
8233         uint8_t gmode;
8234
8235         BWN_ASSERT_LOCKED(sc);
8236
8237         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8238                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8239                     mac->mac_phy.supports_2ghz) {
8240                         up_dev = mac;
8241                         gmode = 1;
8242                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8243                     mac->mac_phy.supports_5ghz) {
8244                         up_dev = mac;
8245                         gmode = 0;
8246                 } else {
8247                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8248                         return (EINVAL);
8249                 }
8250                 if (up_dev != NULL)
8251                         break;
8252         }
8253         if (up_dev == NULL) {
8254                 device_printf(sc->sc_dev, "Could not find a device\n");
8255                 return (ENODEV);
8256         }
8257         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8258                 return (0);
8259
8260         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8261             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8262
8263         down_dev = sc->sc_curmac;;
8264         status = down_dev->mac_status;
8265         if (status >= BWN_MAC_STATUS_STARTED)
8266                 bwn_core_stop(down_dev);
8267         if (status >= BWN_MAC_STATUS_INITED)
8268                 bwn_core_exit(down_dev);
8269
8270         if (down_dev != up_dev)
8271                 bwn_phy_reset(down_dev);
8272
8273         up_dev->mac_phy.gmode = gmode;
8274         if (status >= BWN_MAC_STATUS_INITED) {
8275                 err = bwn_core_init(up_dev);
8276                 if (err) {
8277                         device_printf(sc->sc_dev,
8278                             "fatal: failed to initialize for %s-GHz\n",
8279                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8280                         goto fail;
8281                 }
8282         }
8283         if (status >= BWN_MAC_STATUS_STARTED)
8284                 bwn_core_start(up_dev);
8285         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8286         sc->sc_curmac = up_dev;
8287
8288         return (0);
8289 fail:
8290         sc->sc_curmac = NULL;
8291         return (err);
8292 }
8293
8294 static void
8295 bwn_rf_turnon(struct bwn_mac *mac)
8296 {
8297
8298         bwn_mac_suspend(mac);
8299         mac->mac_phy.rf_onoff(mac, 1);
8300         mac->mac_phy.rf_on = 1;
8301         bwn_mac_enable(mac);
8302 }
8303
8304 static void
8305 bwn_rf_turnoff(struct bwn_mac *mac)
8306 {
8307
8308         bwn_mac_suspend(mac);
8309         mac->mac_phy.rf_onoff(mac, 0);
8310         mac->mac_phy.rf_on = 0;
8311         bwn_mac_enable(mac);
8312 }
8313
8314 static void
8315 bwn_phy_reset(struct bwn_mac *mac)
8316 {
8317         struct bwn_softc *sc = mac->mac_sc;
8318
8319         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8320             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8321              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8322         DELAY(1000);
8323         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8324             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8325             BWN_TGSLOW_PHYRESET);
8326         DELAY(1000);
8327 }
8328
8329 static int
8330 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8331 {
8332         const struct ieee80211_txparam *tp;
8333         struct bwn_vap *bvp = BWN_VAP(vap);
8334         struct ieee80211com *ic= vap->iv_ic;
8335         struct ifnet *ifp = ic->ic_ifp;
8336         enum ieee80211_state ostate = vap->iv_state;
8337         struct bwn_softc *sc = ifp->if_softc;
8338         struct bwn_mac *mac = sc->sc_curmac;
8339         int error;
8340
8341         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8342             ieee80211_state_name[vap->iv_state],
8343             ieee80211_state_name[nstate]);
8344
8345         error = bvp->bv_newstate(vap, nstate, arg);
8346         if (error != 0)
8347                 return (error);
8348
8349         BWN_LOCK(sc);
8350
8351         bwn_led_newstate(mac, nstate);
8352
8353         /*
8354          * Clear the BSSID when we stop a STA
8355          */
8356         if (vap->iv_opmode == IEEE80211_M_STA) {
8357                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8358                         /*
8359                          * Clear out the BSSID.  If we reassociate to
8360                          * the same AP, this will reinialize things
8361                          * correctly...
8362                          */
8363                         if (ic->ic_opmode == IEEE80211_M_STA &&
8364                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8365                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8366                                 bwn_set_macaddr(mac);
8367                         }
8368                 }
8369         }
8370
8371         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8372             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8373                 /* XXX nothing to do? */
8374         } else if (nstate == IEEE80211_S_RUN) {
8375                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8376                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8377                 bwn_set_opmode(mac);
8378                 bwn_set_pretbtt(mac);
8379                 bwn_spu_setdelay(mac, 0);
8380                 bwn_set_macaddr(mac);
8381
8382                 /* Initializes ratectl for a node. */
8383                 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
8384                 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
8385                         ieee80211_ratectl_node_init(vap->iv_bss);
8386         }
8387
8388         BWN_UNLOCK(sc);
8389
8390         return (error);
8391 }
8392
8393 static void
8394 bwn_set_pretbtt(struct bwn_mac *mac)
8395 {
8396         struct bwn_softc *sc = mac->mac_sc;
8397         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8398         uint16_t pretbtt;
8399
8400         if (ic->ic_opmode == IEEE80211_M_IBSS)
8401                 pretbtt = 2;
8402         else
8403                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8404         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8405         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8406 }
8407
8408 static int
8409 bwn_intr(void *arg)
8410 {
8411         struct bwn_mac *mac = arg;
8412         struct bwn_softc *sc = mac->mac_sc;
8413         uint32_t reason;
8414
8415         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8416             (sc->sc_flags & BWN_FLAG_INVALID))
8417                 return (FILTER_STRAY);
8418
8419         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8420         if (reason == 0xffffffff)       /* shared IRQ */
8421                 return (FILTER_STRAY);
8422         reason &= mac->mac_intr_mask;
8423         if (reason == 0)
8424                 return (FILTER_HANDLED);
8425
8426         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8427         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8428         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8429         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8430         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8431         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8432         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8433         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8434         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8435         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8436         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8437
8438         /* Disable interrupts. */
8439         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8440
8441         mac->mac_reason_intr = reason;
8442
8443         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8445
8446         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8447         return (FILTER_HANDLED);
8448 }
8449
8450 static void
8451 bwn_intrtask(void *arg, int npending)
8452 {
8453         struct bwn_mac *mac = arg;
8454         struct bwn_softc *sc = mac->mac_sc;
8455         struct ifnet *ifp = sc->sc_ifp;
8456         uint32_t merged = 0;
8457         int i, tx = 0, rx = 0;
8458
8459         BWN_LOCK(sc);
8460         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8461             (sc->sc_flags & BWN_FLAG_INVALID)) {
8462                 BWN_UNLOCK(sc);
8463                 return;
8464         }
8465
8466         for (i = 0; i < N(mac->mac_reason); i++)
8467                 merged |= mac->mac_reason[i];
8468
8469         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8470                 device_printf(sc->sc_dev, "MAC trans error\n");
8471
8472         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8473                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8474                 mac->mac_phy.txerrors--;
8475                 if (mac->mac_phy.txerrors == 0) {
8476                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8477                         bwn_restart(mac, "PHY TX errors");
8478                 }
8479         }
8480
8481         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8482                 if (merged & BWN_DMAINTR_FATALMASK) {
8483                         device_printf(sc->sc_dev,
8484                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8485                             mac->mac_reason[0], mac->mac_reason[1],
8486                             mac->mac_reason[2], mac->mac_reason[3],
8487                             mac->mac_reason[4], mac->mac_reason[5]);
8488                         bwn_restart(mac, "DMA error");
8489                         BWN_UNLOCK(sc);
8490                         return;
8491                 }
8492                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8493                         device_printf(sc->sc_dev,
8494                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8495                             mac->mac_reason[0], mac->mac_reason[1],
8496                             mac->mac_reason[2], mac->mac_reason[3],
8497                             mac->mac_reason[4], mac->mac_reason[5]);
8498                 }
8499         }
8500
8501         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8502                 bwn_intr_ucode_debug(mac);
8503         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8504                 bwn_intr_tbtt_indication(mac);
8505         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8506                 bwn_intr_atim_end(mac);
8507         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8508                 bwn_intr_beacon(mac);
8509         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8510                 bwn_intr_pmq(mac);
8511         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8512                 bwn_intr_noise(mac);
8513
8514         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8515                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8516                         bwn_dma_rx(mac->mac_method.dma.rx);
8517                         rx = 1;
8518                 }
8519         } else
8520                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8521
8522         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8523         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8524         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8525         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8526         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8527
8528         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8529                 bwn_intr_txeof(mac);
8530                 tx = 1;
8531         }
8532
8533         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8534
8535         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8536                 int evt = BWN_LED_EVENT_NONE;
8537
8538                 if (tx && rx) {
8539                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8540                                 evt = BWN_LED_EVENT_RX;
8541                         else
8542                                 evt = BWN_LED_EVENT_TX;
8543                 } else if (tx) {
8544                         evt = BWN_LED_EVENT_TX;
8545                 } else if (rx) {
8546                         evt = BWN_LED_EVENT_RX;
8547                 } else if (rx == 0) {
8548                         evt = BWN_LED_EVENT_POLL;
8549                 }
8550
8551                 if (evt != BWN_LED_EVENT_NONE)
8552                         bwn_led_event(mac, evt);
8553        }
8554
8555         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8556                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8557                         bwn_start_locked(ifp);
8558         }
8559
8560         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8561         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8562
8563         BWN_UNLOCK(sc);
8564 }
8565
8566 static void
8567 bwn_restart(struct bwn_mac *mac, const char *msg)
8568 {
8569         struct bwn_softc *sc = mac->mac_sc;
8570         struct ifnet *ifp = sc->sc_ifp;
8571         struct ieee80211com *ic = ifp->if_l2com;
8572
8573         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8574                 return;
8575
8576         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8577         ieee80211_runtask(ic, &mac->mac_hwreset);
8578 }
8579
8580 static void
8581 bwn_intr_ucode_debug(struct bwn_mac *mac)
8582 {
8583         struct bwn_softc *sc = mac->mac_sc;
8584         uint16_t reason;
8585
8586         if (mac->mac_fw.opensource == 0)
8587                 return;
8588
8589         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8590         switch (reason) {
8591         case BWN_DEBUGINTR_PANIC:
8592                 bwn_handle_fwpanic(mac);
8593                 break;
8594         case BWN_DEBUGINTR_DUMP_SHM:
8595                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8596                 break;
8597         case BWN_DEBUGINTR_DUMP_REGS:
8598                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8599                 break;
8600         case BWN_DEBUGINTR_MARKER:
8601                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8602                 break;
8603         default:
8604                 device_printf(sc->sc_dev,
8605                     "ucode debug unknown reason: %#x\n", reason);
8606         }
8607
8608         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8609             BWN_DEBUGINTR_ACK);
8610 }
8611
8612 static void
8613 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8614 {
8615         struct bwn_softc *sc = mac->mac_sc;
8616         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8617
8618         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8619                 bwn_psctl(mac, 0);
8620         if (ic->ic_opmode == IEEE80211_M_IBSS)
8621                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8622 }
8623
8624 static void
8625 bwn_intr_atim_end(struct bwn_mac *mac)
8626 {
8627
8628         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8629                 BWN_WRITE_4(mac, BWN_MACCMD,
8630                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8631                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8632         }
8633 }
8634
8635 static void
8636 bwn_intr_beacon(struct bwn_mac *mac)
8637 {
8638         struct bwn_softc *sc = mac->mac_sc;
8639         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8640         uint32_t cmd, beacon0, beacon1;
8641
8642         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8643             ic->ic_opmode == IEEE80211_M_MBSS)
8644                 return;
8645
8646         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8647
8648         cmd = BWN_READ_4(mac, BWN_MACCMD);
8649         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8650         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8651
8652         if (beacon0 && beacon1) {
8653                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8654                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8655                 return;
8656         }
8657
8658         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8659                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8660                 bwn_load_beacon0(mac);
8661                 bwn_load_beacon1(mac);
8662                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8663                 cmd |= BWN_MACCMD_BEACON0_VALID;
8664                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8665         } else {
8666                 if (!beacon0) {
8667                         bwn_load_beacon0(mac);
8668                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8669                         cmd |= BWN_MACCMD_BEACON0_VALID;
8670                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8671                 } else if (!beacon1) {
8672                         bwn_load_beacon1(mac);
8673                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8674                         cmd |= BWN_MACCMD_BEACON1_VALID;
8675                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8676                 }
8677         }
8678 }
8679
8680 static void
8681 bwn_intr_pmq(struct bwn_mac *mac)
8682 {
8683         uint32_t tmp;
8684
8685         while (1) {
8686                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8687                 if (!(tmp & 0x00000008))
8688                         break;
8689         }
8690         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8691 }
8692
8693 static void
8694 bwn_intr_noise(struct bwn_mac *mac)
8695 {
8696         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8697         uint16_t tmp;
8698         uint8_t noise[4];
8699         uint8_t i, j;
8700         int32_t average;
8701
8702         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8703                 return;
8704
8705         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8706         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8707         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8708             noise[3] == 0x7f)
8709                 goto new;
8710
8711         KASSERT(mac->mac_noise.noi_nsamples < 8,
8712             ("%s:%d: fail", __func__, __LINE__));
8713         i = mac->mac_noise.noi_nsamples;
8714         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8715         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8716         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8717         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8718         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8719         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8720         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8721         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8722         mac->mac_noise.noi_nsamples++;
8723         if (mac->mac_noise.noi_nsamples == 8) {
8724                 average = 0;
8725                 for (i = 0; i < 8; i++) {
8726                         for (j = 0; j < 4; j++)
8727                                 average += mac->mac_noise.noi_samples[i][j];
8728                 }
8729                 average = (((average / 32) * 125) + 64) / 128;
8730                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8731                 if (tmp >= 8)
8732                         average += 2;
8733                 else
8734                         average -= 25;
8735                 average -= (tmp == 8) ? 72 : 48;
8736
8737                 mac->mac_stats.link_noise = average;
8738                 mac->mac_noise.noi_running = 0;
8739                 return;
8740         }
8741 new:
8742         bwn_noise_gensample(mac);
8743 }
8744
8745 static int
8746 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8747 {
8748         struct bwn_mac *mac = prq->prq_mac;
8749         struct bwn_softc *sc = mac->mac_sc;
8750         unsigned int i;
8751
8752         BWN_ASSERT_LOCKED(sc);
8753
8754         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8755                 return (0);
8756
8757         for (i = 0; i < 5000; i++) {
8758                 if (bwn_pio_rxeof(prq) == 0)
8759                         break;
8760         }
8761         if (i >= 5000)
8762                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8763         return ((i > 0) ? 1 : 0);
8764 }
8765
8766 static void
8767 bwn_dma_rx(struct bwn_dma_ring *dr)
8768 {
8769         int slot, curslot;
8770
8771         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8772         curslot = dr->get_curslot(dr);
8773         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8774             ("%s:%d: fail", __func__, __LINE__));
8775
8776         slot = dr->dr_curslot;
8777         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8778                 bwn_dma_rxeof(dr, &slot);
8779
8780         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8781             BUS_DMASYNC_PREWRITE);
8782
8783         dr->set_curslot(dr, slot);
8784         dr->dr_curslot = slot;
8785 }
8786
8787 static void
8788 bwn_intr_txeof(struct bwn_mac *mac)
8789 {
8790         struct bwn_txstatus stat;
8791         uint32_t stat0, stat1;
8792         uint16_t tmp;
8793
8794         BWN_ASSERT_LOCKED(mac->mac_sc);
8795
8796         while (1) {
8797                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8798                 if (!(stat0 & 0x00000001))
8799                         break;
8800                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8801
8802                 stat.cookie = (stat0 >> 16);
8803                 stat.seq = (stat1 & 0x0000ffff);
8804                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8805                 tmp = (stat0 & 0x0000ffff);
8806                 stat.framecnt = ((tmp & 0xf000) >> 12);
8807                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8808                 stat.sreason = ((tmp & 0x001c) >> 2);
8809                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8810                 stat.im = (tmp & 0x0040) ? 1 : 0;
8811                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8812                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8813
8814                 bwn_handle_txeof(mac, &stat);
8815         }
8816 }
8817
8818 static void
8819 bwn_hwreset(void *arg, int npending)
8820 {
8821         struct bwn_mac *mac = arg;
8822         struct bwn_softc *sc = mac->mac_sc;
8823         int error = 0;
8824         int prev_status;
8825
8826         BWN_LOCK(sc);
8827
8828         prev_status = mac->mac_status;
8829         if (prev_status >= BWN_MAC_STATUS_STARTED)
8830                 bwn_core_stop(mac);
8831         if (prev_status >= BWN_MAC_STATUS_INITED)
8832                 bwn_core_exit(mac);
8833
8834         if (prev_status >= BWN_MAC_STATUS_INITED) {
8835                 error = bwn_core_init(mac);
8836                 if (error)
8837                         goto out;
8838         }
8839         if (prev_status >= BWN_MAC_STATUS_STARTED)
8840                 bwn_core_start(mac);
8841 out:
8842         if (error) {
8843                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8844                 sc->sc_curmac = NULL;
8845         }
8846         BWN_UNLOCK(sc);
8847 }
8848
8849 static void
8850 bwn_handle_fwpanic(struct bwn_mac *mac)
8851 {
8852         struct bwn_softc *sc = mac->mac_sc;
8853         uint16_t reason;
8854
8855         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8856         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8857
8858         if (reason == BWN_FWPANIC_RESTART)
8859                 bwn_restart(mac, "ucode panic");
8860 }
8861
8862 static void
8863 bwn_load_beacon0(struct bwn_mac *mac)
8864 {
8865
8866         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8867 }
8868
8869 static void
8870 bwn_load_beacon1(struct bwn_mac *mac)
8871 {
8872
8873         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8874 }
8875
8876 static uint32_t
8877 bwn_jssi_read(struct bwn_mac *mac)
8878 {
8879         uint32_t val = 0;
8880
8881         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8882         val <<= 16;
8883         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8884
8885         return (val);
8886 }
8887
8888 static void
8889 bwn_noise_gensample(struct bwn_mac *mac)
8890 {
8891         uint32_t jssi = 0x7f7f7f7f;
8892
8893         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8894         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8895         BWN_WRITE_4(mac, BWN_MACCMD,
8896             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8897 }
8898
8899 static int
8900 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8901 {
8902         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8903
8904         return (dr->dr_numslots - dr->dr_usedslot);
8905 }
8906
8907 static int
8908 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8909 {
8910         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8911
8912         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8913             ("%s:%d: fail", __func__, __LINE__));
8914         if (slot == dr->dr_numslots - 1)
8915                 return (0);
8916         return (slot + 1);
8917 }
8918
8919 static void
8920 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8921 {
8922         struct bwn_mac *mac = dr->dr_mac;
8923         struct bwn_softc *sc = mac->mac_sc;
8924         struct bwn_dma *dma = &mac->mac_method.dma;
8925         struct bwn_dmadesc_generic *desc;
8926         struct bwn_dmadesc_meta *meta;
8927         struct bwn_rxhdr4 *rxhdr;
8928         struct ifnet *ifp = sc->sc_ifp;
8929         struct mbuf *m;
8930         uint32_t macstat;
8931         int32_t tmp;
8932         int cnt = 0;
8933         uint16_t len;
8934
8935         dr->getdesc(dr, *slot, &desc, &meta);
8936
8937         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8938         m = meta->mt_m;
8939
8940         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8941                 ifp->if_ierrors++;
8942                 return;
8943         }
8944
8945         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8946         len = le16toh(rxhdr->frame_len);
8947         if (len <= 0) {
8948                 ifp->if_ierrors++;
8949                 return;
8950         }
8951         if (bwn_dma_check_redzone(dr, m)) {
8952                 device_printf(sc->sc_dev, "redzone error.\n");
8953                 bwn_dma_set_redzone(dr, m);
8954                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8955                     BUS_DMASYNC_PREWRITE);
8956                 return;
8957         }
8958         if (len > dr->dr_rx_bufsize) {
8959                 tmp = len;
8960                 while (1) {
8961                         dr->getdesc(dr, *slot, &desc, &meta);
8962                         bwn_dma_set_redzone(dr, meta->mt_m);
8963                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8964                             BUS_DMASYNC_PREWRITE);
8965                         *slot = bwn_dma_nextslot(dr, *slot);
8966                         cnt++;
8967                         tmp -= dr->dr_rx_bufsize;
8968                         if (tmp <= 0)
8969                                 break;
8970                 }
8971                 device_printf(sc->sc_dev, "too small buffer "
8972                        "(len %u buffer %u dropped %d)\n",
8973                        len, dr->dr_rx_bufsize, cnt);
8974                 return;
8975         }
8976         macstat = le32toh(rxhdr->mac_status);
8977         if (macstat & BWN_RX_MAC_FCSERR) {
8978                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8979                         device_printf(sc->sc_dev, "RX drop\n");
8980                         return;
8981                 }
8982         }
8983
8984         m->m_pkthdr.rcvif = ifp;
8985         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8986         m_adj(m, dr->dr_frameoffset);
8987
8988         bwn_rxeof(dr->dr_mac, m, rxhdr);
8989 }
8990
8991 static void
8992 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8993 {
8994         struct bwn_dma_ring *dr;
8995         struct bwn_dmadesc_generic *desc;
8996         struct bwn_dmadesc_meta *meta;
8997         struct bwn_pio_txqueue *tq;
8998         struct bwn_pio_txpkt *tp = NULL;
8999         struct bwn_softc *sc = mac->mac_sc;
9000         struct bwn_stats *stats = &mac->mac_stats;
9001         struct ieee80211_node *ni;
9002         struct ieee80211vap *vap;
9003         int retrycnt = 0, slot;
9004
9005         BWN_ASSERT_LOCKED(mac->mac_sc);
9006
9007         if (status->im)
9008                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9009         if (status->ampdu)
9010                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9011         if (status->rtscnt) {
9012                 if (status->rtscnt == 0xf)
9013                         stats->rtsfail++;
9014                 else
9015                         stats->rts++;
9016         }
9017
9018         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9019                 if (status->ack) {
9020                         dr = bwn_dma_parse_cookie(mac, status,
9021                             status->cookie, &slot);
9022                         if (dr == NULL) {
9023                                 device_printf(sc->sc_dev,
9024                                     "failed to parse cookie\n");
9025                                 return;
9026                         }
9027                         while (1) {
9028                                 dr->getdesc(dr, slot, &desc, &meta);
9029                                 if (meta->mt_islast) {
9030                                         ni = meta->mt_ni;
9031                                         vap = ni->ni_vap;
9032                                         ieee80211_ratectl_tx_complete(vap, ni,
9033                                             status->ack ?
9034                                               IEEE80211_RATECTL_TX_SUCCESS :
9035                                               IEEE80211_RATECTL_TX_FAILURE,
9036                                             &retrycnt, 0);
9037                                         break;
9038                                 }
9039                                 slot = bwn_dma_nextslot(dr, slot);
9040                         }
9041                 }
9042                 bwn_dma_handle_txeof(mac, status);
9043         } else {
9044                 if (status->ack) {
9045                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9046                         if (tq == NULL) {
9047                                 device_printf(sc->sc_dev,
9048                                     "failed to parse cookie\n");
9049                                 return;
9050                         }
9051                         ni = tp->tp_ni;
9052                         vap = ni->ni_vap;
9053                         ieee80211_ratectl_tx_complete(vap, ni,
9054                             status->ack ?
9055                               IEEE80211_RATECTL_TX_SUCCESS :
9056                               IEEE80211_RATECTL_TX_FAILURE,
9057                             &retrycnt, 0);
9058                 }
9059                 bwn_pio_handle_txeof(mac, status);
9060         }
9061
9062         bwn_phy_txpower_check(mac, 0);
9063 }
9064
9065 static uint8_t
9066 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9067 {
9068         struct bwn_mac *mac = prq->prq_mac;
9069         struct bwn_softc *sc = mac->mac_sc;
9070         struct bwn_rxhdr4 rxhdr;
9071         struct ifnet *ifp = sc->sc_ifp;
9072         struct mbuf *m;
9073         uint32_t ctl32, macstat, v32;
9074         unsigned int i, padding;
9075         uint16_t ctl16, len, totlen, v16;
9076         unsigned char *mp;
9077         char *data;
9078
9079         memset(&rxhdr, 0, sizeof(rxhdr));
9080
9081         if (prq->prq_rev >= 8) {
9082                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9083                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9084                         return (0);
9085                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9086                     BWN_PIO8_RXCTL_FRAMEREADY);
9087                 for (i = 0; i < 10; i++) {
9088                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9089                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9090                                 goto ready;
9091                         DELAY(10);
9092                 }
9093         } else {
9094                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9095                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9096                         return (0);
9097                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9098                     BWN_PIO_RXCTL_FRAMEREADY);
9099                 for (i = 0; i < 10; i++) {
9100                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9101                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9102                                 goto ready;
9103                         DELAY(10);
9104                 }
9105         }
9106         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9107         return (1);
9108 ready:
9109         if (prq->prq_rev >= 8)
9110                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9111                     prq->prq_base + BWN_PIO8_RXDATA);
9112         else
9113                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9114                     prq->prq_base + BWN_PIO_RXDATA);
9115         len = le16toh(rxhdr.frame_len);
9116         if (len > 0x700) {
9117                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9118                 goto error;
9119         }
9120         if (len == 0) {
9121                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9122                 goto error;
9123         }
9124
9125         macstat = le32toh(rxhdr.mac_status);
9126         if (macstat & BWN_RX_MAC_FCSERR) {
9127                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9128                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9129                         goto error;
9130                 }
9131         }
9132
9133         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9134         totlen = len + padding;
9135         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9136         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9137         if (m == NULL) {
9138                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9139                 goto error;
9140         }
9141         mp = mtod(m, unsigned char *);
9142         if (prq->prq_rev >= 8) {
9143                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9144                     prq->prq_base + BWN_PIO8_RXDATA);
9145                 if (totlen & 3) {
9146                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9147                         data = &(mp[totlen - 1]);
9148                         switch (totlen & 3) {
9149                         case 3:
9150                                 *data = (v32 >> 16);
9151                                 data--;
9152                         case 2:
9153                                 *data = (v32 >> 8);
9154                                 data--;
9155                         case 1:
9156                                 *data = v32;
9157                         }
9158                 }
9159         } else {
9160                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9161                     prq->prq_base + BWN_PIO_RXDATA);
9162                 if (totlen & 1) {
9163                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9164                         mp[totlen - 1] = v16;
9165                 }
9166         }
9167
9168         m->m_pkthdr.rcvif = ifp;
9169         m->m_len = m->m_pkthdr.len = totlen;
9170
9171         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9172
9173         return (1);
9174 error:
9175         if (prq->prq_rev >= 8)
9176                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9177                     BWN_PIO8_RXCTL_DATAREADY);
9178         else
9179                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9180         return (1);
9181 }
9182
9183 static int
9184 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9185     struct bwn_dmadesc_meta *meta, int init)
9186 {
9187         struct bwn_mac *mac = dr->dr_mac;
9188         struct bwn_dma *dma = &mac->mac_method.dma;
9189         struct bwn_rxhdr4 *hdr;
9190         bus_dmamap_t map;
9191         bus_addr_t paddr;
9192         struct mbuf *m;
9193         int error;
9194
9195         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9196         if (m == NULL) {
9197                 error = ENOBUFS;
9198
9199                 /*
9200                  * If the NIC is up and running, we need to:
9201                  * - Clear RX buffer's header.
9202                  * - Restore RX descriptor settings.
9203                  */
9204                 if (init)
9205                         return (error);
9206                 else
9207                         goto back;
9208         }
9209         m->m_len = m->m_pkthdr.len = MCLBYTES;
9210
9211         bwn_dma_set_redzone(dr, m);
9212
9213         /*
9214          * Try to load RX buf into temporary DMA map
9215          */
9216         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9217             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9218         if (error) {
9219                 m_freem(m);
9220
9221                 /*
9222                  * See the comment above
9223                  */
9224                 if (init)
9225                         return (error);
9226                 else
9227                         goto back;
9228         }
9229
9230         if (!init)
9231                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9232         meta->mt_m = m;
9233         meta->mt_paddr = paddr;
9234
9235         /*
9236          * Swap RX buf's DMA map with the loaded temporary one
9237          */
9238         map = meta->mt_dmap;
9239         meta->mt_dmap = dr->dr_spare_dmap;
9240         dr->dr_spare_dmap = map;
9241
9242 back:
9243         /*
9244          * Clear RX buf header
9245          */
9246         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9247         bzero(hdr, sizeof(*hdr));
9248         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9249             BUS_DMASYNC_PREWRITE);
9250
9251         /*
9252          * Setup RX buf descriptor
9253          */
9254         dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9255             sizeof(*hdr), 0, 0, 0);
9256         return (error);
9257 }
9258
9259 static void
9260 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9261                  bus_size_t mapsz __unused, int error)
9262 {
9263
9264         if (!error) {
9265                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9266                 *((bus_addr_t *)arg) = seg->ds_addr;
9267         }
9268 }
9269
9270 static int
9271 bwn_hwrate2ieeerate(int rate)
9272 {
9273
9274         switch (rate) {
9275         case BWN_CCK_RATE_1MB:
9276                 return (2);
9277         case BWN_CCK_RATE_2MB:
9278                 return (4);
9279         case BWN_CCK_RATE_5MB:
9280                 return (11);
9281         case BWN_CCK_RATE_11MB:
9282                 return (22);
9283         case BWN_OFDM_RATE_6MB:
9284                 return (12);
9285         case BWN_OFDM_RATE_9MB:
9286                 return (18);
9287         case BWN_OFDM_RATE_12MB:
9288                 return (24);
9289         case BWN_OFDM_RATE_18MB:
9290                 return (36);
9291         case BWN_OFDM_RATE_24MB:
9292                 return (48);
9293         case BWN_OFDM_RATE_36MB:
9294                 return (72);
9295         case BWN_OFDM_RATE_48MB:
9296                 return (96);
9297         case BWN_OFDM_RATE_54MB:
9298                 return (108);
9299         default:
9300                 printf("Ooops\n");
9301                 return (0);
9302         }
9303 }
9304
9305 static void
9306 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9307 {
9308         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9309         struct bwn_plcp6 *plcp;
9310         struct bwn_softc *sc = mac->mac_sc;
9311         struct ieee80211_frame_min *wh;
9312         struct ieee80211_node *ni;
9313         struct ifnet *ifp = sc->sc_ifp;
9314         struct ieee80211com *ic = ifp->if_l2com;
9315         uint32_t macstat;
9316         int padding, rate, rssi = 0, noise = 0, type;
9317         uint16_t phytype, phystat0, phystat3, chanstat;
9318         unsigned char *mp = mtod(m, unsigned char *);
9319         static int rx_mac_dec_rpt = 0;
9320
9321         BWN_ASSERT_LOCKED(sc);
9322
9323         phystat0 = le16toh(rxhdr->phy_status0);
9324         phystat3 = le16toh(rxhdr->phy_status3);
9325         macstat = le32toh(rxhdr->mac_status);
9326         chanstat = le16toh(rxhdr->channel);
9327         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9328
9329         if (macstat & BWN_RX_MAC_FCSERR)
9330                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9331         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9332                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9333         if (macstat & BWN_RX_MAC_DECERR)
9334                 goto drop;
9335
9336         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9337         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9338                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9339                     m->m_pkthdr.len);
9340                 goto drop;
9341         }
9342         plcp = (struct bwn_plcp6 *)(mp + padding);
9343         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9344         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9345                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9346                     m->m_pkthdr.len);
9347                 goto drop;
9348         }
9349         wh = mtod(m, struct ieee80211_frame_min *);
9350
9351         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9352                 device_printf(sc->sc_dev,
9353                     "RX decryption attempted (old %d keyidx %#x)\n",
9354                     BWN_ISOLDFMT(mac),
9355                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9356
9357         /* XXX calculating RSSI & noise & antenna */
9358
9359         if (phystat0 & BWN_RX_PHYST0_OFDM)
9360                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9361                     phytype == BWN_PHYTYPE_A);
9362         else
9363                 rate = bwn_plcp_get_cckrate(mac, plcp);
9364         if (rate == -1) {
9365                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9366                         goto drop;
9367         }
9368         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9369
9370         /* RX radio tap */
9371         if (ieee80211_radiotap_active(ic))
9372                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9373         m_adj(m, -IEEE80211_CRC_LEN);
9374
9375         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9376         noise = mac->mac_stats.link_noise;
9377
9378         ifp->if_ipackets++;
9379
9380         BWN_UNLOCK(sc);
9381
9382         ni = ieee80211_find_rxnode(ic, wh);
9383         if (ni != NULL) {
9384                 type = ieee80211_input(ni, m, rssi, noise);
9385                 ieee80211_free_node(ni);
9386         } else
9387                 type = ieee80211_input_all(ic, m, rssi, noise);
9388
9389         BWN_LOCK(sc);
9390         return;
9391 drop:
9392         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9393 }
9394
9395 static void
9396 bwn_dma_handle_txeof(struct bwn_mac *mac,
9397     const struct bwn_txstatus *status)
9398 {
9399         struct bwn_dma *dma = &mac->mac_method.dma;
9400         struct bwn_dma_ring *dr;
9401         struct bwn_dmadesc_generic *desc;
9402         struct bwn_dmadesc_meta *meta;
9403         struct bwn_softc *sc = mac->mac_sc;
9404         struct ieee80211_node *ni;
9405         struct ifnet *ifp = sc->sc_ifp;
9406         struct mbuf *m;
9407         int slot;
9408
9409         BWN_ASSERT_LOCKED(sc);
9410
9411         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9412         if (dr == NULL) {
9413                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9414                 return;
9415         }
9416         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9417
9418         while (1) {
9419                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9420                     ("%s:%d: fail", __func__, __LINE__));
9421                 dr->getdesc(dr, slot, &desc, &meta);
9422
9423                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9424                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9425                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9426                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9427
9428                 if (meta->mt_islast) {
9429                         KASSERT(meta->mt_m != NULL,
9430                             ("%s:%d: fail", __func__, __LINE__));
9431
9432                         ni = meta->mt_ni;
9433                         m = meta->mt_m;
9434                         if (ni != NULL) {
9435                                 /*
9436                                  * Do any tx complete callback. Note this must
9437                                  * be done before releasing the node reference.
9438                                  */
9439                                 if (m->m_flags & M_TXCB)
9440                                         ieee80211_process_callback(ni, m, 0);
9441                                 ieee80211_free_node(ni);
9442                                 meta->mt_ni = NULL;
9443                         }
9444                         m_freem(m);
9445                         meta->mt_m = NULL;
9446                 } else {
9447                         KASSERT(meta->mt_m == NULL,
9448                             ("%s:%d: fail", __func__, __LINE__));
9449                 }
9450
9451                 dr->dr_usedslot--;
9452                 if (meta->mt_islast) {
9453                         ifp->if_opackets++;
9454                         break;
9455                 }
9456                 slot = bwn_dma_nextslot(dr, slot);
9457         }
9458         sc->sc_watchdog_timer = 0;
9459         if (dr->dr_stop) {
9460                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9461                     ("%s:%d: fail", __func__, __LINE__));
9462                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9463                 dr->dr_stop = 0;
9464         }
9465 }
9466
9467 static void
9468 bwn_pio_handle_txeof(struct bwn_mac *mac,
9469     const struct bwn_txstatus *status)
9470 {
9471         struct bwn_pio_txqueue *tq;
9472         struct bwn_pio_txpkt *tp = NULL;
9473         struct bwn_softc *sc = mac->mac_sc;
9474         struct ifnet *ifp = sc->sc_ifp;
9475
9476         BWN_ASSERT_LOCKED(sc);
9477
9478         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9479         if (tq == NULL)
9480                 return;
9481
9482         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9483         tq->tq_free++;
9484
9485         if (tp->tp_ni != NULL) {
9486                 /*
9487                  * Do any tx complete callback.  Note this must
9488                  * be done before releasing the node reference.
9489                  */
9490                 if (tp->tp_m->m_flags & M_TXCB)
9491                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9492                 ieee80211_free_node(tp->tp_ni);
9493                 tp->tp_ni = NULL;
9494         }
9495         m_freem(tp->tp_m);
9496         tp->tp_m = NULL;
9497         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9498
9499         ifp->if_opackets++;
9500
9501         sc->sc_watchdog_timer = 0;
9502         if (tq->tq_stop) {
9503                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9504                 tq->tq_stop = 0;
9505         }
9506 }
9507
9508 static void
9509 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9510 {
9511         struct bwn_softc *sc = mac->mac_sc;
9512         struct bwn_phy *phy = &mac->mac_phy;
9513         struct ifnet *ifp = sc->sc_ifp;
9514         struct ieee80211com *ic = ifp->if_l2com;
9515         unsigned long now;
9516         int result;
9517
9518         BWN_GETTIME(now);
9519
9520         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9521                 return;
9522         phy->nexttime = now + 2 * 1000;
9523
9524         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9525             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9526                 return;
9527
9528         if (phy->recalc_txpwr != NULL) {
9529                 result = phy->recalc_txpwr(mac,
9530                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9531                 if (result == BWN_TXPWR_RES_DONE)
9532                         return;
9533                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9534                     ("%s: fail", __func__));
9535                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9536
9537                 ieee80211_runtask(ic, &mac->mac_txpower);
9538         }
9539 }
9540
9541 static uint16_t
9542 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9543 {
9544
9545         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9546 }
9547
9548 static uint32_t
9549 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9550 {
9551
9552         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9553 }
9554
9555 static void
9556 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9557 {
9558
9559         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9560 }
9561
9562 static void
9563 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9564 {
9565
9566         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9567 }
9568
9569 static int
9570 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9571 {
9572
9573         switch (rate) {
9574         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9575         case 12:
9576                 return (BWN_OFDM_RATE_6MB);
9577         case 18:
9578                 return (BWN_OFDM_RATE_9MB);
9579         case 24:
9580                 return (BWN_OFDM_RATE_12MB);
9581         case 36:
9582                 return (BWN_OFDM_RATE_18MB);
9583         case 48:
9584                 return (BWN_OFDM_RATE_24MB);
9585         case 72:
9586                 return (BWN_OFDM_RATE_36MB);
9587         case 96:
9588                 return (BWN_OFDM_RATE_48MB);
9589         case 108:
9590                 return (BWN_OFDM_RATE_54MB);
9591         /* CCK rates (NB: not IEEE std, device-specific) */
9592         case 2:
9593                 return (BWN_CCK_RATE_1MB);
9594         case 4:
9595                 return (BWN_CCK_RATE_2MB);
9596         case 11:
9597                 return (BWN_CCK_RATE_5MB);
9598         case 22:
9599                 return (BWN_CCK_RATE_11MB);
9600         }
9601
9602         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9603         return (BWN_CCK_RATE_1MB);
9604 }
9605
9606 static int
9607 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9608     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9609 {
9610         const struct bwn_phy *phy = &mac->mac_phy;
9611         struct bwn_softc *sc = mac->mac_sc;
9612         struct ieee80211_frame *wh;
9613         struct ieee80211_frame *protwh;
9614         struct ieee80211_frame_cts *cts;
9615         struct ieee80211_frame_rts *rts;
9616         const struct ieee80211_txparam *tp;
9617         struct ieee80211vap *vap = ni->ni_vap;
9618         struct ifnet *ifp = sc->sc_ifp;
9619         struct ieee80211com *ic = ifp->if_l2com;
9620         struct mbuf *mprot;
9621         unsigned int len;
9622         uint32_t macctl = 0;
9623         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9624         uint16_t phyctl = 0;
9625         uint8_t rate, rate_fb;
9626
9627         wh = mtod(m, struct ieee80211_frame *);
9628         memset(txhdr, 0, sizeof(*txhdr));
9629
9630         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9631         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9632         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9633
9634         /*
9635          * Find TX rate
9636          */
9637         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9638         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9639                 rate = rate_fb = tp->mgmtrate;
9640         else if (ismcast)
9641                 rate = rate_fb = tp->mcastrate;
9642         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9643                 rate = rate_fb = tp->ucastrate;
9644         else {
9645                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9646                 rate = ni->ni_txrate;
9647
9648                 if (rix > 0)
9649                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9650                             IEEE80211_RATE_VAL;
9651                 else
9652                         rate_fb = rate;
9653         }
9654
9655         sc->sc_tx_rate = rate;
9656
9657         rate = bwn_ieeerate2hwrate(sc, rate);
9658         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9659
9660         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9661             bwn_plcp_getcck(rate);
9662         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9663         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9664
9665         if ((rate_fb == rate) ||
9666             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9667             (*(u_int16_t *)wh->i_dur == htole16(0)))
9668                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9669         else
9670                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9671                     m->m_pkthdr.len, rate, isshort);
9672
9673         /* XXX TX encryption */
9674         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9675             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9676             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9677             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9678         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9679             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9680
9681         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9682             BWN_TX_EFT_FB_CCK;
9683         txhdr->chan = phy->chan;
9684         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9685             BWN_TX_PHY_ENC_CCK;
9686         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9687              rate == BWN_CCK_RATE_11MB))
9688                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9689
9690         /* XXX TX antenna selection */
9691
9692         switch (bwn_antenna_sanitize(mac, 0)) {
9693         case 0:
9694                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9695                 break;
9696         case 1:
9697                 phyctl |= BWN_TX_PHY_ANT0;
9698                 break;
9699         case 2:
9700                 phyctl |= BWN_TX_PHY_ANT1;
9701                 break;
9702         case 3:
9703                 phyctl |= BWN_TX_PHY_ANT2;
9704                 break;
9705         case 4:
9706                 phyctl |= BWN_TX_PHY_ANT3;
9707                 break;
9708         default:
9709                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9710         }
9711
9712         if (!ismcast)
9713                 macctl |= BWN_TX_MAC_ACK;
9714
9715         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9716         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9717             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9718                 macctl |= BWN_TX_MAC_LONGFRAME;
9719
9720         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9721                 /* XXX RTS rate is always 1MB??? */
9722                 rts_rate = BWN_CCK_RATE_1MB;
9723                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9724
9725                 protdur = ieee80211_compute_duration(ic->ic_rt,
9726                     m->m_pkthdr.len, rate, isshort) +
9727                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9728
9729                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9730                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9731                             (txhdr->body.old.rts_frame) :
9732                             (txhdr->body.new.rts_frame));
9733                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9734                             protdur);
9735                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9736                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9737                             mprot->m_pkthdr.len);
9738                         m_freem(mprot);
9739                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9740                         len = sizeof(struct ieee80211_frame_cts);
9741                 } else {
9742                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9743                             (txhdr->body.old.rts_frame) :
9744                             (txhdr->body.new.rts_frame));
9745                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9746                             isshort);
9747                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9748                             wh->i_addr2, protdur);
9749                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9750                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9751                             mprot->m_pkthdr.len);
9752                         m_freem(mprot);
9753                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9754                         len = sizeof(struct ieee80211_frame_rts);
9755                 }
9756                 len += IEEE80211_CRC_LEN;
9757                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9758                     &txhdr->body.old.rts_plcp :
9759                     &txhdr->body.new.rts_plcp), len, rts_rate);
9760                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9761                     rts_rate_fb);
9762
9763                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9764                     (&txhdr->body.old.rts_frame) :
9765                     (&txhdr->body.new.rts_frame));
9766                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9767
9768                 if (BWN_ISOFDMRATE(rts_rate)) {
9769                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9770                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9771                 } else {
9772                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9773                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9774                 }
9775                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9776                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9777         }
9778
9779         if (BWN_ISOLDFMT(mac))
9780                 txhdr->body.old.cookie = htole16(cookie);
9781         else
9782                 txhdr->body.new.cookie = htole16(cookie);
9783
9784         txhdr->macctl = htole32(macctl);
9785         txhdr->phyctl = htole16(phyctl);
9786
9787         /*
9788          * TX radio tap
9789          */
9790         if (ieee80211_radiotap_active_vap(vap)) {
9791                 sc->sc_tx_th.wt_flags = 0;
9792                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9793                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9794                 if (isshort &&
9795                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9796                      rate == BWN_CCK_RATE_11MB))
9797                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9798                 sc->sc_tx_th.wt_rate = rate;
9799
9800                 ieee80211_radiotap_tx(vap, m);
9801         }
9802
9803         return (0);
9804 }
9805
9806 static void
9807 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9808     const uint8_t rate)
9809 {
9810         uint32_t d, plen;
9811         uint8_t *raw = plcp->o.raw;
9812
9813         if (BWN_ISOFDMRATE(rate)) {
9814                 d = bwn_plcp_getofdm(rate);
9815                 KASSERT(!(octets & 0xf000),
9816                     ("%s:%d: fail", __func__, __LINE__));
9817                 d |= (octets << 5);
9818                 plcp->o.data = htole32(d);
9819         } else {
9820                 plen = octets * 16 / rate;
9821                 if ((octets * 16 % rate) > 0) {
9822                         plen++;
9823                         if ((rate == BWN_CCK_RATE_11MB)
9824                             && ((octets * 8 % 11) < 4)) {
9825                                 raw[1] = 0x84;
9826                         } else
9827                                 raw[1] = 0x04;
9828                 } else
9829                         raw[1] = 0x04;
9830                 plcp->o.data |= htole32(plen << 16);
9831                 raw[0] = bwn_plcp_getcck(rate);
9832         }
9833 }
9834
9835 static uint8_t
9836 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9837 {
9838         struct bwn_softc *sc = mac->mac_sc;
9839         uint8_t mask;
9840
9841         if (n == 0)
9842                 return (0);
9843         if (mac->mac_phy.gmode)
9844                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9845         else
9846                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9847         if (!(mask & (1 << (n - 1))))
9848                 return (0);
9849         return (n);
9850 }
9851
9852 static uint8_t
9853 bwn_get_fbrate(uint8_t bitrate)
9854 {
9855         switch (bitrate) {
9856         case BWN_CCK_RATE_1MB:
9857                 return (BWN_CCK_RATE_1MB);
9858         case BWN_CCK_RATE_2MB:
9859                 return (BWN_CCK_RATE_1MB);
9860         case BWN_CCK_RATE_5MB:
9861                 return (BWN_CCK_RATE_2MB);
9862         case BWN_CCK_RATE_11MB:
9863                 return (BWN_CCK_RATE_5MB);
9864         case BWN_OFDM_RATE_6MB:
9865                 return (BWN_CCK_RATE_5MB);
9866         case BWN_OFDM_RATE_9MB:
9867                 return (BWN_OFDM_RATE_6MB);
9868         case BWN_OFDM_RATE_12MB:
9869                 return (BWN_OFDM_RATE_9MB);
9870         case BWN_OFDM_RATE_18MB:
9871                 return (BWN_OFDM_RATE_12MB);
9872         case BWN_OFDM_RATE_24MB:
9873                 return (BWN_OFDM_RATE_18MB);
9874         case BWN_OFDM_RATE_36MB:
9875                 return (BWN_OFDM_RATE_24MB);
9876         case BWN_OFDM_RATE_48MB:
9877                 return (BWN_OFDM_RATE_36MB);
9878         case BWN_OFDM_RATE_54MB:
9879                 return (BWN_OFDM_RATE_48MB);
9880         }
9881         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9882         return (0);
9883 }
9884
9885 static uint32_t
9886 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9887     uint32_t ctl, const void *_data, int len)
9888 {
9889         struct bwn_softc *sc = mac->mac_sc;
9890         uint32_t value = 0;
9891         const uint8_t *data = _data;
9892
9893         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9894             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9895         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9896
9897         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9898             tq->tq_base + BWN_PIO8_TXDATA);
9899         if (len & 3) {
9900                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9901                     BWN_PIO8_TXCTL_24_31);
9902                 data = &(data[len - 1]);
9903                 switch (len & 3) {
9904                 case 3:
9905                         ctl |= BWN_PIO8_TXCTL_16_23;
9906                         value |= (uint32_t)(*data) << 16;
9907                         data--;
9908                 case 2:
9909                         ctl |= BWN_PIO8_TXCTL_8_15;
9910                         value |= (uint32_t)(*data) << 8;
9911                         data--;
9912                 case 1:
9913                         value |= (uint32_t)(*data);
9914                 }
9915                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9916                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9917         }
9918
9919         return (ctl);
9920 }
9921
9922 static void
9923 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9924     uint16_t offset, uint32_t value)
9925 {
9926
9927         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9928 }
9929
9930 static uint16_t
9931 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9932     uint16_t ctl, const void *_data, int len)
9933 {
9934         struct bwn_softc *sc = mac->mac_sc;
9935         const uint8_t *data = _data;
9936
9937         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9938         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9939
9940         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9941             tq->tq_base + BWN_PIO_TXDATA);
9942         if (len & 1) {
9943                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9944                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9945                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9946         }
9947
9948         return (ctl);
9949 }
9950
9951 static uint16_t
9952 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9953     uint16_t ctl, struct mbuf *m0)
9954 {
9955         int i, j = 0;
9956         uint16_t data = 0;
9957         const uint8_t *buf;
9958         struct mbuf *m = m0;
9959
9960         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9961         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9962
9963         for (; m != NULL; m = m->m_next) {
9964                 buf = mtod(m, const uint8_t *);
9965                 for (i = 0; i < m->m_len; i++) {
9966                         if (!((j++) % 2))
9967                                 data |= buf[i];
9968                         else {
9969                                 data |= (buf[i] << 8);
9970                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9971                                 data = 0;
9972                         }
9973                 }
9974         }
9975         if (m0->m_pkthdr.len % 2) {
9976                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9977                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9978                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9979         }
9980
9981         return (ctl);
9982 }
9983
9984 static void
9985 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9986 {
9987
9988         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9989                 return;
9990         BWN_WRITE_2(mac, 0x684, 510 + time);
9991         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9992 }
9993
9994 static struct bwn_dma_ring *
9995 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9996 {
9997
9998         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9999                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10000
10001         switch (prio) {
10002         case 3:
10003                 return (mac->mac_method.dma.wme[WME_AC_VO]);
10004         case 2:
10005                 return (mac->mac_method.dma.wme[WME_AC_VI]);
10006         case 0:
10007                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10008         case 1:
10009                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10010         }
10011         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10012         return (NULL);
10013 }
10014
10015 static int
10016 bwn_dma_getslot(struct bwn_dma_ring *dr)
10017 {
10018         int slot;
10019
10020         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10021
10022         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10023         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10024         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10025
10026         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10027         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10028         dr->dr_curslot = slot;
10029         dr->dr_usedslot++;
10030
10031         return (slot);
10032 }
10033
10034 static int
10035 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10036 {
10037         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10038         unsigned int a, b, c, d;
10039         unsigned int avg;
10040         uint32_t tmp;
10041
10042         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10043         a = tmp & 0xff;
10044         b = (tmp >> 8) & 0xff;
10045         c = (tmp >> 16) & 0xff;
10046         d = (tmp >> 24) & 0xff;
10047         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10048             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10049                 return (ENOENT);
10050         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10051             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10052             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10053
10054         if (ofdm) {
10055                 a = (a + 32) & 0x3f;
10056                 b = (b + 32) & 0x3f;
10057                 c = (c + 32) & 0x3f;
10058                 d = (d + 32) & 0x3f;
10059         }
10060
10061         avg = (a + b + c + d + 2) / 4;
10062         if (ofdm) {
10063                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10064                     & BWN_HF_4DB_CCK_POWERBOOST)
10065                         avg = (avg >= 13) ? (avg - 13) : 0;
10066         }
10067         return (avg);
10068 }
10069
10070 static void
10071 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10072 {
10073         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10074         int rfatt = *rfattp;
10075         int bbatt = *bbattp;
10076
10077         while (1) {
10078                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10079                         break;
10080                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10081                         break;
10082                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10083                         break;
10084                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10085                         break;
10086                 if (bbatt > lo->bbatt.max) {
10087                         bbatt -= 4;
10088                         rfatt += 1;
10089                         continue;
10090                 }
10091                 if (bbatt < lo->bbatt.min) {
10092                         bbatt += 4;
10093                         rfatt -= 1;
10094                         continue;
10095                 }
10096                 if (rfatt > lo->rfatt.max) {
10097                         rfatt -= 1;
10098                         bbatt += 4;
10099                         continue;
10100                 }
10101                 if (rfatt < lo->rfatt.min) {
10102                         rfatt += 1;
10103                         bbatt -= 4;
10104                         continue;
10105                 }
10106                 break;
10107         }
10108
10109         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10110         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10111 }
10112
10113 static void
10114 bwn_phy_lock(struct bwn_mac *mac)
10115 {
10116         struct bwn_softc *sc = mac->mac_sc;
10117         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10118
10119         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10120             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10121
10122         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10123                 bwn_psctl(mac, BWN_PS_AWAKE);
10124 }
10125
10126 static void
10127 bwn_phy_unlock(struct bwn_mac *mac)
10128 {
10129         struct bwn_softc *sc = mac->mac_sc;
10130         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10131
10132         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10133             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10134
10135         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10136                 bwn_psctl(mac, 0);
10137 }
10138
10139 static void
10140 bwn_rf_lock(struct bwn_mac *mac)
10141 {
10142
10143         BWN_WRITE_4(mac, BWN_MACCTL,
10144             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10145         BWN_READ_4(mac, BWN_MACCTL);
10146         DELAY(10);
10147 }
10148
10149 static void
10150 bwn_rf_unlock(struct bwn_mac *mac)
10151 {
10152
10153         BWN_READ_2(mac, BWN_PHYVER);
10154         BWN_WRITE_4(mac, BWN_MACCTL,
10155             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10156 }
10157
10158 static struct bwn_pio_txqueue *
10159 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10160     struct bwn_pio_txpkt **pack)
10161 {
10162         struct bwn_pio *pio = &mac->mac_method.pio;
10163         struct bwn_pio_txqueue *tq = NULL;
10164         unsigned int index;
10165
10166         switch (cookie & 0xf000) {
10167         case 0x1000:
10168                 tq = &pio->wme[WME_AC_BK];
10169                 break;
10170         case 0x2000:
10171                 tq = &pio->wme[WME_AC_BE];
10172                 break;
10173         case 0x3000:
10174                 tq = &pio->wme[WME_AC_VI];
10175                 break;
10176         case 0x4000:
10177                 tq = &pio->wme[WME_AC_VO];
10178                 break;
10179         case 0x5000:
10180                 tq = &pio->mcast;
10181                 break;
10182         }
10183         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10184         if (tq == NULL)
10185                 return (NULL);
10186         index = (cookie & 0x0fff);
10187         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10188         if (index >= N(tq->tq_pkts))
10189                 return (NULL);
10190         *pack = &tq->tq_pkts[index];
10191         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10192         return (tq);
10193 }
10194
10195 static void
10196 bwn_txpwr(void *arg, int npending)
10197 {
10198         struct bwn_mac *mac = arg;
10199         struct bwn_softc *sc = mac->mac_sc;
10200
10201         BWN_LOCK(sc);
10202         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10203             mac->mac_phy.set_txpwr != NULL)
10204                 mac->mac_phy.set_txpwr(mac);
10205         BWN_UNLOCK(sc);
10206 }
10207
10208 static void
10209 bwn_task_15s(struct bwn_mac *mac)
10210 {
10211         uint16_t reg;
10212
10213         if (mac->mac_fw.opensource) {
10214                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10215                 if (reg) {
10216                         bwn_restart(mac, "fw watchdog");
10217                         return;
10218                 }
10219                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10220         }
10221         if (mac->mac_phy.task_15s)
10222                 mac->mac_phy.task_15s(mac);
10223
10224         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10225 }
10226
10227 static void
10228 bwn_task_30s(struct bwn_mac *mac)
10229 {
10230
10231         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10232                 return;
10233         mac->mac_noise.noi_running = 1;
10234         mac->mac_noise.noi_nsamples = 0;
10235
10236         bwn_noise_gensample(mac);
10237 }
10238
10239 static void
10240 bwn_task_60s(struct bwn_mac *mac)
10241 {
10242
10243         if (mac->mac_phy.task_60s)
10244                 mac->mac_phy.task_60s(mac);
10245         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10246 }
10247
10248 static void
10249 bwn_tasks(void *arg)
10250 {
10251         struct bwn_mac *mac = arg;
10252         struct bwn_softc *sc = mac->mac_sc;
10253
10254         BWN_ASSERT_LOCKED(sc);
10255         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10256                 return;
10257
10258         if (mac->mac_task_state % 4 == 0)
10259                 bwn_task_60s(mac);
10260         if (mac->mac_task_state % 2 == 0)
10261                 bwn_task_30s(mac);
10262         bwn_task_15s(mac);
10263
10264         mac->mac_task_state++;
10265         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10266 }
10267
10268 static int
10269 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10270 {
10271         struct bwn_softc *sc = mac->mac_sc;
10272
10273         KASSERT(a == 0, ("not support APHY\n"));
10274
10275         switch (plcp->o.raw[0] & 0xf) {
10276         case 0xb:
10277                 return (BWN_OFDM_RATE_6MB);
10278         case 0xf:
10279                 return (BWN_OFDM_RATE_9MB);
10280         case 0xa:
10281                 return (BWN_OFDM_RATE_12MB);
10282         case 0xe:
10283                 return (BWN_OFDM_RATE_18MB);
10284         case 0x9:
10285                 return (BWN_OFDM_RATE_24MB);
10286         case 0xd:
10287                 return (BWN_OFDM_RATE_36MB);
10288         case 0x8:
10289                 return (BWN_OFDM_RATE_48MB);
10290         case 0xc:
10291                 return (BWN_OFDM_RATE_54MB);
10292         }
10293         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10294             plcp->o.raw[0] & 0xf);
10295         return (-1);
10296 }
10297
10298 static int
10299 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10300 {
10301         struct bwn_softc *sc = mac->mac_sc;
10302
10303         switch (plcp->o.raw[0]) {
10304         case 0x0a:
10305                 return (BWN_CCK_RATE_1MB);
10306         case 0x14:
10307                 return (BWN_CCK_RATE_2MB);
10308         case 0x37:
10309                 return (BWN_CCK_RATE_5MB);
10310         case 0x6e:
10311                 return (BWN_CCK_RATE_11MB);
10312         }
10313         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10314         return (-1);
10315 }
10316
10317 static void
10318 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10319     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10320     int rssi, int noise)
10321 {
10322         struct bwn_softc *sc = mac->mac_sc;
10323         const struct ieee80211_frame_min *wh;
10324         uint64_t tsf;
10325         uint16_t low_mactime_now;
10326
10327         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10328                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10329
10330         wh = mtod(m, const struct ieee80211_frame_min *);
10331         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10332                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10333
10334         bwn_tsf_read(mac, &tsf);
10335         low_mactime_now = tsf;
10336         tsf = tsf & ~0xffffULL;
10337         tsf += le16toh(rxhdr->mac_time);
10338         if (low_mactime_now < le16toh(rxhdr->mac_time))
10339                 tsf -= 0x10000;
10340
10341         sc->sc_rx_th.wr_tsf = tsf;
10342         sc->sc_rx_th.wr_rate = rate;
10343         sc->sc_rx_th.wr_antsignal = rssi;
10344         sc->sc_rx_th.wr_antnoise = noise;
10345 }
10346
10347 static void
10348 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10349 {
10350         uint32_t low, high;
10351
10352         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10353             ("%s:%d: fail", __func__, __LINE__));
10354
10355         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10356         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10357         *tsf = high;
10358         *tsf <<= 32;
10359         *tsf |= low;
10360 }
10361
10362 static int
10363 bwn_dma_attach(struct bwn_mac *mac)
10364 {
10365         struct bwn_dma *dma = &mac->mac_method.dma;
10366         struct bwn_softc *sc = mac->mac_sc;
10367         bus_addr_t lowaddr = 0;
10368         int error;
10369
10370         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10371                 return (0);
10372
10373         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10374
10375         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10376
10377         dma->dmatype = bwn_dma_gettype(mac);
10378         if (dma->dmatype == BWN_DMA_30BIT)
10379                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10380         else if (dma->dmatype == BWN_DMA_32BIT)
10381                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10382         else
10383                 lowaddr = BUS_SPACE_MAXADDR;
10384
10385         /*
10386          * Create top level DMA tag
10387          */
10388         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10389                                BWN_ALIGN, 0,            /* alignment, bounds */
10390                                lowaddr,                 /* lowaddr */
10391                                BUS_SPACE_MAXADDR,       /* highaddr */
10392                                NULL, NULL,              /* filter, filterarg */
10393                                MAXBSIZE,                /* maxsize */
10394                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10395                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10396                                0,                       /* flags */
10397                                NULL, NULL,              /* lockfunc, lockarg */
10398                                &dma->parent_dtag);
10399         if (error) {
10400                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10401                 return (error);
10402         }
10403
10404         /*
10405          * Create TX/RX mbuf DMA tag
10406          */
10407         error = bus_dma_tag_create(dma->parent_dtag,
10408                                 1,
10409                                 0,
10410                                 BUS_SPACE_MAXADDR,
10411                                 BUS_SPACE_MAXADDR,
10412                                 NULL, NULL,
10413                                 MCLBYTES,
10414                                 1,
10415                                 BUS_SPACE_MAXSIZE_32BIT,
10416                                 0,
10417                                 NULL, NULL,
10418                                 &dma->rxbuf_dtag);
10419         if (error) {
10420                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10421                 goto fail0;
10422         }
10423         error = bus_dma_tag_create(dma->parent_dtag,
10424                                 1,
10425                                 0,
10426                                 BUS_SPACE_MAXADDR,
10427                                 BUS_SPACE_MAXADDR,
10428                                 NULL, NULL,
10429                                 MCLBYTES,
10430                                 1,
10431                                 BUS_SPACE_MAXSIZE_32BIT,
10432                                 0,
10433                                 NULL, NULL,
10434                                 &dma->txbuf_dtag);
10435         if (error) {
10436                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10437                 goto fail1;
10438         }
10439
10440         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10441         if (!dma->wme[WME_AC_BK])
10442                 goto fail2;
10443
10444         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10445         if (!dma->wme[WME_AC_BE])
10446                 goto fail3;
10447
10448         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10449         if (!dma->wme[WME_AC_VI])
10450                 goto fail4;
10451
10452         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10453         if (!dma->wme[WME_AC_VO])
10454                 goto fail5;
10455
10456         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10457         if (!dma->mcast)
10458                 goto fail6;
10459         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10460         if (!dma->rx)
10461                 goto fail7;
10462
10463         return (error);
10464
10465 fail7:  bwn_dma_ringfree(&dma->mcast);
10466 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10467 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10468 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10469 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10470 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10471 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10472 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10473         return (error);
10474 }
10475
10476 static struct bwn_dma_ring *
10477 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10478     uint16_t cookie, int *slot)
10479 {
10480         struct bwn_dma *dma = &mac->mac_method.dma;
10481         struct bwn_dma_ring *dr;
10482         struct bwn_softc *sc = mac->mac_sc;
10483
10484         BWN_ASSERT_LOCKED(mac->mac_sc);
10485
10486         switch (cookie & 0xf000) {
10487         case 0x1000:
10488                 dr = dma->wme[WME_AC_BK];
10489                 break;
10490         case 0x2000:
10491                 dr = dma->wme[WME_AC_BE];
10492                 break;
10493         case 0x3000:
10494                 dr = dma->wme[WME_AC_VI];
10495                 break;
10496         case 0x4000:
10497                 dr = dma->wme[WME_AC_VO];
10498                 break;
10499         case 0x5000:
10500                 dr = dma->mcast;
10501                 break;
10502         default:
10503                 dr = NULL;
10504                 KASSERT(0 == 1,
10505                     ("invalid cookie value %d", cookie & 0xf000));
10506         }
10507         *slot = (cookie & 0x0fff);
10508         if (*slot < 0 || *slot >= dr->dr_numslots) {
10509                 /*
10510                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10511                  * that it occurs events which have same H/W sequence numbers.
10512                  * When it's occurred just prints a WARNING msgs and ignores.
10513                  */
10514                 KASSERT(status->seq == dma->lastseq,
10515                     ("%s:%d: fail", __func__, __LINE__));
10516                 device_printf(sc->sc_dev,
10517                     "out of slot ranges (0 < %d < %d)\n", *slot,
10518                     dr->dr_numslots);
10519                 return (NULL);
10520         }
10521         dma->lastseq = status->seq;
10522         return (dr);
10523 }
10524
10525 static void
10526 bwn_dma_stop(struct bwn_mac *mac)
10527 {
10528         struct bwn_dma *dma;
10529
10530         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10531                 return;
10532         dma = &mac->mac_method.dma;
10533
10534         bwn_dma_ringstop(&dma->rx);
10535         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10536         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10537         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10538         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10539         bwn_dma_ringstop(&dma->mcast);
10540 }
10541
10542 static void
10543 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10544 {
10545
10546         if (dr == NULL)
10547                 return;
10548
10549         bwn_dma_cleanup(*dr);
10550 }
10551
10552 static void
10553 bwn_pio_stop(struct bwn_mac *mac)
10554 {
10555         struct bwn_pio *pio;
10556
10557         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10558                 return;
10559         pio = &mac->mac_method.pio;
10560
10561         bwn_destroy_queue_tx(&pio->mcast);
10562         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10563         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10564         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10565         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10566 }
10567
10568 static void
10569 bwn_led_attach(struct bwn_mac *mac)
10570 {
10571         struct bwn_softc *sc = mac->mac_sc;
10572         const uint8_t *led_act = NULL;
10573         uint16_t val[BWN_LED_MAX];
10574         int i;
10575
10576         sc->sc_led_idle = (2350 * hz) / 1000;
10577         sc->sc_led_blink = 1;
10578
10579         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10580                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10581                     bwn_vendor_led_act[i].vid) {
10582                         led_act = bwn_vendor_led_act[i].led_act;
10583                         break;
10584                 }
10585         }
10586         if (led_act == NULL)
10587                 led_act = bwn_default_led_act;
10588
10589         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10590         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10591         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10592         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10593
10594         for (i = 0; i < BWN_LED_MAX; ++i) {
10595                 struct bwn_led *led = &sc->sc_leds[i];
10596
10597                 if (val[i] == 0xff) {
10598                         led->led_act = led_act[i];
10599                 } else {
10600                         if (val[i] & BWN_LED_ACT_LOW)
10601                                 led->led_flags |= BWN_LED_F_ACTLOW;
10602                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10603                 }
10604                 led->led_mask = (1 << i);
10605
10606                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10607                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10608                     led->led_act == BWN_LED_ACT_BLINK) {
10609                         led->led_flags |= BWN_LED_F_BLINK;
10610                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10611                                 led->led_flags |= BWN_LED_F_POLLABLE;
10612                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10613                                 led->led_flags |= BWN_LED_F_SLOW;
10614
10615                         if (sc->sc_blink_led == NULL) {
10616                                 sc->sc_blink_led = led;
10617                                 if (led->led_flags & BWN_LED_F_SLOW)
10618                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10619                         }
10620                 }
10621
10622                 DPRINTF(sc, BWN_DEBUG_LED,
10623                     "%dth led, act %d, lowact %d\n", i,
10624                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10625         }
10626         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10627 }
10628
10629 static __inline uint16_t
10630 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10631 {
10632
10633         if (led->led_flags & BWN_LED_F_ACTLOW)
10634                 on = !on;
10635         if (on)
10636                 val |= led->led_mask;
10637         else
10638                 val &= ~led->led_mask;
10639         return val;
10640 }
10641
10642 static void
10643 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10644 {
10645         struct bwn_softc *sc = mac->mac_sc;
10646         struct ifnet *ifp = sc->sc_ifp;
10647         struct ieee80211com *ic = ifp->if_l2com;
10648         uint16_t val;
10649         int i;
10650
10651         if (nstate == IEEE80211_S_INIT) {
10652                 callout_stop(&sc->sc_led_blink_ch);
10653                 sc->sc_led_blinking = 0;
10654         }
10655
10656         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10657                 return;
10658
10659         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10660         for (i = 0; i < BWN_LED_MAX; ++i) {
10661                 struct bwn_led *led = &sc->sc_leds[i];
10662                 int on;
10663
10664                 if (led->led_act == BWN_LED_ACT_UNKN ||
10665                     led->led_act == BWN_LED_ACT_NULL)
10666                         continue;
10667
10668                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10669                     nstate != IEEE80211_S_INIT)
10670                         continue;
10671
10672                 switch (led->led_act) {
10673                 case BWN_LED_ACT_ON:    /* Always on */
10674                         on = 1;
10675                         break;
10676                 case BWN_LED_ACT_OFF:   /* Always off */
10677                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10678                         on = 0;
10679                         break;
10680                 default:
10681                         on = 1;
10682                         switch (nstate) {
10683                         case IEEE80211_S_INIT:
10684                                 on = 0;
10685                                 break;
10686                         case IEEE80211_S_RUN:
10687                                 if (led->led_act == BWN_LED_ACT_11G &&
10688                                     ic->ic_curmode != IEEE80211_MODE_11G)
10689                                         on = 0;
10690                                 break;
10691                         default:
10692                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10693                                         on = 0;
10694                                 break;
10695                         }
10696                         break;
10697                 }
10698
10699                 val = bwn_led_onoff(led, val, on);
10700         }
10701         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10702 }
10703
10704 static void
10705 bwn_led_event(struct bwn_mac *mac, int event)
10706 {
10707         struct bwn_softc *sc = mac->mac_sc;
10708         struct bwn_led *led = sc->sc_blink_led;
10709         int rate;
10710
10711         if (event == BWN_LED_EVENT_POLL) {
10712                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10713                         return;
10714                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10715                         return;
10716         }
10717
10718         sc->sc_led_ticks = ticks;
10719         if (sc->sc_led_blinking)
10720                 return;
10721
10722         switch (event) {
10723         case BWN_LED_EVENT_RX:
10724                 rate = sc->sc_rx_rate;
10725                 break;
10726         case BWN_LED_EVENT_TX:
10727                 rate = sc->sc_tx_rate;
10728                 break;
10729         case BWN_LED_EVENT_POLL:
10730                 rate = 0;
10731                 break;
10732         default:
10733                 panic("unknown LED event %d\n", event);
10734                 break;
10735         }
10736         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10737             bwn_led_duration[rate].off_dur);
10738 }
10739
10740 static void
10741 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10742 {
10743         struct bwn_softc *sc = mac->mac_sc;
10744         struct bwn_led *led = sc->sc_blink_led;
10745         uint16_t val;
10746
10747         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10748         val = bwn_led_onoff(led, val, 1);
10749         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10750
10751         if (led->led_flags & BWN_LED_F_SLOW) {
10752                 BWN_LED_SLOWDOWN(on_dur);
10753                 BWN_LED_SLOWDOWN(off_dur);
10754         }
10755
10756         sc->sc_led_blinking = 1;
10757         sc->sc_led_blink_offdur = off_dur;
10758
10759         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10760 }
10761
10762 static void
10763 bwn_led_blink_next(void *arg)
10764 {
10765         struct bwn_mac *mac = arg;
10766         struct bwn_softc *sc = mac->mac_sc;
10767         uint16_t val;
10768
10769         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10770         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10771         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10772
10773         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10774             bwn_led_blink_end, mac);
10775 }
10776
10777 static void
10778 bwn_led_blink_end(void *arg)
10779 {
10780         struct bwn_mac *mac = arg;
10781         struct bwn_softc *sc = mac->mac_sc;
10782
10783         sc->sc_led_blinking = 0;
10784 }
10785
10786 static int
10787 bwn_suspend(device_t dev)
10788 {
10789         struct bwn_softc *sc = device_get_softc(dev);
10790
10791         bwn_stop(sc, 1);
10792         return (0);
10793 }
10794
10795 static int
10796 bwn_resume(device_t dev)
10797 {
10798         struct bwn_softc *sc = device_get_softc(dev);
10799         struct ifnet *ifp = sc->sc_ifp;
10800
10801         if (ifp->if_flags & IFF_UP)
10802                 bwn_init(sc);
10803         return (0);
10804 }
10805
10806 static void
10807 bwn_rfswitch(void *arg)
10808 {
10809         struct bwn_softc *sc = arg;
10810         struct bwn_mac *mac = sc->sc_curmac;
10811         int cur = 0, prev = 0;
10812
10813         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10814             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10815
10816         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10817                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10818                         & BWN_RF_HWENABLED_HI_MASK))
10819                         cur = 1;
10820         } else {
10821                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10822                     & BWN_RF_HWENABLED_LO_MASK)
10823                         cur = 1;
10824         }
10825
10826         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10827                 prev = 1;
10828
10829         if (cur != prev) {
10830                 if (cur)
10831                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10832                 else
10833                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10834
10835                 device_printf(sc->sc_dev,
10836                     "status of RF switch is changed to %s\n",
10837                     cur ? "ON" : "OFF");
10838                 if (cur != mac->mac_phy.rf_on) {
10839                         if (cur)
10840                                 bwn_rf_turnon(mac);
10841                         else
10842                                 bwn_rf_turnoff(mac);
10843                 }
10844         }
10845
10846         callout_schedule(&sc->sc_rfswitch_ch, hz);
10847 }
10848
10849 static void
10850 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10851 {
10852         struct bwn_phy *phy = &mac->mac_phy;
10853         struct bwn_phy_lp *plp = &phy->phy_lp;
10854
10855         plp->plp_antenna = BWN_ANT_DEFAULT;
10856 }
10857
10858 static int
10859 bwn_phy_lp_init(struct bwn_mac *mac)
10860 {
10861         static const struct bwn_stxtable tables[] = {
10862                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10863                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10864                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10865                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10866                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10867                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10868                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10869                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10870                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10871                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10872                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10873                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10874                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10875                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10876                 { 2, 11, 0x40, 0, 0x0f }
10877         };
10878         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10879         struct bwn_softc *sc = mac->mac_sc;
10880         const struct bwn_stxtable *st;
10881         struct ifnet *ifp = sc->sc_ifp;
10882         struct ieee80211com *ic = ifp->if_l2com;
10883         int i, error;
10884         uint16_t tmp;
10885
10886         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10887         bwn_phy_lp_bbinit(mac);
10888
10889         /* initialize RF */
10890         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10891         DELAY(1);
10892         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10893         DELAY(1);
10894
10895         if (mac->mac_phy.rf_ver == 0x2062)
10896                 bwn_phy_lp_b2062_init(mac);
10897         else {
10898                 bwn_phy_lp_b2063_init(mac);
10899
10900                 /* synchronize stx table. */
10901                 for (i = 0; i < N(tables); i++) {
10902                         st = &tables[i];
10903                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10904                         tmp >>= st->st_rfshift;
10905                         tmp <<= st->st_physhift;
10906                         BWN_PHY_SETMASK(mac,
10907                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10908                             ~(st->st_mask << st->st_physhift), tmp);
10909                 }
10910
10911                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10912                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10913         }
10914
10915         /* calibrate RC */
10916         if (mac->mac_phy.rev >= 2)
10917                 bwn_phy_lp_rxcal_r2(mac);
10918         else if (!plp->plp_rccap) {
10919                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10920                         bwn_phy_lp_rccal_r12(mac);
10921         } else
10922                 bwn_phy_lp_set_rccap(mac);
10923
10924         error = bwn_phy_lp_switch_channel(mac, 7);
10925         if (error)
10926                 device_printf(sc->sc_dev,
10927                     "failed to change channel 7 (%d)\n", error);
10928         bwn_phy_lp_txpctl_init(mac);
10929         bwn_phy_lp_calib(mac);
10930         return (0);
10931 }
10932
10933 static uint16_t
10934 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10935 {
10936
10937         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10938         return (BWN_READ_2(mac, BWN_PHYDATA));
10939 }
10940
10941 static void
10942 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10943 {
10944
10945         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10946         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10947 }
10948
10949 static void
10950 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10951     uint16_t set)
10952 {
10953
10954         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10955         BWN_WRITE_2(mac, BWN_PHYDATA,
10956             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10957 }
10958
10959 static uint16_t
10960 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10961 {
10962
10963         KASSERT(reg != 1, ("unaccessible register %d", reg));
10964         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10965                 reg |= 0x100;
10966         if (mac->mac_phy.rev >= 2)
10967                 reg |= 0x200;
10968         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10969         return BWN_READ_2(mac, BWN_RFDATALO);
10970 }
10971
10972 static void
10973 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10974 {
10975
10976         KASSERT(reg != 1, ("unaccessible register %d", reg));
10977         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10978         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10979 }
10980
10981 static void
10982 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10983 {
10984
10985         if (on) {
10986                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10987                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10988                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10989                 return;
10990         }
10991
10992         if (mac->mac_phy.rev >= 2) {
10993                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10994                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10995                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10996                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10997                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10998                 return;
10999         }
11000
11001         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11002         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11003         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11004         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11005 }
11006
11007 static int
11008 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11009 {
11010         struct bwn_phy *phy = &mac->mac_phy;
11011         struct bwn_phy_lp *plp = &phy->phy_lp;
11012         int error;
11013
11014         if (phy->rf_ver == 0x2063) {
11015                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11016                 if (error)
11017                         return (error);
11018         } else {
11019                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11020                 if (error)
11021                         return (error);
11022                 bwn_phy_lp_set_anafilter(mac, chan);
11023                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11024         }
11025
11026         plp->plp_chan = chan;
11027         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11028         return (0);
11029 }
11030
11031 static uint32_t
11032 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11033 {
11034         struct bwn_softc *sc = mac->mac_sc;
11035         struct ifnet *ifp = sc->sc_ifp;
11036         struct ieee80211com *ic = ifp->if_l2com;
11037
11038         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11039 }
11040
11041 static void
11042 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11043 {
11044         struct bwn_phy *phy = &mac->mac_phy;
11045         struct bwn_phy_lp *plp = &phy->phy_lp;
11046
11047         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11048                 return;
11049
11050         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11051         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11052         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11053         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11054         plp->plp_antenna = antenna;
11055 }
11056
11057 static void
11058 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11059 {
11060
11061         bwn_phy_lp_calib(mac);
11062 }
11063
11064 static void
11065 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11066 {
11067         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11068         struct bwn_softc *sc = mac->mac_sc;
11069         struct ifnet *ifp = sc->sc_ifp;
11070         struct ieee80211com *ic = ifp->if_l2com;
11071
11072         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11073                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11074                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11075                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11076                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11077                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11078                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11079                 return;
11080         }
11081
11082         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11083         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11084         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11085         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11086         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11087         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11088         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11089         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11090 }
11091
11092 static void
11093 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11094 {
11095
11096         bwn_phy_lp_tblinit(mac);
11097         if (mac->mac_phy.rev >= 2)
11098                 bwn_phy_lp_bbinit_r2(mac);
11099         else
11100                 bwn_phy_lp_bbinit_r01(mac);
11101 }
11102
11103 static void
11104 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11105 {
11106         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11107         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11108         struct bwn_softc *sc = mac->mac_sc;
11109         struct ifnet *ifp = sc->sc_ifp;
11110         struct ieee80211com *ic = ifp->if_l2com;
11111
11112         bwn_phy_lp_set_txgain(mac,
11113             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11114         bwn_phy_lp_set_bbmult(mac, 150);
11115 }
11116
11117 static void
11118 bwn_phy_lp_calib(struct bwn_mac *mac)
11119 {
11120         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11121         struct bwn_softc *sc = mac->mac_sc;
11122         struct ifnet *ifp = sc->sc_ifp;
11123         struct ieee80211com *ic = ifp->if_l2com;
11124         const struct bwn_rxcompco *rc = NULL;
11125         struct bwn_txgain ogain;
11126         int i, omode, oafeovr, orf, obbmult;
11127         uint8_t mode, fc = 0;
11128
11129         if (plp->plp_chanfullcal != plp->plp_chan) {
11130                 plp->plp_chanfullcal = plp->plp_chan;
11131                 fc = 1;
11132         }
11133
11134         bwn_mac_suspend(mac);
11135
11136         /* BlueTooth Coexistance Override */
11137         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11138         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11139
11140         if (mac->mac_phy.rev >= 2)
11141                 bwn_phy_lp_digflt_save(mac);
11142         bwn_phy_lp_get_txpctlmode(mac);
11143         mode = plp->plp_txpctlmode;
11144         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11145         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11146                 bwn_phy_lp_bugfix(mac);
11147         if (mac->mac_phy.rev >= 2 && fc == 1) {
11148                 bwn_phy_lp_get_txpctlmode(mac);
11149                 omode = plp->plp_txpctlmode;
11150                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11151                 if (oafeovr)
11152                         ogain = bwn_phy_lp_get_txgain(mac);
11153                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11154                 obbmult = bwn_phy_lp_get_bbmult(mac);
11155                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11156                 if (oafeovr)
11157                         bwn_phy_lp_set_txgain(mac, &ogain);
11158                 bwn_phy_lp_set_bbmult(mac, obbmult);
11159                 bwn_phy_lp_set_txpctlmode(mac, omode);
11160                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11161         }
11162         bwn_phy_lp_set_txpctlmode(mac, mode);
11163         if (mac->mac_phy.rev >= 2)
11164                 bwn_phy_lp_digflt_restore(mac);
11165
11166         /* do RX IQ Calculation; assumes that noise is true. */
11167         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11168                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11169                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11170                                 rc = &bwn_rxcompco_5354[i];
11171                 }
11172         } else if (mac->mac_phy.rev >= 2)
11173                 rc = &bwn_rxcompco_r2;
11174         else {
11175                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11176                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11177                                 rc = &bwn_rxcompco_r12[i];
11178                 }
11179         }
11180         if (rc == NULL)
11181                 goto fail;
11182
11183         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11184         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11185
11186         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11187
11188         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11189                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11190                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11191         } else {
11192                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11193                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11194         }
11195
11196         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11197         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11198         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11199         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11200         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11201         bwn_phy_lp_set_deaf(mac, 0);
11202         /* XXX no checking return value? */
11203         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11204         bwn_phy_lp_clear_deaf(mac, 0);
11205         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11206         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11207         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11208
11209         /* disable RX GAIN override. */
11210         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11211         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11212         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11213         if (mac->mac_phy.rev >= 2) {
11214                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11215                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11216                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11217                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11218                 }
11219         } else {
11220                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11221         }
11222
11223         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11224         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11225 fail:
11226         bwn_mac_enable(mac);
11227 }
11228
11229 static void
11230 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11231 {
11232
11233         if (on) {
11234                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11235                 return;
11236         }
11237
11238         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11239         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11240 }
11241
11242 static int
11243 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11244 {
11245         static const struct bwn_b206x_chan *bc = NULL;
11246         struct bwn_softc *sc = mac->mac_sc;
11247         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11248             tmp[6];
11249         uint16_t old, scale, tmp16;
11250         int i, div;
11251
11252         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11253                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11254                         bc = &bwn_b2063_chantable[i];
11255                         break;
11256                 }
11257         }
11258         if (bc == NULL)
11259                 return (EINVAL);
11260
11261         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11262         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11263         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11264         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11265         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11266         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11267         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11268         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11269         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11270         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11271         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11272         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11273
11274         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11275         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11276
11277         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11278         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11279         freqref = freqxtal * 3;
11280         div = (freqxtal <= 26000000 ? 1 : 2);
11281         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11282         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11283                 999999) / 1000000) + 1;
11284
11285         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11286         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11287             0xfff8, timeout >> 2);
11288         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11289             0xff9f,timeout << 5);
11290         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11291
11292         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11293         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11294         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11295
11296         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11297             (timeoutref + 1)) - 1;
11298         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11299             0xf0, count >> 8);
11300         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11301
11302         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11303         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11304         while (tmp[1] >= freqref) {
11305                 tmp[0]++;
11306                 tmp[1] -= freqref;
11307         }
11308         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11309         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11310         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11311         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11312         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11313
11314         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11315         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11316         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11317         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11318
11319         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11320         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11321
11322         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11323                 scale = 1;
11324                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11325         } else {
11326                 scale = 0;
11327                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11328         }
11329         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11330         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11331
11332         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11333             (scale + 1);
11334         if (tmp[5] > 150)
11335                 tmp[5] = 0;
11336
11337         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11338         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11339
11340         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11341         if (freqxtal > 26000000)
11342                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11343         else
11344                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11345
11346         if (val[0] == 45)
11347                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11348         else
11349                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11350
11351         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11352         DELAY(1);
11353         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11354
11355         /* VCO Calibration */
11356         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11357         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11358         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11359         DELAY(1);
11360         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11361         DELAY(1);
11362         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11363         DELAY(1);
11364         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11365         DELAY(300);
11366         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11367
11368         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11369         return (0);
11370 }
11371
11372 static int
11373 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11374 {
11375         struct bwn_softc *sc = mac->mac_sc;
11376         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11377         const struct bwn_b206x_chan *bc = NULL;
11378         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11379         uint32_t tmp[9];
11380         int i;
11381
11382         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11383                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11384                         bc = &bwn_b2062_chantable[i];
11385                         break;
11386                 }
11387         }
11388
11389         if (bc == NULL)
11390                 return (EINVAL);
11391
11392         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11393         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11394         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11395         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11396         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11397         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11398         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11399         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11400         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11401         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11402
11403         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11404         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11405         bwn_phy_lp_b2062_reset_pllbias(mac);
11406         tmp[0] = freqxtal / 1000;
11407         tmp[1] = plp->plp_div * 1000;
11408         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11409         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11410                 tmp[2] *= 2;
11411         tmp[3] = 48 * tmp[0];
11412         tmp[5] = tmp[2] / tmp[3];
11413         tmp[6] = tmp[2] % tmp[3];
11414         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11415         tmp[4] = tmp[6] * 0x100;
11416         tmp[5] = tmp[4] / tmp[3];
11417         tmp[6] = tmp[4] % tmp[3];
11418         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11419         tmp[4] = tmp[6] * 0x100;
11420         tmp[5] = tmp[4] / tmp[3];
11421         tmp[6] = tmp[4] % tmp[3];
11422         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11423         tmp[4] = tmp[6] * 0x100;
11424         tmp[5] = tmp[4] / tmp[3];
11425         tmp[6] = tmp[4] % tmp[3];
11426         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11427             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11428         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11429         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11430         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11431         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11432
11433         bwn_phy_lp_b2062_vco_calib(mac);
11434         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11435                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11436                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11437                 bwn_phy_lp_b2062_reset_pllbias(mac);
11438                 bwn_phy_lp_b2062_vco_calib(mac);
11439                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11440                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11441                         return (EIO);
11442                 }
11443         }
11444         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11445         return (0);
11446 }
11447
11448 static void
11449 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11450 {
11451         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11452         uint16_t tmp = (channel == 14);
11453
11454         if (mac->mac_phy.rev < 2) {
11455                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11456                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11457                         bwn_phy_lp_set_rccap(mac);
11458                 return;
11459         }
11460
11461         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11462 }
11463
11464 static void
11465 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11466 {
11467         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11468         struct bwn_softc *sc = mac->mac_sc;
11469         struct ifnet *ifp = sc->sc_ifp;
11470         struct ieee80211com *ic = ifp->if_l2com;
11471         uint16_t iso, tmp[3];
11472
11473         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11474
11475         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11476                 iso = plp->plp_txisoband_m;
11477         else if (freq <= 5320)
11478                 iso = plp->plp_txisoband_l;
11479         else if (freq <= 5700)
11480                 iso = plp->plp_txisoband_m;
11481         else
11482                 iso = plp->plp_txisoband_h;
11483
11484         tmp[0] = ((iso - 26) / 12) << 12;
11485         tmp[1] = tmp[0] + 0x1000;
11486         tmp[2] = tmp[0] + 0x2000;
11487
11488         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11489         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11490 }
11491
11492 static void
11493 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11494 {
11495         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11496         int i;
11497         static const uint16_t addr[] = {
11498                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11499                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11500                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11501                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11502                 BWN_PHY_OFDM(0xcf),
11503         };
11504         static const uint16_t val[] = {
11505                 0xde5e, 0xe832, 0xe331, 0x4d26,
11506                 0x0026, 0x1420, 0x0020, 0xfe08,
11507                 0x0008,
11508         };
11509
11510         for (i = 0; i < N(addr); i++) {
11511                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11512                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11513         }
11514 }
11515
11516 static void
11517 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11518 {
11519         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11520         struct bwn_softc *sc = mac->mac_sc;
11521         uint16_t ctl;
11522
11523         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11524         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11525         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11526                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11527                 break;
11528         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11529                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11530                 break;
11531         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11532                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11533                 break;
11534         default:
11535                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11536                 device_printf(sc->sc_dev, "unknown command mode\n");
11537                 break;
11538         }
11539 }
11540
11541 static void
11542 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11543 {
11544         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11545         uint16_t ctl;
11546         uint8_t old;
11547
11548         bwn_phy_lp_get_txpctlmode(mac);
11549         old = plp->plp_txpctlmode;
11550         if (old == mode)
11551                 return;
11552         plp->plp_txpctlmode = mode;
11553
11554         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11555                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11556                     plp->plp_tssiidx);
11557                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11558                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11559
11560                 /* disable TX GAIN override */
11561                 if (mac->mac_phy.rev < 2)
11562                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11563                 else {
11564                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11565                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11566                 }
11567                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11568
11569                 plp->plp_txpwridx = -1;
11570         }
11571         if (mac->mac_phy.rev >= 2) {
11572                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11573                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11574                 else
11575                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11576         }
11577
11578         /* writes TX Power Control mode */
11579         switch (plp->plp_txpctlmode) {
11580         case BWN_PHYLP_TXPCTL_OFF:
11581                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11582                 break;
11583         case BWN_PHYLP_TXPCTL_ON_HW:
11584                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11585                 break;
11586         case BWN_PHYLP_TXPCTL_ON_SW:
11587                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11588                 break;
11589         default:
11590                 ctl = 0;
11591                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11592         }
11593         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11594             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11595 }
11596
11597 static void
11598 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11599 {
11600         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11601         struct bwn_softc *sc = mac->mac_sc;
11602         const unsigned int size = 256;
11603         struct bwn_txgain tg;
11604         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11605         uint16_t tssinpt, tssiidx, value[2];
11606         uint8_t mode;
11607         int8_t txpwridx;
11608
11609         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11610             M_NOWAIT | M_ZERO);
11611         if (tabs == NULL) {
11612                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11613                 return;
11614         }
11615
11616         bwn_phy_lp_get_txpctlmode(mac);
11617         mode = plp->plp_txpctlmode;
11618         txpwridx = plp->plp_txpwridx;
11619         tssinpt = plp->plp_tssinpt;
11620         tssiidx = plp->plp_tssiidx;
11621
11622         bwn_tab_read_multi(mac,
11623             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11624             BWN_TAB_4(7, 0x140), size, tabs);
11625
11626         bwn_phy_lp_tblinit(mac);
11627         bwn_phy_lp_bbinit(mac);
11628         bwn_phy_lp_txpctl_init(mac);
11629         bwn_phy_lp_rf_onoff(mac, 1);
11630         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11631
11632         bwn_tab_write_multi(mac,
11633             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11634             BWN_TAB_4(7, 0x140), size, tabs);
11635
11636         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11637         plp->plp_tssinpt = tssinpt;
11638         plp->plp_tssiidx = tssiidx;
11639         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11640         if (txpwridx != -1) {
11641                 /* set TX power by index */
11642                 plp->plp_txpwridx = txpwridx;
11643                 bwn_phy_lp_get_txpctlmode(mac);
11644                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11645                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11646                 if (mac->mac_phy.rev >= 2) {
11647                         rxcomp = bwn_tab_read(mac,
11648                             BWN_TAB_4(7, txpwridx + 320));
11649                         txgain = bwn_tab_read(mac,
11650                             BWN_TAB_4(7, txpwridx + 192));
11651                         tg.tg_pad = (txgain >> 16) & 0xff;
11652                         tg.tg_gm = txgain & 0xff;
11653                         tg.tg_pga = (txgain >> 8) & 0xff;
11654                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11655                         bwn_phy_lp_set_txgain(mac, &tg);
11656                 } else {
11657                         rxcomp = bwn_tab_read(mac,
11658                             BWN_TAB_4(10, txpwridx + 320));
11659                         txgain = bwn_tab_read(mac,
11660                             BWN_TAB_4(10, txpwridx + 192));
11661                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11662                             0xf800, (txgain >> 4) & 0x7fff);
11663                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11664                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11665                 }
11666                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11667
11668                 /* set TX IQCC */
11669                 value[0] = (rxcomp >> 10) & 0x3ff;
11670                 value[1] = rxcomp & 0x3ff;
11671                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11672
11673                 coeff = bwn_tab_read(mac,
11674                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11675                     BWN_TAB_4(10, txpwridx + 448));
11676                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11677                 if (mac->mac_phy.rev >= 2) {
11678                         rfpwr = bwn_tab_read(mac,
11679                             BWN_TAB_4(7, txpwridx + 576));
11680                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11681                             rfpwr & 0xffff);
11682                 }
11683                 bwn_phy_lp_set_txgain_override(mac);
11684         }
11685         if (plp->plp_rccap)
11686                 bwn_phy_lp_set_rccap(mac);
11687         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11688         bwn_phy_lp_set_txpctlmode(mac, mode);
11689         free(tabs, M_DEVBUF);
11690 }
11691
11692 static void
11693 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11694 {
11695         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11696         int i;
11697         static const uint16_t addr[] = {
11698                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11699                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11700                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11701                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11702                 BWN_PHY_OFDM(0xcf),
11703         };
11704
11705         for (i = 0; i < N(addr); i++)
11706                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11707 }
11708
11709 static void
11710 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11711 {
11712         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11713
11714         if (mac->mac_phy.rev < 2) {
11715                 bwn_phy_lp_tblinit_r01(mac);
11716                 bwn_phy_lp_tblinit_txgain(mac);
11717                 bwn_phy_lp_set_gaintbl(mac, freq);
11718                 return;
11719         }
11720
11721         bwn_phy_lp_tblinit_r2(mac);
11722         bwn_phy_lp_tblinit_txgain(mac);
11723 }
11724
11725 struct bwn_wpair {
11726         uint16_t                reg;
11727         uint16_t                value;
11728 };
11729
11730 struct bwn_smpair {
11731         uint16_t                offset;
11732         uint16_t                mask;
11733         uint16_t                set;
11734 };
11735
11736 static void
11737 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11738 {
11739         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11740         struct bwn_softc *sc = mac->mac_sc;
11741         struct ifnet *ifp = sc->sc_ifp;
11742         struct ieee80211com *ic = ifp->if_l2com;
11743         static const struct bwn_wpair v1[] = {
11744                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11745                 { BWN_PHY_AFE_CTL, 0x8800 },
11746                 { BWN_PHY_AFE_CTL_OVR, 0 },
11747                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11748                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11749                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11750                 { BWN_PHY_OFDM(0xf9), 0 },
11751                 { BWN_PHY_TR_LOOKUP_1, 0 }
11752         };
11753         static const struct bwn_smpair v2[] = {
11754                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11755                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11756                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11757                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11758                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11759         };
11760         static const struct bwn_smpair v3[] = {
11761                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11762                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11763                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11764                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11765                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11766                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11767                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11768                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11769                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11770                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11771
11772         };
11773         int i;
11774
11775         for (i = 0; i < N(v1); i++)
11776                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11777         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11778         for (i = 0; i < N(v2); i++)
11779                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11780
11781         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11782         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11783         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11784         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11785                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11786                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11787         } else {
11788                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11789         }
11790         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11791         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11792         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11793         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11794         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11795         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11796         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11797         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11798         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11799         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11800         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11801         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11802             (siba_get_chiprev(sc->sc_dev) == 0)) {
11803                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11804                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11805         } else {
11806                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11807                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11808         }
11809         for (i = 0; i < N(v3); i++)
11810                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11811         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11812             (siba_get_chiprev(sc->sc_dev) == 0)) {
11813                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11814                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11815         }
11816
11817         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11818                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11819                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11820                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11821                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11822                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11823                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11824         } else
11825                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11826
11827         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11828         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11829         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11830         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11831         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11832         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11833         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11834             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11835             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11836
11837         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11838             (siba_get_chiprev(sc->sc_dev) == 0)) {
11839                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11840                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11841                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11842         }
11843
11844         bwn_phy_lp_digflt_save(mac);
11845 }
11846
11847 static void
11848 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11849 {
11850         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11851         struct bwn_softc *sc = mac->mac_sc;
11852         struct ifnet *ifp = sc->sc_ifp;
11853         struct ieee80211com *ic = ifp->if_l2com;
11854         static const struct bwn_smpair v1[] = {
11855                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11856                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11857                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11858                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11859                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11860                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11861                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11862         };
11863         static const struct bwn_smpair v2[] = {
11864                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11865                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11866                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11867                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11868                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11869                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11870                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11871                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11872                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11873                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11874                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11875                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11876                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11877                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11878                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11879                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11880         };
11881         static const struct bwn_smpair v3[] = {
11882                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11883                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11884                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11885                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11886                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11887                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11888                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11889                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11890         };
11891         static const struct bwn_smpair v4[] = {
11892                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11893                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11894                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11895                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11896                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11897                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11898                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11899                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11900         };
11901         static const struct bwn_smpair v5[] = {
11902                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11903                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11904                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11905                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11906                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11907                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11908                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11909                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11910         };
11911         int i;
11912         uint16_t tmp, tmp2;
11913
11914         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11915         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11916         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11917         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11918         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11919         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11920         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11921         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11922         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11923         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11924         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11925         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11926         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11927         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11928         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11929         for (i = 0; i < N(v1); i++)
11930                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11931         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11932             0xff00, plp->plp_rxpwroffset);
11933         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11934             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11935            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11936                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11937                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11938                 if (mac->mac_phy.rev == 0)
11939                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11940                             0xffcf, 0x0010);
11941                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11942         } else {
11943                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11944                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11945                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11946         }
11947         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11948         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11949         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11950                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11951         else
11952                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11953         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11954         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11955             0xfff9, (plp->plp_bxarch << 1));
11956         if (mac->mac_phy.rev == 1 &&
11957             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11958                 for (i = 0; i < N(v2); i++)
11959                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11960                             v2[i].set);
11961         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11962             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11963             ((mac->mac_phy.rev == 0) &&
11964              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11965                 for (i = 0; i < N(v3); i++)
11966                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11967                             v3[i].set);
11968         } else if (mac->mac_phy.rev == 1 ||
11969                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11970                 for (i = 0; i < N(v4); i++)
11971                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11972                             v4[i].set);
11973         } else {
11974                 for (i = 0; i < N(v5); i++)
11975                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11976                             v5[i].set);
11977         }
11978         if (mac->mac_phy.rev == 1 &&
11979             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11980                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11981                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11982                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11983                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11984         }
11985         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11986             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11987             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11988                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11989                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11990                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11991                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11992         }
11993         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11994                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11995                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11996                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11997                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11998                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11999                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
12000                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12001                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12002         } else {
12003                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12004                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12005         }
12006         if (mac->mac_phy.rev == 1) {
12007                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12008                 tmp2 = (tmp & 0x03e0) >> 5;
12009                 tmp2 |= tmp2 << 5;
12010                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12011                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12012                 tmp2 = (tmp & 0x1f00) >> 8;
12013                 tmp2 |= tmp2 << 5;
12014                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12015                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12016                 tmp2 = tmp & 0x00ff;
12017                 tmp2 |= tmp << 8;
12018                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12019         }
12020 }
12021
12022 struct bwn_b2062_freq {
12023         uint16_t                freq;
12024         uint8_t                 value[6];
12025 };
12026
12027 static void
12028 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12029 {
12030 #define CALC_CTL7(freq, div)                                            \
12031         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12032 #define CALC_CTL18(freq, div)                                           \
12033         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12034 #define CALC_CTL19(freq, div)                                           \
12035         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12036         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12037         struct bwn_softc *sc = mac->mac_sc;
12038         struct ifnet *ifp = sc->sc_ifp;
12039         struct ieee80211com *ic = ifp->if_l2com;
12040         static const struct bwn_b2062_freq freqdata_tab[] = {
12041                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12042                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12043                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12044                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12045                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12046                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12047         };
12048         static const struct bwn_wpair v1[] = {
12049                 { BWN_B2062_N_TXCTL3, 0 },
12050                 { BWN_B2062_N_TXCTL4, 0 },
12051                 { BWN_B2062_N_TXCTL5, 0 },
12052                 { BWN_B2062_N_TXCTL6, 0 },
12053                 { BWN_B2062_N_PDNCTL0, 0x40 },
12054                 { BWN_B2062_N_PDNCTL0, 0 },
12055                 { BWN_B2062_N_CALIB_TS, 0x10 },
12056                 { BWN_B2062_N_CALIB_TS, 0 }
12057         };
12058         const struct bwn_b2062_freq *f = NULL;
12059         uint32_t xtalfreq, ref;
12060         unsigned int i;
12061
12062         bwn_phy_lp_b2062_tblinit(mac);
12063
12064         for (i = 0; i < N(v1); i++)
12065                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12066         if (mac->mac_phy.rev > 0)
12067                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12068                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12069         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12070                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12071         else
12072                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12073
12074         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12075             ("%s:%d: fail", __func__, __LINE__));
12076         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12077         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12078
12079         if (xtalfreq <= 30000000) {
12080                 plp->plp_div = 1;
12081                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12082         } else {
12083                 plp->plp_div = 2;
12084                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12085         }
12086
12087         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12088             CALC_CTL7(xtalfreq, plp->plp_div));
12089         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12090             CALC_CTL18(xtalfreq, plp->plp_div));
12091         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12092             CALC_CTL19(xtalfreq, plp->plp_div));
12093
12094         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12095         ref &= 0xffff;
12096         for (i = 0; i < N(freqdata_tab); i++) {
12097                 if (ref < freqdata_tab[i].freq) {
12098                         f = &freqdata_tab[i];
12099                         break;
12100                 }
12101         }
12102         if (f == NULL)
12103                 f = &freqdata_tab[N(freqdata_tab) - 1];
12104         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12105             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12106         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12107             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12108         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12109         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12110 #undef CALC_CTL7
12111 #undef CALC_CTL18
12112 #undef CALC_CTL19
12113 }
12114
12115 static void
12116 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12117 {
12118
12119         bwn_phy_lp_b2063_tblinit(mac);
12120         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12121         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12122         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12123         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12124         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12125         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12126         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12127         if (mac->mac_phy.rev == 2) {
12128                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12129                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12130                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12131         } else {
12132                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12133                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12134         }
12135 }
12136
12137 static void
12138 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12139 {
12140         struct bwn_softc *sc = mac->mac_sc;
12141         static const struct bwn_wpair v1[] = {
12142                 { BWN_B2063_RX_BB_SP8, 0x0 },
12143                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12144                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12145                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12146                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12147                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12148                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12149                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12150         };
12151         static const struct bwn_wpair v2[] = {
12152                 { BWN_B2063_TX_BB_SP3, 0x0 },
12153                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12154                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12155                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12156                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12157         };
12158         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12159         int i;
12160         uint8_t tmp;
12161
12162         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12163
12164         for (i = 0; i < 2; i++)
12165                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12166         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12167         for (i = 2; i < N(v1); i++)
12168                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12169         for (i = 0; i < 10000; i++) {
12170                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12171                         break;
12172                 DELAY(1000);
12173         }
12174
12175         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12176                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12177
12178         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12179
12180         for (i = 0; i < N(v2); i++)
12181                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12182         if (freqxtal == 24000000) {
12183                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12184                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12185         } else {
12186                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12187                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12188         }
12189         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12190         for (i = 0; i < 10000; i++) {
12191                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12192                         break;
12193                 DELAY(1000);
12194         }
12195         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12196                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12197         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12198 }
12199
12200 static void
12201 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12202 {
12203         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12204         struct bwn_softc *sc = mac->mac_sc;
12205         struct bwn_phy_lp_iq_est ie;
12206         struct bwn_txgain tx_gains;
12207         static const uint32_t pwrtbl[21] = {
12208                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12209                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12210                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12211                 0x0004c, 0x0002c, 0x0001a,
12212         };
12213         uint32_t npwr, ipwr, sqpwr, tmp;
12214         int loopback, i, j, sum, error;
12215         uint16_t save[7];
12216         uint8_t txo, bbmult, txpctlmode;
12217
12218         error = bwn_phy_lp_switch_channel(mac, 7);
12219         if (error)
12220                 device_printf(sc->sc_dev,
12221                     "failed to change channel to 7 (%d)\n", error);
12222         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12223         bbmult = bwn_phy_lp_get_bbmult(mac);
12224         if (txo)
12225                 tx_gains = bwn_phy_lp_get_txgain(mac);
12226
12227         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12228         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12229         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12230         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12231         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12232         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12233         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12234
12235         bwn_phy_lp_get_txpctlmode(mac);
12236         txpctlmode = plp->plp_txpctlmode;
12237         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12238
12239         /* disable CRS */
12240         bwn_phy_lp_set_deaf(mac, 1);
12241         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12242         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12243         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12244         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12245         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12246         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12247         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12248         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12249         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12250         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12251         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12252         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12253         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12254         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12255         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12256         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12257         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12258         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12259         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12260         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12261         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12262         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12263         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12264         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12265
12266         loopback = bwn_phy_lp_loopback(mac);
12267         if (loopback == -1)
12268                 goto done;
12269         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12270         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12271         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12272         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12273         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12274
12275         tmp = 0;
12276         memset(&ie, 0, sizeof(ie));
12277         for (i = 128; i <= 159; i++) {
12278                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12279                 sum = 0;
12280                 for (j = 5; j <= 25; j++) {
12281                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12282                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12283                                 goto done;
12284                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12285                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12286                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12287                             12);
12288                         sum += ((ipwr - npwr) * (ipwr - npwr));
12289                         if ((i == 128) || (sum < tmp)) {
12290                                 plp->plp_rccap = i;
12291                                 tmp = sum;
12292                         }
12293                 }
12294         }
12295         bwn_phy_lp_ddfs_turnoff(mac);
12296 done:
12297         /* restore CRS */
12298         bwn_phy_lp_clear_deaf(mac, 1);
12299         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12300         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12301
12302         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12303         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12304         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12305         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12306         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12307         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12308         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12309
12310         bwn_phy_lp_set_bbmult(mac, bbmult);
12311         if (txo)
12312                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12313         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12314         if (plp->plp_rccap)
12315                 bwn_phy_lp_set_rccap(mac);
12316 }
12317
12318 static void
12319 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12320 {
12321         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12322         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12323
12324         if (mac->mac_phy.rev == 1)
12325                 rc_cap = MIN(rc_cap + 5, 15);
12326
12327         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12328             MAX(plp->plp_rccap - 4, 0x80));
12329         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12330         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12331             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12332 }
12333
12334 static uint32_t
12335 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12336 {
12337         uint32_t i, q, r;
12338
12339         if (div == 0)
12340                 return (0);
12341
12342         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12343                 q <<= 1;
12344                 if (r << 1 >= div) {
12345                         q++;
12346                         r = (r << 1) - div;
12347                 }
12348         }
12349         if (r << 1 >= div)
12350                 q++;
12351         return (q);
12352 }
12353
12354 static void
12355 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12356 {
12357         struct bwn_softc *sc = mac->mac_sc;
12358
12359         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12360         DELAY(20);
12361         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12362                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12363                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12364         } else {
12365                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12366         }
12367         DELAY(5);
12368 }
12369
12370 static void
12371 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12372 {
12373
12374         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12375         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12376         DELAY(200);
12377 }
12378
12379 static void
12380 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12381 {
12382 #define FLAG_A  0x01
12383 #define FLAG_G  0x02
12384         struct bwn_softc *sc = mac->mac_sc;
12385         struct ifnet *ifp = sc->sc_ifp;
12386         struct ieee80211com *ic = ifp->if_l2com;
12387         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12388                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12389                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12390                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12391                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12392                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12393                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12399                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12426                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12427                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12428                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12429                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12430                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12431                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12432                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12433                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12434                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12435         };
12436         const struct bwn_b206x_rfinit_entry *br;
12437         unsigned int i;
12438
12439         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12440                 br = &bwn_b2062_init_tab[i];
12441                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12442                         if (br->br_flags & FLAG_G)
12443                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12444                 } else {
12445                         if (br->br_flags & FLAG_A)
12446                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12447                 }
12448         }
12449 #undef FLAG_A
12450 #undef FLAG_B
12451 }
12452
12453 static void
12454 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12455 {
12456 #define FLAG_A  0x01
12457 #define FLAG_G  0x02
12458         struct bwn_softc *sc = mac->mac_sc;
12459         struct ifnet *ifp = sc->sc_ifp;
12460         struct ieee80211com *ic = ifp->if_l2com;
12461         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12462                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12464                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12465                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12466                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12467                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12468                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12469                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12470                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12471                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12472                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12473                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12474                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12475                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12476                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12477                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12478                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12479                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12482                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12483                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12485                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12486                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12487                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12488                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12489                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12493                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12494                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12495                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12496                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12497                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12498                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12499                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12500                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12501                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12502                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12503                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12504         };
12505         const struct bwn_b206x_rfinit_entry *br;
12506         unsigned int i;
12507
12508         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12509                 br = &bwn_b2063_init_tab[i];
12510                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12511                         if (br->br_flags & FLAG_G)
12512                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12513                 } else {
12514                         if (br->br_flags & FLAG_A)
12515                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12516                 }
12517         }
12518 #undef FLAG_A
12519 #undef FLAG_B
12520 }
12521
12522 static void
12523 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12524     int count, void *_data)
12525 {
12526         unsigned int i;
12527         uint32_t offset, type;
12528         uint8_t *data = _data;
12529
12530         type = BWN_TAB_GETTYPE(typenoffset);
12531         offset = BWN_TAB_GETOFFSET(typenoffset);
12532         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12533
12534         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12535
12536         for (i = 0; i < count; i++) {
12537                 switch (type) {
12538                 case BWN_TAB_8BIT:
12539                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12540                         data++;
12541                         break;
12542                 case BWN_TAB_16BIT:
12543                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12544                             BWN_PHY_TABLEDATALO);
12545                         data += 2;
12546                         break;
12547                 case BWN_TAB_32BIT:
12548                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12549                             BWN_PHY_TABLEDATAHI);
12550                         *((uint32_t *)data) <<= 16;
12551                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12552                             BWN_PHY_TABLEDATALO);
12553                         data += 4;
12554                         break;
12555                 default:
12556                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12557                 }
12558         }
12559 }
12560
12561 static void
12562 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12563     int count, const void *_data)
12564 {
12565         uint32_t offset, type, value;
12566         const uint8_t *data = _data;
12567         unsigned int i;
12568
12569         type = BWN_TAB_GETTYPE(typenoffset);
12570         offset = BWN_TAB_GETOFFSET(typenoffset);
12571         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12572
12573         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12574
12575         for (i = 0; i < count; i++) {
12576                 switch (type) {
12577                 case BWN_TAB_8BIT:
12578                         value = *data;
12579                         data++;
12580                         KASSERT(!(value & ~0xff),
12581                             ("%s:%d: fail", __func__, __LINE__));
12582                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12583                         break;
12584                 case BWN_TAB_16BIT:
12585                         value = *((const uint16_t *)data);
12586                         data += 2;
12587                         KASSERT(!(value & ~0xffff),
12588                             ("%s:%d: fail", __func__, __LINE__));
12589                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12590                         break;
12591                 case BWN_TAB_32BIT:
12592                         value = *((const uint32_t *)data);
12593                         data += 4;
12594                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12595                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12596                         break;
12597                 default:
12598                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12599                 }
12600         }
12601 }
12602
12603 static struct bwn_txgain
12604 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12605 {
12606         struct bwn_txgain tg;
12607         uint16_t tmp;
12608
12609         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12610         if (mac->mac_phy.rev < 2) {
12611                 tmp = BWN_PHY_READ(mac,
12612                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12613                 tg.tg_gm = tmp & 0x0007;
12614                 tg.tg_pga = (tmp & 0x0078) >> 3;
12615                 tg.tg_pad = (tmp & 0x780) >> 7;
12616                 return (tg);
12617         }
12618
12619         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12620         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12621         tg.tg_gm = tmp & 0xff;
12622         tg.tg_pga = (tmp >> 8) & 0xff;
12623         return (tg);
12624 }
12625
12626 static uint8_t
12627 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12628 {
12629
12630         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12631 }
12632
12633 static void
12634 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12635 {
12636         uint16_t pa;
12637
12638         if (mac->mac_phy.rev < 2) {
12639                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12640                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12641                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12642                 bwn_phy_lp_set_txgain_override(mac);
12643                 return;
12644         }
12645
12646         pa = bwn_phy_lp_get_pa_gain(mac);
12647         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12648             (tg->tg_pga << 8) | tg->tg_gm);
12649         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12650             tg->tg_pad | (pa << 6));
12651         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12652         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12653             tg->tg_pad | (pa << 8));
12654         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12655         bwn_phy_lp_set_txgain_override(mac);
12656 }
12657
12658 static void
12659 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12660 {
12661
12662         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12663 }
12664
12665 static void
12666 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12667 {
12668         uint16_t trsw = (tx << 1) | rx;
12669
12670         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12671         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12672 }
12673
12674 static void
12675 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12676 {
12677         struct bwn_softc *sc = mac->mac_sc;
12678         struct ifnet *ifp = sc->sc_ifp;
12679         struct ieee80211com *ic = ifp->if_l2com;
12680         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12681
12682         if (mac->mac_phy.rev < 2) {
12683                 trsw = gain & 0x1;
12684                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12685                 ext_lna = (gain & 2) >> 1;
12686
12687                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12688                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12689                     0xfbff, ext_lna << 10);
12690                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12691                     0xf7ff, ext_lna << 11);
12692                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12693         } else {
12694                 low_gain = gain & 0xffff;
12695                 high_gain = (gain >> 16) & 0xf;
12696                 ext_lna = (gain >> 21) & 0x1;
12697                 trsw = ~(gain >> 20) & 0x1;
12698
12699                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12700                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12701                     0xfdff, ext_lna << 9);
12702                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12703                     0xfbff, ext_lna << 10);
12704                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12705                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12706                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12707                         tmp = (gain >> 2) & 0x3;
12708                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12709                             0xe7ff, tmp<<11);
12710                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12711                             tmp << 3);
12712                 }
12713         }
12714
12715         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12716         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12717         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12718         if (mac->mac_phy.rev >= 2) {
12719                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12720                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12721                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12722                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12723                 }
12724                 return;
12725         }
12726         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12727 }
12728
12729 static void
12730 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12731 {
12732         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12733
12734         if (user)
12735                 plp->plp_crsusr_off = 1;
12736         else
12737                 plp->plp_crssys_off = 1;
12738
12739         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12740 }
12741
12742 static void
12743 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12744 {
12745         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12746         struct bwn_softc *sc = mac->mac_sc;
12747         struct ifnet *ifp = sc->sc_ifp;
12748         struct ieee80211com *ic = ifp->if_l2com;
12749
12750         if (user)
12751                 plp->plp_crsusr_off = 0;
12752         else
12753                 plp->plp_crssys_off = 0;
12754
12755         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12756                 return;
12757
12758         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12759                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12760         else
12761                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12762 }
12763
12764 static unsigned int
12765 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12766 {
12767         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12768         static uint8_t sqrt_table[256] = {
12769                 10, 14, 17, 20, 22, 24, 26, 28,
12770                 30, 31, 33, 34, 36, 37, 38, 40,
12771                 41, 42, 43, 44, 45, 46, 47, 48,
12772                 50, 50, 51, 52, 53, 54, 55, 56,
12773                 57, 58, 59, 60, 60, 61, 62, 63,
12774                 64, 64, 65, 66, 67, 67, 68, 69,
12775                 70, 70, 71, 72, 72, 73, 74, 74,
12776                 75, 76, 76, 77, 78, 78, 79, 80,
12777                 80, 81, 81, 82, 83, 83, 84, 84,
12778                 85, 86, 86, 87, 87, 88, 88, 89,
12779                 90, 90, 91, 91, 92, 92, 93, 93,
12780                 94, 94, 95, 95, 96, 96, 97, 97,
12781                 98, 98, 99, 100, 100, 100, 101, 101,
12782                 102, 102, 103, 103, 104, 104, 105, 105,
12783                 106, 106, 107, 107, 108, 108, 109, 109,
12784                 110, 110, 110, 111, 111, 112, 112, 113,
12785                 113, 114, 114, 114, 115, 115, 116, 116,
12786                 117, 117, 117, 118, 118, 119, 119, 120,
12787                 120, 120, 121, 121, 122, 122, 122, 123,
12788                 123, 124, 124, 124, 125, 125, 126, 126,
12789                 126, 127, 127, 128, 128, 128, 129, 129,
12790                 130, 130, 130, 131, 131, 131, 132, 132,
12791                 133, 133, 133, 134, 134, 134, 135, 135,
12792                 136, 136, 136, 137, 137, 137, 138, 138,
12793                 138, 139, 139, 140, 140, 140, 141, 141,
12794                 141, 142, 142, 142, 143, 143, 143, 144,
12795                 144, 144, 145, 145, 145, 146, 146, 146,
12796                 147, 147, 147, 148, 148, 148, 149, 149,
12797                 150, 150, 150, 150, 151, 151, 151, 152,
12798                 152, 152, 153, 153, 153, 154, 154, 154,
12799                 155, 155, 155, 156, 156, 156, 157, 157,
12800                 157, 158, 158, 158, 159, 159, 159, 160
12801         };
12802
12803         if (x == 0)
12804                 return (0);
12805         if (x >= 256) {
12806                 unsigned int tmp;
12807
12808                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12809                         /* do nothing */ ;
12810                 return (tmp);
12811         }
12812         return (sqrt_table[x - 1] / 10);
12813 }
12814
12815 static int
12816 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12817 {
12818 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12819         int _t;                                                         \
12820         _t = _x - 20;                                                   \
12821         if (_t >= 0) {                                                  \
12822                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12823         } else {                                                        \
12824                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12825         }                                                               \
12826 } while (0)
12827 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12828         int _t;                                                         \
12829         _t = _x - 11;                                                   \
12830         if (_t >= 0)                                                    \
12831                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12832         else                                                            \
12833                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12834 } while (0)
12835         struct bwn_phy_lp_iq_est ie;
12836         uint16_t v0, v1;
12837         int tmp[2], ret;
12838
12839         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12840         v0 = v1 >> 8;
12841         v1 |= 0xff;
12842
12843         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12844         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12845
12846         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12847         if (ret == 0)
12848                 goto done;
12849
12850         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12851                 ret = 0;
12852                 goto done;
12853         }
12854
12855         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12856         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12857
12858         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12859         v0 = tmp[0] >> 3;
12860         v1 = tmp[1] >> 4;
12861 done:
12862         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12863         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12864         return ret;
12865 #undef CALC_COEFF
12866 #undef CALC_COEFF2
12867 }
12868
12869 static void
12870 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12871 {
12872         static const uint16_t noisescale[] = {
12873                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12874                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12875                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12876                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12877                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12878         };
12879         static const uint16_t crsgainnft[] = {
12880                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12881                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12882                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12883                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12884                 0x013d,
12885         };
12886         static const uint16_t filterctl[] = {
12887                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12888                 0xff53, 0x0127,
12889         };
12890         static const uint32_t psctl[] = {
12891                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12892                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12893                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12894                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12895                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12896                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12897                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12898                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12899         };
12900         static const uint16_t ofdmcckgain_r0[] = {
12901                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12902                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12903                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12904                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12905                 0x755d,
12906         };
12907         static const uint16_t ofdmcckgain_r1[] = {
12908                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12909                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12910                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12911                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12912                 0x755d,
12913         };
12914         static const uint16_t gaindelta[] = {
12915                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12916                 0x0000,
12917         };
12918         static const uint32_t txpwrctl[] = {
12919                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12920                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12921                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12922                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12923                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12924                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12925                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12926                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12927                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12928                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12929                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12930                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12931                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12950                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12951                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12952                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12953                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12954                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12955                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12956                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12957                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12958                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12959                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12960                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12961                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12962                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12963                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12964                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12965                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12966                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12967                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12968                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12969                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12970                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12971                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12972                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12973                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12974                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12975                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12976                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12977                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12978                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12979                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12980                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12981                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12982                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12983                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12991                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12992                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12993                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12994                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12995                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12996                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12997                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12998                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12999                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13000                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13001                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13002                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13003                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13004                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13005                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13006                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13007                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13008                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13009                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13010                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13011                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13012                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13013                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13014                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13015                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13016                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13017                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13018                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13019                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13020                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13021                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13022                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13023                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13024                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13025                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13026                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13027                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13028                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13029                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13030                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13031                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13032                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13033                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13034                 0x00000702,
13035         };
13036
13037         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13038
13039         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13040             bwn_tab_sigsq_tbl);
13041         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13042         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13043         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13044         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13045         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13046             bwn_tab_pllfrac_tbl);
13047         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13048             bwn_tabl_iqlocal_tbl);
13049         if (mac->mac_phy.rev == 0) {
13050                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13051                     ofdmcckgain_r0);
13052                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13053                     ofdmcckgain_r0);
13054         } else {
13055                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13056                     ofdmcckgain_r1);
13057                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13058                     ofdmcckgain_r1);
13059         }
13060         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13061         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13062 }
13063
13064 static void
13065 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13066 {
13067         struct bwn_softc *sc = mac->mac_sc;
13068         int i;
13069         static const uint16_t noisescale[] = {
13070                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13071                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13072                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13073                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13074                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13075                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13076                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13077         };
13078         static const uint32_t filterctl[] = {
13079                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13080                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13081         };
13082         static const uint32_t psctl[] = {
13083                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13084                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13085                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13086                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13087         };
13088         static const uint32_t gainidx[] = {
13089                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13090                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13091                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13092                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13093                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13094                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13095                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13096                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13097                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13098                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13099                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13100                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13101                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13102                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13103                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13104                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13105                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13106                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13107                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13108                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13109                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13110                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13111                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13112                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13113                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13114                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13115                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13116                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13117                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13118                 0x0000001a, 0x64ca55ad, 0x0000001a
13119         };
13120         static const uint16_t auxgainidx[] = {
13121                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13122                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13123                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13124                 0x0004, 0x0016
13125         };
13126         static const uint16_t swctl[] = {
13127                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13128                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13129                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13130                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13131                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13132                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13133                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13134                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13135         };
13136         static const uint8_t hf[] = {
13137                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13138                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13139         };
13140         static const uint32_t gainval[] = {
13141                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13142                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13143                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13144                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13145                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13146                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13147                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13148                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13149                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13150                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13151                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13152                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13153                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13154                 0x000000f1, 0x00000000, 0x00000000
13155         };
13156         static const uint16_t gain[] = {
13157                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13158                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13159                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13160                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13161                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13162                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13163                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13164                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13165                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13166                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13167                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13168                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13169         };
13170         static const uint32_t papdeps[] = {
13171                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13172                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13173                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13174                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13175                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13176                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13177                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13178                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13179                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13180                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13181                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13182                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13183                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13184         };
13185         static const uint32_t papdmult[] = {
13186                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13187                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13188                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13189                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13190                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13191                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13192                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13193                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13194                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13195                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13196                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13197                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13198                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13199         };
13200         static const uint32_t gainidx_a0[] = {
13201                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13202                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13203                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13204                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13205                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13206                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13207                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13208                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13209                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13210                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13211                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13212                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13213                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13214         };
13215         static const uint16_t auxgainidx_a0[] = {
13216                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13217                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13218                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13219                 0x0002, 0x0014
13220         };
13221         static const uint32_t gainval_a0[] = {
13222                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13223                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13224                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13225                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13226                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13227                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13228                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13229                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13230                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13231                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13232                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13233                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13234                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13235                 0x000000f7, 0x00000000, 0x00000000
13236         };
13237         static const uint16_t gain_a0[] = {
13238                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13239                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13240                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13241                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13242                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13243                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13244                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13245                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13246                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13247                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13248                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13249                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13250         };
13251
13252         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13253
13254         for (i = 0; i < 704; i++)
13255                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13256
13257         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13258             bwn_tab_sigsq_tbl);
13259         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13260         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13261         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13262         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13263         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13264         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13265         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13266         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13267         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13268         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13269             bwn_tab_pllfrac_tbl);
13270         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13271             bwn_tabl_iqlocal_tbl);
13272         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13273         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13274
13275         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13276             (siba_get_chiprev(sc->sc_dev) == 0)) {
13277                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13278                     gainidx_a0);
13279                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13280                     auxgainidx_a0);
13281                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13282                     gainval_a0);
13283                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13284         }
13285 }
13286
13287 static void
13288 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13289 {
13290         struct bwn_softc *sc = mac->mac_sc;
13291         struct ifnet *ifp = sc->sc_ifp;
13292         struct ieee80211com *ic = ifp->if_l2com;
13293         static struct bwn_txgain_entry txgain_r2[] = {
13294                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13295                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13296                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13297                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13298                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13299                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13300                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13301                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13302                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13303                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13304                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13305                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13306                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13307                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13308                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13309                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13310                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13311                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13312                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13313                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13314                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13315                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13316                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13317                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13318                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13319                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13320                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13321                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13322                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13323                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13324                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13325                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13326                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13327                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13328                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13329                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13330                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13331                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13332                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13333                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13334                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13335                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13336                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13337                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13338                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13339                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13340                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13341                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13342                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13343                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13344                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13345                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13346                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13347                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13348                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13349                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13350                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13351                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13352                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13353                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13354                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13355                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13356                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13357                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13358         };
13359         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13360                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13361                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13362                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13363                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13364                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13365                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13366                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13367                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13368                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13369                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13370                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13371                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13372                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13373                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13374                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13375                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13376                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13377                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13378                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13379                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13380                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13381                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13382                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13383                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13384                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13385                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13386                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13387                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13388                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13389                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13390                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13391                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13392                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13393                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13394                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13395                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13396                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13397                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13398                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13399                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13400                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13401                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13402                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13403                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13404                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13405                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13406                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13407                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13408                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13409                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13410                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13411                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13412                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13413                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13414                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13415                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13416                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13417                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13418                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13419                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13420                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13421                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13422                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13423                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13424         };
13425         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13426                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13427                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13428                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13429                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13430                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13431                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13432                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13433                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13434                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13435                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13436                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13437                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13438                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13439                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13440                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13441                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13442                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13443                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13444                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13445                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13446                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13447                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13448                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13449                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13450                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13451                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13452                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13453                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13454                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13455                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13456                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13457                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13458                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13459                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13460                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13461                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13462                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13463                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13464                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13465                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13466                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13467                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13468                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13469                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13470                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13471                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13472                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13473                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13474                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13475                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13476                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13477                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13478                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13479                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13480                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13481                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13482                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13483                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13484                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13485                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13486                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13487                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13488                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13489                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13490         };
13491         static struct bwn_txgain_entry txgain_r0[] = {
13492                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13493                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13494                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13495                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13496                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13497                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13498                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13499                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13500                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13501                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13502                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13503                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13504                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13505                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13506                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13507                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13508                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13509                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13510                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13511                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13512                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13513                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13514                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13515                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13516                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13517                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13518                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13519                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13520                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13521                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13522                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13523                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13524                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13525                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13526                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13527                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13528                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13529                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13530                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13531                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13532                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13533                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13534                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13535                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13536                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13537                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13538                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13539                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13540                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13541                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13542                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13543                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13544                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13545                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13546                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13547                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13548                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13549                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13550                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13551                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13552                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13553                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13554                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13555                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13556         };
13557         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13558                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13559                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13560                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13561                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13562                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13563                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13564                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13565                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13566                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13567                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13568                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13569                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13570                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13571                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13572                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13573                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13574                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13575                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13576                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13577                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13578                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13579                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13580                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13581                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13582                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13583                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13584                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13585                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13586                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13587                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13588                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13589                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13590                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13591                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13592                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13593                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13594                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13595                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13596                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13597                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13598                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13599                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13600                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13601                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13602                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13603                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13604                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13605                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13606                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13607                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13608                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13609                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13610                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13611                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13612                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13613                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13614                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13615                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13616                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13617                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13618                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13619                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13620                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13621                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13622         };
13623         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13624                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13625                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13626                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13627                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13628                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13629                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13630                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13631                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13632                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13633                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13634                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13635                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13636                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13637                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13638                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13639                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13640                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13641                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13642                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13643                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13644                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13645                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13646                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13647                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13648                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13649                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13650                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13651                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13652                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13653                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13654                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13655                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13656                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13657                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13658                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13659                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13660                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13661                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13662                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13663                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13664                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13665                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13666                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13667                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13668                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13669                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13670                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13671                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13672                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13673                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13674                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13675                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13676                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13677                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13678                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13679                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13680                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13681                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13682                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13683                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13684                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13685                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13686                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13687                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13688         };
13689         static struct bwn_txgain_entry txgain_r1[] = {
13690                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13691                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13692                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13693                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13694                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13695                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13696                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13697                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13698                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13699                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13700                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13701                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13702                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13703                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13704                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13705                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13706                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13707                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13708                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13709                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13710                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13711                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13712                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13713                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13714                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13715                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13716                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13717                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13718                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13719                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13720                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13721                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13722                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13723                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13724                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13725                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13726                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13727                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13728                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13729                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13730                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13731                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13732                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13733                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13734                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13735                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13736                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13737                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13738                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13739                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13740                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13741                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13742                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13743                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13744                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13745                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13746                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13747                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13748                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13749                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13750                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13751                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13752                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13753                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13754                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13755                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13756                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13757                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13758                 { 7, 11, 6, 0, 71 }
13759         };
13760         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13761                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13762                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13763                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13764                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13765                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13766                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13767                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13768                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13769                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13770                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13771                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13772                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13773                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13774                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13775                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13776                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13777                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13778                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13779                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13780                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13781                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13782                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13783                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13784                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13785                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13786                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13787                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13788                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13789                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13790                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13791                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13792                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13793                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13794                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13795                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13796                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13797                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13798                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13799                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13800                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13801                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13802                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13803                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13804                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13805                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13806                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13807                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13808                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13809                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13810                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13811                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13812                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13813                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13814                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13815                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13816                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13817                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13818                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13819                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13820                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13821                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13822                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13823                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13824                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13825         };
13826         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13827                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13828                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13829                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13830                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13831                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13832                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13833                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13834                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13835                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13836                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13837                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13838                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13839                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13840                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13841                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13842                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13843                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13844                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13845                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13846                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13847                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13848                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13849                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13850                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13851                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13852                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13853                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13854                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13855                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13856                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13857                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13858                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13859                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13860                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13861                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13862                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13863                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13864                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13865                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13866                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13867                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13868                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13869                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13870                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13871                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13872                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13873                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13874                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13875                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13876                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13877                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13878                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13879                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13880                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13881                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13882                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13883                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13884                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13885                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13886                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13887                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13888                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13889                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13890                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13891         };
13892
13893         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13894                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13895                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13896                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13897                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13898                             txgain_2ghz_r2);
13899                 else
13900                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13901                             txgain_5ghz_r2);
13902                 return;
13903         }
13904
13905         if (mac->mac_phy.rev == 0) {
13906                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13907                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13908                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13909                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13910                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13911                             txgain_2ghz_r0);
13912                 else
13913                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13914                             txgain_5ghz_r0);
13915                 return;
13916         }
13917
13918         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13919             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13920                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13921         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13922                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13923         else
13924                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13925 }
13926
13927 static void
13928 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13929 {
13930         uint32_t offset, type;
13931
13932         type = BWN_TAB_GETTYPE(typeoffset);
13933         offset = BWN_TAB_GETOFFSET(typeoffset);
13934         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13935
13936         switch (type) {
13937         case BWN_TAB_8BIT:
13938                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13939                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13940                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13941                 break;
13942         case BWN_TAB_16BIT:
13943                 KASSERT(!(value & ~0xffff),
13944                     ("%s:%d: fail", __func__, __LINE__));
13945                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13946                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13947                 break;
13948         case BWN_TAB_32BIT:
13949                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13950                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13951                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13952                 break;
13953         default:
13954                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13955         }
13956 }
13957
13958 static int
13959 bwn_phy_lp_loopback(struct bwn_mac *mac)
13960 {
13961         struct bwn_phy_lp_iq_est ie;
13962         int i, index = -1;
13963         uint32_t tmp;
13964
13965         memset(&ie, 0, sizeof(ie));
13966
13967         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13968         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13969         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13970         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13971         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13972         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13973         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13974         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13975         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13976         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13977         for (i = 0; i < 32; i++) {
13978                 bwn_phy_lp_set_rxgain_idx(mac, i);
13979                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13980                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13981                         continue;
13982                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13983                 if ((tmp > 4000) && (tmp < 10000)) {
13984                         index = i;
13985                         break;
13986                 }
13987         }
13988         bwn_phy_lp_ddfs_turnoff(mac);
13989         return (index);
13990 }
13991
13992 static void
13993 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13994 {
13995
13996         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13997 }
13998
13999 static void
14000 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14001     int incr1, int incr2, int scale_idx)
14002 {
14003
14004         bwn_phy_lp_ddfs_turnoff(mac);
14005         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14006         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14007         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14008         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14009         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14010         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14011         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14012         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14013         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14014         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14015 }
14016
14017 static uint8_t
14018 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14019     struct bwn_phy_lp_iq_est *ie)
14020 {
14021         int i;
14022
14023         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14024         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14025         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14026         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14027         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14028
14029         for (i = 0; i < 500; i++) {
14030                 if (!(BWN_PHY_READ(mac,
14031                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14032                         break;
14033                 DELAY(1000);
14034         }
14035         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14036                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14037                 return 0;
14038         }
14039
14040         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14041         ie->ie_iqprod <<= 16;
14042         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14043         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14044         ie->ie_ipwr <<= 16;
14045         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14046         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14047         ie->ie_qpwr <<= 16;
14048         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14049
14050         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14051         return 1;
14052 }
14053
14054 static uint32_t
14055 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14056 {
14057         uint32_t offset, type, value;
14058
14059         type = BWN_TAB_GETTYPE(typeoffset);
14060         offset = BWN_TAB_GETOFFSET(typeoffset);
14061         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14062
14063         switch (type) {
14064         case BWN_TAB_8BIT:
14065                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14066                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14067                 break;
14068         case BWN_TAB_16BIT:
14069                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14070                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14071                 break;
14072         case BWN_TAB_32BIT:
14073                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14074                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14075                 value <<= 16;
14076                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14077                 break;
14078         default:
14079                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14080                 value = 0;
14081         }
14082
14083         return (value);
14084 }
14085
14086 static void
14087 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14088 {
14089
14090         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14091         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14092 }
14093
14094 static void
14095 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14096 {
14097         uint16_t ctl;
14098
14099         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14100         ctl |= dac << 7;
14101         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14102 }
14103
14104 static void
14105 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14106 {
14107
14108         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14109         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14110 }
14111
14112 static void
14113 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14114 {
14115
14116         if (mac->mac_phy.rev < 2)
14117                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14118         else {
14119                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14120                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14121         }
14122         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14123 }
14124
14125 static uint16_t
14126 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14127 {
14128
14129         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14130 }
14131
14132 static uint8_t
14133 bwn_nbits(int32_t val)
14134 {
14135         uint32_t tmp;
14136         uint8_t nbits = 0;
14137
14138         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14139                 nbits++;
14140         return (nbits);
14141 }
14142
14143 static void
14144 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14145     struct bwn_txgain_entry *table)
14146 {
14147         int i;
14148
14149         for (i = offset; i < count; i++)
14150                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14151 }
14152
14153 static void
14154 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14155     struct bwn_txgain_entry data)
14156 {
14157
14158         if (mac->mac_phy.rev >= 2)
14159                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14160         else
14161                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14162 }
14163
14164 static void
14165 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14166     struct bwn_txgain_entry te)
14167 {
14168         struct bwn_softc *sc = mac->mac_sc;
14169         struct ifnet *ifp = sc->sc_ifp;
14170         struct ieee80211com *ic = ifp->if_l2com;
14171         uint32_t tmp;
14172
14173         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14174
14175         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14176         if (mac->mac_phy.rev >= 3) {
14177                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14178                     (0x10 << 24) : (0x70 << 24));
14179         } else {
14180                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14181                     (0x14 << 24) : (0x7f << 24));
14182         }
14183         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14184         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14185             te.te_bbmult << 20 | te.te_dac << 28);
14186 }
14187
14188 static void
14189 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14190     struct bwn_txgain_entry te)
14191 {
14192
14193         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14194
14195         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14196             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14197             te.te_dac);
14198         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14199 }
14200
14201 static void
14202 bwn_sysctl_node(struct bwn_softc *sc)
14203 {
14204         device_t dev = sc->sc_dev;
14205         struct bwn_mac *mac;
14206         struct bwn_stats *stats;
14207
14208         /* XXX assume that count of MAC is only 1. */
14209
14210         if ((mac = sc->sc_curmac) == NULL)
14211                 return;
14212         stats = &mac->mac_stats;
14213
14214         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14215             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14216             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14217         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14218             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14219             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14220         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14221             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14222             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14223
14224 #ifdef BWN_DEBUG
14225         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14226             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14227             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14228 #endif
14229 }
14230
14231 static device_method_t bwn_methods[] = {
14232         /* Device interface */
14233         DEVMETHOD(device_probe,         bwn_probe),
14234         DEVMETHOD(device_attach,        bwn_attach),
14235         DEVMETHOD(device_detach,        bwn_detach),
14236         DEVMETHOD(device_suspend,       bwn_suspend),
14237         DEVMETHOD(device_resume,        bwn_resume),
14238         KOBJMETHOD_END
14239 };
14240 static driver_t bwn_driver = {
14241         "bwn",
14242         bwn_methods,
14243         sizeof(struct bwn_softc)
14244 };
14245 static devclass_t bwn_devclass;
14246 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14247 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14248 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14249 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14250 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);