]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/dev/bwn/if_bwn.c
MFC r217511:
[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         struct bwn_vap *bvp = BWN_VAP(vap);
8333         struct ieee80211com *ic= vap->iv_ic;
8334         struct ifnet *ifp = ic->ic_ifp;
8335         enum ieee80211_state ostate = vap->iv_state;
8336         struct bwn_softc *sc = ifp->if_softc;
8337         struct bwn_mac *mac = sc->sc_curmac;
8338         int error;
8339
8340         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8341             ieee80211_state_name[vap->iv_state],
8342             ieee80211_state_name[nstate]);
8343
8344         error = bvp->bv_newstate(vap, nstate, arg);
8345         if (error != 0)
8346                 return (error);
8347
8348         BWN_LOCK(sc);
8349
8350         bwn_led_newstate(mac, nstate);
8351
8352         /*
8353          * Clear the BSSID when we stop a STA
8354          */
8355         if (vap->iv_opmode == IEEE80211_M_STA) {
8356                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8357                         /*
8358                          * Clear out the BSSID.  If we reassociate to
8359                          * the same AP, this will reinialize things
8360                          * correctly...
8361                          */
8362                         if (ic->ic_opmode == IEEE80211_M_STA &&
8363                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8364                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8365                                 bwn_set_macaddr(mac);
8366                         }
8367                 }
8368         }
8369
8370         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8371             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8372                 /* XXX nothing to do? */
8373         } else if (nstate == IEEE80211_S_RUN) {
8374                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8375                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8376                 bwn_set_opmode(mac);
8377                 bwn_set_pretbtt(mac);
8378                 bwn_spu_setdelay(mac, 0);
8379                 bwn_set_macaddr(mac);
8380         }
8381
8382         BWN_UNLOCK(sc);
8383
8384         return (error);
8385 }
8386
8387 static void
8388 bwn_set_pretbtt(struct bwn_mac *mac)
8389 {
8390         struct bwn_softc *sc = mac->mac_sc;
8391         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8392         uint16_t pretbtt;
8393
8394         if (ic->ic_opmode == IEEE80211_M_IBSS)
8395                 pretbtt = 2;
8396         else
8397                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8398         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8399         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8400 }
8401
8402 static int
8403 bwn_intr(void *arg)
8404 {
8405         struct bwn_mac *mac = arg;
8406         struct bwn_softc *sc = mac->mac_sc;
8407         uint32_t reason;
8408
8409         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8410             (sc->sc_flags & BWN_FLAG_INVALID))
8411                 return (FILTER_STRAY);
8412
8413         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8414         if (reason == 0xffffffff)       /* shared IRQ */
8415                 return (FILTER_STRAY);
8416         reason &= mac->mac_intr_mask;
8417         if (reason == 0)
8418                 return (FILTER_HANDLED);
8419
8420         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8421         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8422         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8423         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8424         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8425         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8426         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8427         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8428         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8429         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8430         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8431
8432         /* Disable interrupts. */
8433         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8434
8435         mac->mac_reason_intr = reason;
8436
8437         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8438         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8439
8440         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8441         return (FILTER_HANDLED);
8442 }
8443
8444 static void
8445 bwn_intrtask(void *arg, int npending)
8446 {
8447         struct bwn_mac *mac = arg;
8448         struct bwn_softc *sc = mac->mac_sc;
8449         struct ifnet *ifp = sc->sc_ifp;
8450         uint32_t merged = 0;
8451         int i, tx = 0, rx = 0;
8452
8453         BWN_LOCK(sc);
8454         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8455             (sc->sc_flags & BWN_FLAG_INVALID)) {
8456                 BWN_UNLOCK(sc);
8457                 return;
8458         }
8459
8460         for (i = 0; i < N(mac->mac_reason); i++)
8461                 merged |= mac->mac_reason[i];
8462
8463         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8464                 device_printf(sc->sc_dev, "MAC trans error\n");
8465
8466         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8467                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8468                 mac->mac_phy.txerrors--;
8469                 if (mac->mac_phy.txerrors == 0) {
8470                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8471                         bwn_restart(mac, "PHY TX errors");
8472                 }
8473         }
8474
8475         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8476                 if (merged & BWN_DMAINTR_FATALMASK) {
8477                         device_printf(sc->sc_dev,
8478                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8479                             mac->mac_reason[0], mac->mac_reason[1],
8480                             mac->mac_reason[2], mac->mac_reason[3],
8481                             mac->mac_reason[4], mac->mac_reason[5]);
8482                         bwn_restart(mac, "DMA error");
8483                         BWN_UNLOCK(sc);
8484                         return;
8485                 }
8486                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8487                         device_printf(sc->sc_dev,
8488                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8489                             mac->mac_reason[0], mac->mac_reason[1],
8490                             mac->mac_reason[2], mac->mac_reason[3],
8491                             mac->mac_reason[4], mac->mac_reason[5]);
8492                 }
8493         }
8494
8495         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8496                 bwn_intr_ucode_debug(mac);
8497         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8498                 bwn_intr_tbtt_indication(mac);
8499         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8500                 bwn_intr_atim_end(mac);
8501         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8502                 bwn_intr_beacon(mac);
8503         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8504                 bwn_intr_pmq(mac);
8505         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8506                 bwn_intr_noise(mac);
8507
8508         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8509                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8510                         bwn_dma_rx(mac->mac_method.dma.rx);
8511                         rx = 1;
8512                 }
8513         } else
8514                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8515
8516         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8519         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8520         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8521
8522         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8523                 bwn_intr_txeof(mac);
8524                 tx = 1;
8525         }
8526
8527         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8528
8529         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8530                 int evt = BWN_LED_EVENT_NONE;
8531
8532                 if (tx && rx) {
8533                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8534                                 evt = BWN_LED_EVENT_RX;
8535                         else
8536                                 evt = BWN_LED_EVENT_TX;
8537                 } else if (tx) {
8538                         evt = BWN_LED_EVENT_TX;
8539                 } else if (rx) {
8540                         evt = BWN_LED_EVENT_RX;
8541                 } else if (rx == 0) {
8542                         evt = BWN_LED_EVENT_POLL;
8543                 }
8544
8545                 if (evt != BWN_LED_EVENT_NONE)
8546                         bwn_led_event(mac, evt);
8547        }
8548
8549         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8550                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8551                         bwn_start_locked(ifp);
8552         }
8553
8554         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8555         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8556
8557         BWN_UNLOCK(sc);
8558 }
8559
8560 static void
8561 bwn_restart(struct bwn_mac *mac, const char *msg)
8562 {
8563         struct bwn_softc *sc = mac->mac_sc;
8564         struct ifnet *ifp = sc->sc_ifp;
8565         struct ieee80211com *ic = ifp->if_l2com;
8566
8567         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8568                 return;
8569
8570         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8571         ieee80211_runtask(ic, &mac->mac_hwreset);
8572 }
8573
8574 static void
8575 bwn_intr_ucode_debug(struct bwn_mac *mac)
8576 {
8577         struct bwn_softc *sc = mac->mac_sc;
8578         uint16_t reason;
8579
8580         if (mac->mac_fw.opensource == 0)
8581                 return;
8582
8583         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8584         switch (reason) {
8585         case BWN_DEBUGINTR_PANIC:
8586                 bwn_handle_fwpanic(mac);
8587                 break;
8588         case BWN_DEBUGINTR_DUMP_SHM:
8589                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8590                 break;
8591         case BWN_DEBUGINTR_DUMP_REGS:
8592                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8593                 break;
8594         case BWN_DEBUGINTR_MARKER:
8595                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8596                 break;
8597         default:
8598                 device_printf(sc->sc_dev,
8599                     "ucode debug unknown reason: %#x\n", reason);
8600         }
8601
8602         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8603             BWN_DEBUGINTR_ACK);
8604 }
8605
8606 static void
8607 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8608 {
8609         struct bwn_softc *sc = mac->mac_sc;
8610         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8611
8612         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8613                 bwn_psctl(mac, 0);
8614         if (ic->ic_opmode == IEEE80211_M_IBSS)
8615                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8616 }
8617
8618 static void
8619 bwn_intr_atim_end(struct bwn_mac *mac)
8620 {
8621
8622         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8623                 BWN_WRITE_4(mac, BWN_MACCMD,
8624                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8625                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8626         }
8627 }
8628
8629 static void
8630 bwn_intr_beacon(struct bwn_mac *mac)
8631 {
8632         struct bwn_softc *sc = mac->mac_sc;
8633         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8634         uint32_t cmd, beacon0, beacon1;
8635
8636         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8637             ic->ic_opmode == IEEE80211_M_MBSS)
8638                 return;
8639
8640         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8641
8642         cmd = BWN_READ_4(mac, BWN_MACCMD);
8643         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8644         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8645
8646         if (beacon0 && beacon1) {
8647                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8648                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8649                 return;
8650         }
8651
8652         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8653                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8654                 bwn_load_beacon0(mac);
8655                 bwn_load_beacon1(mac);
8656                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8657                 cmd |= BWN_MACCMD_BEACON0_VALID;
8658                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8659         } else {
8660                 if (!beacon0) {
8661                         bwn_load_beacon0(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 if (!beacon1) {
8666                         bwn_load_beacon1(mac);
8667                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8668                         cmd |= BWN_MACCMD_BEACON1_VALID;
8669                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8670                 }
8671         }
8672 }
8673
8674 static void
8675 bwn_intr_pmq(struct bwn_mac *mac)
8676 {
8677         uint32_t tmp;
8678
8679         while (1) {
8680                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8681                 if (!(tmp & 0x00000008))
8682                         break;
8683         }
8684         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8685 }
8686
8687 static void
8688 bwn_intr_noise(struct bwn_mac *mac)
8689 {
8690         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8691         uint16_t tmp;
8692         uint8_t noise[4];
8693         uint8_t i, j;
8694         int32_t average;
8695
8696         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8697                 return;
8698
8699         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8700         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8701         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8702             noise[3] == 0x7f)
8703                 goto new;
8704
8705         KASSERT(mac->mac_noise.noi_nsamples < 8,
8706             ("%s:%d: fail", __func__, __LINE__));
8707         i = mac->mac_noise.noi_nsamples;
8708         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8709         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8710         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8711         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8712         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8713         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8714         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8715         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8716         mac->mac_noise.noi_nsamples++;
8717         if (mac->mac_noise.noi_nsamples == 8) {
8718                 average = 0;
8719                 for (i = 0; i < 8; i++) {
8720                         for (j = 0; j < 4; j++)
8721                                 average += mac->mac_noise.noi_samples[i][j];
8722                 }
8723                 average = (((average / 32) * 125) + 64) / 128;
8724                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8725                 if (tmp >= 8)
8726                         average += 2;
8727                 else
8728                         average -= 25;
8729                 average -= (tmp == 8) ? 72 : 48;
8730
8731                 mac->mac_stats.link_noise = average;
8732                 mac->mac_noise.noi_running = 0;
8733                 return;
8734         }
8735 new:
8736         bwn_noise_gensample(mac);
8737 }
8738
8739 static int
8740 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8741 {
8742         struct bwn_mac *mac = prq->prq_mac;
8743         struct bwn_softc *sc = mac->mac_sc;
8744         unsigned int i;
8745
8746         BWN_ASSERT_LOCKED(sc);
8747
8748         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8749                 return (0);
8750
8751         for (i = 0; i < 5000; i++) {
8752                 if (bwn_pio_rxeof(prq) == 0)
8753                         break;
8754         }
8755         if (i >= 5000)
8756                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8757         return ((i > 0) ? 1 : 0);
8758 }
8759
8760 static void
8761 bwn_dma_rx(struct bwn_dma_ring *dr)
8762 {
8763         int slot, curslot;
8764
8765         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8766         curslot = dr->get_curslot(dr);
8767         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8768             ("%s:%d: fail", __func__, __LINE__));
8769
8770         slot = dr->dr_curslot;
8771         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8772                 bwn_dma_rxeof(dr, &slot);
8773
8774         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8775             BUS_DMASYNC_PREWRITE);
8776
8777         dr->set_curslot(dr, slot);
8778         dr->dr_curslot = slot;
8779 }
8780
8781 static void
8782 bwn_intr_txeof(struct bwn_mac *mac)
8783 {
8784         struct bwn_txstatus stat;
8785         uint32_t stat0, stat1;
8786         uint16_t tmp;
8787
8788         BWN_ASSERT_LOCKED(mac->mac_sc);
8789
8790         while (1) {
8791                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8792                 if (!(stat0 & 0x00000001))
8793                         break;
8794                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8795
8796                 stat.cookie = (stat0 >> 16);
8797                 stat.seq = (stat1 & 0x0000ffff);
8798                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8799                 tmp = (stat0 & 0x0000ffff);
8800                 stat.framecnt = ((tmp & 0xf000) >> 12);
8801                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8802                 stat.sreason = ((tmp & 0x001c) >> 2);
8803                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8804                 stat.im = (tmp & 0x0040) ? 1 : 0;
8805                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8806                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8807
8808                 bwn_handle_txeof(mac, &stat);
8809         }
8810 }
8811
8812 static void
8813 bwn_hwreset(void *arg, int npending)
8814 {
8815         struct bwn_mac *mac = arg;
8816         struct bwn_softc *sc = mac->mac_sc;
8817         int error = 0;
8818         int prev_status;
8819
8820         BWN_LOCK(sc);
8821
8822         prev_status = mac->mac_status;
8823         if (prev_status >= BWN_MAC_STATUS_STARTED)
8824                 bwn_core_stop(mac);
8825         if (prev_status >= BWN_MAC_STATUS_INITED)
8826                 bwn_core_exit(mac);
8827
8828         if (prev_status >= BWN_MAC_STATUS_INITED) {
8829                 error = bwn_core_init(mac);
8830                 if (error)
8831                         goto out;
8832         }
8833         if (prev_status >= BWN_MAC_STATUS_STARTED)
8834                 bwn_core_start(mac);
8835 out:
8836         if (error) {
8837                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8838                 sc->sc_curmac = NULL;
8839         }
8840         BWN_UNLOCK(sc);
8841 }
8842
8843 static void
8844 bwn_handle_fwpanic(struct bwn_mac *mac)
8845 {
8846         struct bwn_softc *sc = mac->mac_sc;
8847         uint16_t reason;
8848
8849         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8850         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8851
8852         if (reason == BWN_FWPANIC_RESTART)
8853                 bwn_restart(mac, "ucode panic");
8854 }
8855
8856 static void
8857 bwn_load_beacon0(struct bwn_mac *mac)
8858 {
8859
8860         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8861 }
8862
8863 static void
8864 bwn_load_beacon1(struct bwn_mac *mac)
8865 {
8866
8867         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8868 }
8869
8870 static uint32_t
8871 bwn_jssi_read(struct bwn_mac *mac)
8872 {
8873         uint32_t val = 0;
8874
8875         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8876         val <<= 16;
8877         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8878
8879         return (val);
8880 }
8881
8882 static void
8883 bwn_noise_gensample(struct bwn_mac *mac)
8884 {
8885         uint32_t jssi = 0x7f7f7f7f;
8886
8887         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8888         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8889         BWN_WRITE_4(mac, BWN_MACCMD,
8890             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8891 }
8892
8893 static int
8894 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8895 {
8896         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8897
8898         return (dr->dr_numslots - dr->dr_usedslot);
8899 }
8900
8901 static int
8902 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8903 {
8904         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8905
8906         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8907             ("%s:%d: fail", __func__, __LINE__));
8908         if (slot == dr->dr_numslots - 1)
8909                 return (0);
8910         return (slot + 1);
8911 }
8912
8913 static void
8914 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8915 {
8916         struct bwn_mac *mac = dr->dr_mac;
8917         struct bwn_softc *sc = mac->mac_sc;
8918         struct bwn_dma *dma = &mac->mac_method.dma;
8919         struct bwn_dmadesc_generic *desc;
8920         struct bwn_dmadesc_meta *meta;
8921         struct bwn_rxhdr4 *rxhdr;
8922         struct ifnet *ifp = sc->sc_ifp;
8923         struct mbuf *m;
8924         uint32_t macstat;
8925         int32_t tmp;
8926         int cnt = 0;
8927         uint16_t len;
8928
8929         dr->getdesc(dr, *slot, &desc, &meta);
8930
8931         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8932         m = meta->mt_m;
8933
8934         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8935                 ifp->if_ierrors++;
8936                 return;
8937         }
8938
8939         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8940         len = le16toh(rxhdr->frame_len);
8941         if (len <= 0) {
8942                 ifp->if_ierrors++;
8943                 return;
8944         }
8945         if (bwn_dma_check_redzone(dr, m)) {
8946                 device_printf(sc->sc_dev, "redzone error.\n");
8947                 bwn_dma_set_redzone(dr, m);
8948                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8949                     BUS_DMASYNC_PREWRITE);
8950                 return;
8951         }
8952         if (len > dr->dr_rx_bufsize) {
8953                 tmp = len;
8954                 while (1) {
8955                         dr->getdesc(dr, *slot, &desc, &meta);
8956                         bwn_dma_set_redzone(dr, meta->mt_m);
8957                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8958                             BUS_DMASYNC_PREWRITE);
8959                         *slot = bwn_dma_nextslot(dr, *slot);
8960                         cnt++;
8961                         tmp -= dr->dr_rx_bufsize;
8962                         if (tmp <= 0)
8963                                 break;
8964                 }
8965                 device_printf(sc->sc_dev, "too small buffer "
8966                        "(len %u buffer %u dropped %d)\n",
8967                        len, dr->dr_rx_bufsize, cnt);
8968                 return;
8969         }
8970         macstat = le32toh(rxhdr->mac_status);
8971         if (macstat & BWN_RX_MAC_FCSERR) {
8972                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8973                         device_printf(sc->sc_dev, "RX drop\n");
8974                         return;
8975                 }
8976         }
8977
8978         m->m_pkthdr.rcvif = ifp;
8979         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8980         m_adj(m, dr->dr_frameoffset);
8981
8982         bwn_rxeof(dr->dr_mac, m, rxhdr);
8983 }
8984
8985 static void
8986 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8987 {
8988         struct bwn_dma_ring *dr;
8989         struct bwn_dmadesc_generic *desc;
8990         struct bwn_dmadesc_meta *meta;
8991         struct bwn_pio_txqueue *tq;
8992         struct bwn_pio_txpkt *tp = NULL;
8993         struct bwn_softc *sc = mac->mac_sc;
8994         struct bwn_stats *stats = &mac->mac_stats;
8995         struct ieee80211_node *ni;
8996         struct ieee80211vap *vap;
8997         int retrycnt = 0, slot;
8998
8999         BWN_ASSERT_LOCKED(mac->mac_sc);
9000
9001         if (status->im)
9002                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9003         if (status->ampdu)
9004                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9005         if (status->rtscnt) {
9006                 if (status->rtscnt == 0xf)
9007                         stats->rtsfail++;
9008                 else
9009                         stats->rts++;
9010         }
9011
9012         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9013                 if (status->ack) {
9014                         dr = bwn_dma_parse_cookie(mac, status,
9015                             status->cookie, &slot);
9016                         if (dr == NULL) {
9017                                 device_printf(sc->sc_dev,
9018                                     "failed to parse cookie\n");
9019                                 return;
9020                         }
9021                         while (1) {
9022                                 dr->getdesc(dr, slot, &desc, &meta);
9023                                 if (meta->mt_islast) {
9024                                         ni = meta->mt_ni;
9025                                         vap = ni->ni_vap;
9026                                         ieee80211_ratectl_tx_complete(vap, ni,
9027                                             status->ack ?
9028                                               IEEE80211_RATECTL_TX_SUCCESS :
9029                                               IEEE80211_RATECTL_TX_FAILURE,
9030                                             &retrycnt, 0);
9031                                         break;
9032                                 }
9033                                 slot = bwn_dma_nextslot(dr, slot);
9034                         }
9035                 }
9036                 bwn_dma_handle_txeof(mac, status);
9037         } else {
9038                 if (status->ack) {
9039                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9040                         if (tq == NULL) {
9041                                 device_printf(sc->sc_dev,
9042                                     "failed to parse cookie\n");
9043                                 return;
9044                         }
9045                         ni = tp->tp_ni;
9046                         vap = ni->ni_vap;
9047                         ieee80211_ratectl_tx_complete(vap, ni,
9048                             status->ack ?
9049                               IEEE80211_RATECTL_TX_SUCCESS :
9050                               IEEE80211_RATECTL_TX_FAILURE,
9051                             &retrycnt, 0);
9052                 }
9053                 bwn_pio_handle_txeof(mac, status);
9054         }
9055
9056         bwn_phy_txpower_check(mac, 0);
9057 }
9058
9059 static uint8_t
9060 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9061 {
9062         struct bwn_mac *mac = prq->prq_mac;
9063         struct bwn_softc *sc = mac->mac_sc;
9064         struct bwn_rxhdr4 rxhdr;
9065         struct ifnet *ifp = sc->sc_ifp;
9066         struct mbuf *m;
9067         uint32_t ctl32, macstat, v32;
9068         unsigned int i, padding;
9069         uint16_t ctl16, len, totlen, v16;
9070         unsigned char *mp;
9071         char *data;
9072
9073         memset(&rxhdr, 0, sizeof(rxhdr));
9074
9075         if (prq->prq_rev >= 8) {
9076                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9077                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9078                         return (0);
9079                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9080                     BWN_PIO8_RXCTL_FRAMEREADY);
9081                 for (i = 0; i < 10; i++) {
9082                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9083                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9084                                 goto ready;
9085                         DELAY(10);
9086                 }
9087         } else {
9088                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9089                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9090                         return (0);
9091                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9092                     BWN_PIO_RXCTL_FRAMEREADY);
9093                 for (i = 0; i < 10; i++) {
9094                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9095                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9096                                 goto ready;
9097                         DELAY(10);
9098                 }
9099         }
9100         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9101         return (1);
9102 ready:
9103         if (prq->prq_rev >= 8)
9104                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9105                     prq->prq_base + BWN_PIO8_RXDATA);
9106         else
9107                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9108                     prq->prq_base + BWN_PIO_RXDATA);
9109         len = le16toh(rxhdr.frame_len);
9110         if (len > 0x700) {
9111                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9112                 goto error;
9113         }
9114         if (len == 0) {
9115                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9116                 goto error;
9117         }
9118
9119         macstat = le32toh(rxhdr.mac_status);
9120         if (macstat & BWN_RX_MAC_FCSERR) {
9121                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9122                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9123                         goto error;
9124                 }
9125         }
9126
9127         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9128         totlen = len + padding;
9129         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9130         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9131         if (m == NULL) {
9132                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9133                 goto error;
9134         }
9135         mp = mtod(m, unsigned char *);
9136         if (prq->prq_rev >= 8) {
9137                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9138                     prq->prq_base + BWN_PIO8_RXDATA);
9139                 if (totlen & 3) {
9140                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9141                         data = &(mp[totlen - 1]);
9142                         switch (totlen & 3) {
9143                         case 3:
9144                                 *data = (v32 >> 16);
9145                                 data--;
9146                         case 2:
9147                                 *data = (v32 >> 8);
9148                                 data--;
9149                         case 1:
9150                                 *data = v32;
9151                         }
9152                 }
9153         } else {
9154                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9155                     prq->prq_base + BWN_PIO_RXDATA);
9156                 if (totlen & 1) {
9157                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9158                         mp[totlen - 1] = v16;
9159                 }
9160         }
9161
9162         m->m_pkthdr.rcvif = ifp;
9163         m->m_len = m->m_pkthdr.len = totlen;
9164
9165         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9166
9167         return (1);
9168 error:
9169         if (prq->prq_rev >= 8)
9170                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9171                     BWN_PIO8_RXCTL_DATAREADY);
9172         else
9173                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9174         return (1);
9175 }
9176
9177 static int
9178 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9179     struct bwn_dmadesc_meta *meta, int init)
9180 {
9181         struct bwn_mac *mac = dr->dr_mac;
9182         struct bwn_dma *dma = &mac->mac_method.dma;
9183         struct bwn_rxhdr4 *hdr;
9184         bus_dmamap_t map;
9185         bus_addr_t paddr;
9186         struct mbuf *m;
9187         int error;
9188
9189         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9190         if (m == NULL) {
9191                 error = ENOBUFS;
9192
9193                 /*
9194                  * If the NIC is up and running, we need to:
9195                  * - Clear RX buffer's header.
9196                  * - Restore RX descriptor settings.
9197                  */
9198                 if (init)
9199                         return (error);
9200                 else
9201                         goto back;
9202         }
9203         m->m_len = m->m_pkthdr.len = MCLBYTES;
9204
9205         bwn_dma_set_redzone(dr, m);
9206
9207         /*
9208          * Try to load RX buf into temporary DMA map
9209          */
9210         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9211             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9212         if (error) {
9213                 m_freem(m);
9214
9215                 /*
9216                  * See the comment above
9217                  */
9218                 if (init)
9219                         return (error);
9220                 else
9221                         goto back;
9222         }
9223
9224         if (!init)
9225                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9226         meta->mt_m = m;
9227         meta->mt_paddr = paddr;
9228
9229         /*
9230          * Swap RX buf's DMA map with the loaded temporary one
9231          */
9232         map = meta->mt_dmap;
9233         meta->mt_dmap = dr->dr_spare_dmap;
9234         dr->dr_spare_dmap = map;
9235
9236 back:
9237         /*
9238          * Clear RX buf header
9239          */
9240         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9241         bzero(hdr, sizeof(*hdr));
9242         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9243             BUS_DMASYNC_PREWRITE);
9244
9245         /*
9246          * Setup RX buf descriptor
9247          */
9248         dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9249             sizeof(*hdr), 0, 0, 0);
9250         return (error);
9251 }
9252
9253 static void
9254 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9255                  bus_size_t mapsz __unused, int error)
9256 {
9257
9258         if (!error) {
9259                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9260                 *((bus_addr_t *)arg) = seg->ds_addr;
9261         }
9262 }
9263
9264 static int
9265 bwn_hwrate2ieeerate(int rate)
9266 {
9267
9268         switch (rate) {
9269         case BWN_CCK_RATE_1MB:
9270                 return (2);
9271         case BWN_CCK_RATE_2MB:
9272                 return (4);
9273         case BWN_CCK_RATE_5MB:
9274                 return (11);
9275         case BWN_CCK_RATE_11MB:
9276                 return (22);
9277         case BWN_OFDM_RATE_6MB:
9278                 return (12);
9279         case BWN_OFDM_RATE_9MB:
9280                 return (18);
9281         case BWN_OFDM_RATE_12MB:
9282                 return (24);
9283         case BWN_OFDM_RATE_18MB:
9284                 return (36);
9285         case BWN_OFDM_RATE_24MB:
9286                 return (48);
9287         case BWN_OFDM_RATE_36MB:
9288                 return (72);
9289         case BWN_OFDM_RATE_48MB:
9290                 return (96);
9291         case BWN_OFDM_RATE_54MB:
9292                 return (108);
9293         default:
9294                 printf("Ooops\n");
9295                 return (0);
9296         }
9297 }
9298
9299 static void
9300 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9301 {
9302         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9303         struct bwn_plcp6 *plcp;
9304         struct bwn_softc *sc = mac->mac_sc;
9305         struct ieee80211_frame_min *wh;
9306         struct ieee80211_node *ni;
9307         struct ifnet *ifp = sc->sc_ifp;
9308         struct ieee80211com *ic = ifp->if_l2com;
9309         uint32_t macstat;
9310         int padding, rate, rssi = 0, noise = 0, type;
9311         uint16_t phytype, phystat0, phystat3, chanstat;
9312         unsigned char *mp = mtod(m, unsigned char *);
9313         static int rx_mac_dec_rpt = 0;
9314
9315         BWN_ASSERT_LOCKED(sc);
9316
9317         phystat0 = le16toh(rxhdr->phy_status0);
9318         phystat3 = le16toh(rxhdr->phy_status3);
9319         macstat = le32toh(rxhdr->mac_status);
9320         chanstat = le16toh(rxhdr->channel);
9321         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9322
9323         if (macstat & BWN_RX_MAC_FCSERR)
9324                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9325         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9326                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9327         if (macstat & BWN_RX_MAC_DECERR)
9328                 goto drop;
9329
9330         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9331         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9332                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9333                     m->m_pkthdr.len);
9334                 goto drop;
9335         }
9336         plcp = (struct bwn_plcp6 *)(mp + padding);
9337         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9338         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9339                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9340                     m->m_pkthdr.len);
9341                 goto drop;
9342         }
9343         wh = mtod(m, struct ieee80211_frame_min *);
9344
9345         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9346                 device_printf(sc->sc_dev,
9347                     "RX decryption attempted (old %d keyidx %#x)\n",
9348                     BWN_ISOLDFMT(mac),
9349                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9350
9351         /* XXX calculating RSSI & noise & antenna */
9352
9353         if (phystat0 & BWN_RX_PHYST0_OFDM)
9354                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9355                     phytype == BWN_PHYTYPE_A);
9356         else
9357                 rate = bwn_plcp_get_cckrate(mac, plcp);
9358         if (rate == -1) {
9359                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9360                         goto drop;
9361         }
9362         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9363
9364         /* RX radio tap */
9365         if (ieee80211_radiotap_active(ic))
9366                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9367         m_adj(m, -IEEE80211_CRC_LEN);
9368
9369         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9370         noise = mac->mac_stats.link_noise;
9371
9372         ifp->if_ipackets++;
9373
9374         BWN_UNLOCK(sc);
9375
9376         ni = ieee80211_find_rxnode(ic, wh);
9377         if (ni != NULL) {
9378                 type = ieee80211_input(ni, m, rssi, noise);
9379                 ieee80211_free_node(ni);
9380         } else
9381                 type = ieee80211_input_all(ic, m, rssi, noise);
9382
9383         BWN_LOCK(sc);
9384         return;
9385 drop:
9386         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9387 }
9388
9389 static void
9390 bwn_dma_handle_txeof(struct bwn_mac *mac,
9391     const struct bwn_txstatus *status)
9392 {
9393         struct bwn_dma *dma = &mac->mac_method.dma;
9394         struct bwn_dma_ring *dr;
9395         struct bwn_dmadesc_generic *desc;
9396         struct bwn_dmadesc_meta *meta;
9397         struct bwn_softc *sc = mac->mac_sc;
9398         struct ieee80211_node *ni;
9399         struct ifnet *ifp = sc->sc_ifp;
9400         struct mbuf *m;
9401         int slot;
9402
9403         BWN_ASSERT_LOCKED(sc);
9404
9405         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9406         if (dr == NULL) {
9407                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9408                 return;
9409         }
9410         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9411
9412         while (1) {
9413                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9414                     ("%s:%d: fail", __func__, __LINE__));
9415                 dr->getdesc(dr, slot, &desc, &meta);
9416
9417                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9418                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9419                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9420                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9421
9422                 if (meta->mt_islast) {
9423                         KASSERT(meta->mt_m != NULL,
9424                             ("%s:%d: fail", __func__, __LINE__));
9425
9426                         ni = meta->mt_ni;
9427                         m = meta->mt_m;
9428                         if (ni != NULL) {
9429                                 /*
9430                                  * Do any tx complete callback. Note this must
9431                                  * be done before releasing the node reference.
9432                                  */
9433                                 if (m->m_flags & M_TXCB)
9434                                         ieee80211_process_callback(ni, m, 0);
9435                                 ieee80211_free_node(ni);
9436                                 meta->mt_ni = NULL;
9437                         }
9438                         m_freem(m);
9439                         meta->mt_m = NULL;
9440                 } else {
9441                         KASSERT(meta->mt_m == NULL,
9442                             ("%s:%d: fail", __func__, __LINE__));
9443                 }
9444
9445                 dr->dr_usedslot--;
9446                 if (meta->mt_islast) {
9447                         ifp->if_opackets++;
9448                         break;
9449                 }
9450                 slot = bwn_dma_nextslot(dr, slot);
9451         }
9452         sc->sc_watchdog_timer = 0;
9453         if (dr->dr_stop) {
9454                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9455                     ("%s:%d: fail", __func__, __LINE__));
9456                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9457                 dr->dr_stop = 0;
9458         }
9459 }
9460
9461 static void
9462 bwn_pio_handle_txeof(struct bwn_mac *mac,
9463     const struct bwn_txstatus *status)
9464 {
9465         struct bwn_pio_txqueue *tq;
9466         struct bwn_pio_txpkt *tp = NULL;
9467         struct bwn_softc *sc = mac->mac_sc;
9468         struct ifnet *ifp = sc->sc_ifp;
9469
9470         BWN_ASSERT_LOCKED(sc);
9471
9472         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9473         if (tq == NULL)
9474                 return;
9475
9476         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9477         tq->tq_free++;
9478
9479         if (tp->tp_ni != NULL) {
9480                 /*
9481                  * Do any tx complete callback.  Note this must
9482                  * be done before releasing the node reference.
9483                  */
9484                 if (tp->tp_m->m_flags & M_TXCB)
9485                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9486                 ieee80211_free_node(tp->tp_ni);
9487                 tp->tp_ni = NULL;
9488         }
9489         m_freem(tp->tp_m);
9490         tp->tp_m = NULL;
9491         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9492
9493         ifp->if_opackets++;
9494
9495         sc->sc_watchdog_timer = 0;
9496         if (tq->tq_stop) {
9497                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9498                 tq->tq_stop = 0;
9499         }
9500 }
9501
9502 static void
9503 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9504 {
9505         struct bwn_softc *sc = mac->mac_sc;
9506         struct bwn_phy *phy = &mac->mac_phy;
9507         struct ifnet *ifp = sc->sc_ifp;
9508         struct ieee80211com *ic = ifp->if_l2com;
9509         unsigned long now;
9510         int result;
9511
9512         BWN_GETTIME(now);
9513
9514         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9515                 return;
9516         phy->nexttime = now + 2 * 1000;
9517
9518         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9519             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9520                 return;
9521
9522         if (phy->recalc_txpwr != NULL) {
9523                 result = phy->recalc_txpwr(mac,
9524                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9525                 if (result == BWN_TXPWR_RES_DONE)
9526                         return;
9527                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9528                     ("%s: fail", __func__));
9529                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9530
9531                 ieee80211_runtask(ic, &mac->mac_txpower);
9532         }
9533 }
9534
9535 static uint16_t
9536 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9537 {
9538
9539         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9540 }
9541
9542 static uint32_t
9543 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9544 {
9545
9546         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9547 }
9548
9549 static void
9550 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9551 {
9552
9553         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9554 }
9555
9556 static void
9557 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9558 {
9559
9560         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9561 }
9562
9563 static int
9564 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9565 {
9566
9567         switch (rate) {
9568         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9569         case 12:
9570                 return (BWN_OFDM_RATE_6MB);
9571         case 18:
9572                 return (BWN_OFDM_RATE_9MB);
9573         case 24:
9574                 return (BWN_OFDM_RATE_12MB);
9575         case 36:
9576                 return (BWN_OFDM_RATE_18MB);
9577         case 48:
9578                 return (BWN_OFDM_RATE_24MB);
9579         case 72:
9580                 return (BWN_OFDM_RATE_36MB);
9581         case 96:
9582                 return (BWN_OFDM_RATE_48MB);
9583         case 108:
9584                 return (BWN_OFDM_RATE_54MB);
9585         /* CCK rates (NB: not IEEE std, device-specific) */
9586         case 2:
9587                 return (BWN_CCK_RATE_1MB);
9588         case 4:
9589                 return (BWN_CCK_RATE_2MB);
9590         case 11:
9591                 return (BWN_CCK_RATE_5MB);
9592         case 22:
9593                 return (BWN_CCK_RATE_11MB);
9594         }
9595
9596         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9597         return (BWN_CCK_RATE_1MB);
9598 }
9599
9600 static int
9601 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9602     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9603 {
9604         const struct bwn_phy *phy = &mac->mac_phy;
9605         struct bwn_softc *sc = mac->mac_sc;
9606         struct ieee80211_frame *wh;
9607         struct ieee80211_frame *protwh;
9608         struct ieee80211_frame_cts *cts;
9609         struct ieee80211_frame_rts *rts;
9610         const struct ieee80211_txparam *tp;
9611         struct ieee80211vap *vap = ni->ni_vap;
9612         struct ifnet *ifp = sc->sc_ifp;
9613         struct ieee80211com *ic = ifp->if_l2com;
9614         struct mbuf *mprot;
9615         unsigned int len;
9616         uint32_t macctl = 0;
9617         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9618         uint16_t phyctl = 0;
9619         uint8_t rate, rate_fb;
9620
9621         wh = mtod(m, struct ieee80211_frame *);
9622         memset(txhdr, 0, sizeof(*txhdr));
9623
9624         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9625         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9626         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9627
9628         /*
9629          * Find TX rate
9630          */
9631         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9632         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9633                 rate = rate_fb = tp->mgmtrate;
9634         else if (ismcast)
9635                 rate = rate_fb = tp->mcastrate;
9636         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9637                 rate = rate_fb = tp->ucastrate;
9638         else {
9639                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9640                 rate = ni->ni_txrate;
9641
9642                 if (rix > 0)
9643                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9644                             IEEE80211_RATE_VAL;
9645                 else
9646                         rate_fb = rate;
9647         }
9648
9649         sc->sc_tx_rate = rate;
9650
9651         rate = bwn_ieeerate2hwrate(sc, rate);
9652         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9653
9654         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9655             bwn_plcp_getcck(rate);
9656         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9657         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9658
9659         if ((rate_fb == rate) ||
9660             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9661             (*(u_int16_t *)wh->i_dur == htole16(0)))
9662                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9663         else
9664                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9665                     m->m_pkthdr.len, rate, isshort);
9666
9667         /* XXX TX encryption */
9668         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9669             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9670             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9671             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9672         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9673             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9674
9675         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9676             BWN_TX_EFT_FB_CCK;
9677         txhdr->chan = phy->chan;
9678         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9679             BWN_TX_PHY_ENC_CCK;
9680         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9681              rate == BWN_CCK_RATE_11MB))
9682                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9683
9684         /* XXX TX antenna selection */
9685
9686         switch (bwn_antenna_sanitize(mac, 0)) {
9687         case 0:
9688                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9689                 break;
9690         case 1:
9691                 phyctl |= BWN_TX_PHY_ANT0;
9692                 break;
9693         case 2:
9694                 phyctl |= BWN_TX_PHY_ANT1;
9695                 break;
9696         case 3:
9697                 phyctl |= BWN_TX_PHY_ANT2;
9698                 break;
9699         case 4:
9700                 phyctl |= BWN_TX_PHY_ANT3;
9701                 break;
9702         default:
9703                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9704         }
9705
9706         if (!ismcast)
9707                 macctl |= BWN_TX_MAC_ACK;
9708
9709         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9710         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9711             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9712                 macctl |= BWN_TX_MAC_LONGFRAME;
9713
9714         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9715                 /* XXX RTS rate is always 1MB??? */
9716                 rts_rate = BWN_CCK_RATE_1MB;
9717                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9718
9719                 protdur = ieee80211_compute_duration(ic->ic_rt,
9720                     m->m_pkthdr.len, rate, isshort) +
9721                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9722
9723                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9724                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9725                             (txhdr->body.old.rts_frame) :
9726                             (txhdr->body.new.rts_frame));
9727                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9728                             protdur);
9729                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9730                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9731                             mprot->m_pkthdr.len);
9732                         m_freem(mprot);
9733                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9734                         len = sizeof(struct ieee80211_frame_cts);
9735                 } else {
9736                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9737                             (txhdr->body.old.rts_frame) :
9738                             (txhdr->body.new.rts_frame));
9739                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9740                             isshort);
9741                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9742                             wh->i_addr2, protdur);
9743                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9744                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9745                             mprot->m_pkthdr.len);
9746                         m_freem(mprot);
9747                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9748                         len = sizeof(struct ieee80211_frame_rts);
9749                 }
9750                 len += IEEE80211_CRC_LEN;
9751                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9752                     &txhdr->body.old.rts_plcp :
9753                     &txhdr->body.new.rts_plcp), len, rts_rate);
9754                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9755                     rts_rate_fb);
9756
9757                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9758                     (&txhdr->body.old.rts_frame) :
9759                     (&txhdr->body.new.rts_frame));
9760                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9761
9762                 if (BWN_ISOFDMRATE(rts_rate)) {
9763                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9764                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9765                 } else {
9766                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9767                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9768                 }
9769                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9770                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9771         }
9772
9773         if (BWN_ISOLDFMT(mac))
9774                 txhdr->body.old.cookie = htole16(cookie);
9775         else
9776                 txhdr->body.new.cookie = htole16(cookie);
9777
9778         txhdr->macctl = htole32(macctl);
9779         txhdr->phyctl = htole16(phyctl);
9780
9781         /*
9782          * TX radio tap
9783          */
9784         if (ieee80211_radiotap_active_vap(vap)) {
9785                 sc->sc_tx_th.wt_flags = 0;
9786                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9787                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9788                 if (isshort &&
9789                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9790                      rate == BWN_CCK_RATE_11MB))
9791                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9792                 sc->sc_tx_th.wt_rate = rate;
9793
9794                 ieee80211_radiotap_tx(vap, m);
9795         }
9796
9797         return (0);
9798 }
9799
9800 static void
9801 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9802     const uint8_t rate)
9803 {
9804         uint32_t d, plen;
9805         uint8_t *raw = plcp->o.raw;
9806
9807         if (BWN_ISOFDMRATE(rate)) {
9808                 d = bwn_plcp_getofdm(rate);
9809                 KASSERT(!(octets & 0xf000),
9810                     ("%s:%d: fail", __func__, __LINE__));
9811                 d |= (octets << 5);
9812                 plcp->o.data = htole32(d);
9813         } else {
9814                 plen = octets * 16 / rate;
9815                 if ((octets * 16 % rate) > 0) {
9816                         plen++;
9817                         if ((rate == BWN_CCK_RATE_11MB)
9818                             && ((octets * 8 % 11) < 4)) {
9819                                 raw[1] = 0x84;
9820                         } else
9821                                 raw[1] = 0x04;
9822                 } else
9823                         raw[1] = 0x04;
9824                 plcp->o.data |= htole32(plen << 16);
9825                 raw[0] = bwn_plcp_getcck(rate);
9826         }
9827 }
9828
9829 static uint8_t
9830 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9831 {
9832         struct bwn_softc *sc = mac->mac_sc;
9833         uint8_t mask;
9834
9835         if (n == 0)
9836                 return (0);
9837         if (mac->mac_phy.gmode)
9838                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9839         else
9840                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9841         if (!(mask & (1 << (n - 1))))
9842                 return (0);
9843         return (n);
9844 }
9845
9846 static uint8_t
9847 bwn_get_fbrate(uint8_t bitrate)
9848 {
9849         switch (bitrate) {
9850         case BWN_CCK_RATE_1MB:
9851                 return (BWN_CCK_RATE_1MB);
9852         case BWN_CCK_RATE_2MB:
9853                 return (BWN_CCK_RATE_1MB);
9854         case BWN_CCK_RATE_5MB:
9855                 return (BWN_CCK_RATE_2MB);
9856         case BWN_CCK_RATE_11MB:
9857                 return (BWN_CCK_RATE_5MB);
9858         case BWN_OFDM_RATE_6MB:
9859                 return (BWN_CCK_RATE_5MB);
9860         case BWN_OFDM_RATE_9MB:
9861                 return (BWN_OFDM_RATE_6MB);
9862         case BWN_OFDM_RATE_12MB:
9863                 return (BWN_OFDM_RATE_9MB);
9864         case BWN_OFDM_RATE_18MB:
9865                 return (BWN_OFDM_RATE_12MB);
9866         case BWN_OFDM_RATE_24MB:
9867                 return (BWN_OFDM_RATE_18MB);
9868         case BWN_OFDM_RATE_36MB:
9869                 return (BWN_OFDM_RATE_24MB);
9870         case BWN_OFDM_RATE_48MB:
9871                 return (BWN_OFDM_RATE_36MB);
9872         case BWN_OFDM_RATE_54MB:
9873                 return (BWN_OFDM_RATE_48MB);
9874         }
9875         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9876         return (0);
9877 }
9878
9879 static uint32_t
9880 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9881     uint32_t ctl, const void *_data, int len)
9882 {
9883         struct bwn_softc *sc = mac->mac_sc;
9884         uint32_t value = 0;
9885         const uint8_t *data = _data;
9886
9887         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9888             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9889         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9890
9891         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9892             tq->tq_base + BWN_PIO8_TXDATA);
9893         if (len & 3) {
9894                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9895                     BWN_PIO8_TXCTL_24_31);
9896                 data = &(data[len - 1]);
9897                 switch (len & 3) {
9898                 case 3:
9899                         ctl |= BWN_PIO8_TXCTL_16_23;
9900                         value |= (uint32_t)(*data) << 16;
9901                         data--;
9902                 case 2:
9903                         ctl |= BWN_PIO8_TXCTL_8_15;
9904                         value |= (uint32_t)(*data) << 8;
9905                         data--;
9906                 case 1:
9907                         value |= (uint32_t)(*data);
9908                 }
9909                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9910                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9911         }
9912
9913         return (ctl);
9914 }
9915
9916 static void
9917 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9918     uint16_t offset, uint32_t value)
9919 {
9920
9921         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9922 }
9923
9924 static uint16_t
9925 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9926     uint16_t ctl, const void *_data, int len)
9927 {
9928         struct bwn_softc *sc = mac->mac_sc;
9929         const uint8_t *data = _data;
9930
9931         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9932         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9933
9934         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9935             tq->tq_base + BWN_PIO_TXDATA);
9936         if (len & 1) {
9937                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9938                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9939                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9940         }
9941
9942         return (ctl);
9943 }
9944
9945 static uint16_t
9946 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9947     uint16_t ctl, struct mbuf *m0)
9948 {
9949         int i, j = 0;
9950         uint16_t data = 0;
9951         const uint8_t *buf;
9952         struct mbuf *m = m0;
9953
9954         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9955         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9956
9957         for (; m != NULL; m = m->m_next) {
9958                 buf = mtod(m, const uint8_t *);
9959                 for (i = 0; i < m->m_len; i++) {
9960                         if (!((j++) % 2))
9961                                 data |= buf[i];
9962                         else {
9963                                 data |= (buf[i] << 8);
9964                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9965                                 data = 0;
9966                         }
9967                 }
9968         }
9969         if (m0->m_pkthdr.len % 2) {
9970                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9971                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9972                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9973         }
9974
9975         return (ctl);
9976 }
9977
9978 static void
9979 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9980 {
9981
9982         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9983                 return;
9984         BWN_WRITE_2(mac, 0x684, 510 + time);
9985         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9986 }
9987
9988 static struct bwn_dma_ring *
9989 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9990 {
9991
9992         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9993                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9994
9995         switch (prio) {
9996         case 3:
9997                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9998         case 2:
9999                 return (mac->mac_method.dma.wme[WME_AC_VI]);
10000         case 0:
10001                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10002         case 1:
10003                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10004         }
10005         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10006         return (NULL);
10007 }
10008
10009 static int
10010 bwn_dma_getslot(struct bwn_dma_ring *dr)
10011 {
10012         int slot;
10013
10014         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10015
10016         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10017         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10018         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10019
10020         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10021         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10022         dr->dr_curslot = slot;
10023         dr->dr_usedslot++;
10024
10025         return (slot);
10026 }
10027
10028 static int
10029 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10030 {
10031         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10032         unsigned int a, b, c, d;
10033         unsigned int avg;
10034         uint32_t tmp;
10035
10036         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10037         a = tmp & 0xff;
10038         b = (tmp >> 8) & 0xff;
10039         c = (tmp >> 16) & 0xff;
10040         d = (tmp >> 24) & 0xff;
10041         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10042             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10043                 return (ENOENT);
10044         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10045             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10046             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10047
10048         if (ofdm) {
10049                 a = (a + 32) & 0x3f;
10050                 b = (b + 32) & 0x3f;
10051                 c = (c + 32) & 0x3f;
10052                 d = (d + 32) & 0x3f;
10053         }
10054
10055         avg = (a + b + c + d + 2) / 4;
10056         if (ofdm) {
10057                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10058                     & BWN_HF_4DB_CCK_POWERBOOST)
10059                         avg = (avg >= 13) ? (avg - 13) : 0;
10060         }
10061         return (avg);
10062 }
10063
10064 static void
10065 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10066 {
10067         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10068         int rfatt = *rfattp;
10069         int bbatt = *bbattp;
10070
10071         while (1) {
10072                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10073                         break;
10074                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10075                         break;
10076                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10077                         break;
10078                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10079                         break;
10080                 if (bbatt > lo->bbatt.max) {
10081                         bbatt -= 4;
10082                         rfatt += 1;
10083                         continue;
10084                 }
10085                 if (bbatt < lo->bbatt.min) {
10086                         bbatt += 4;
10087                         rfatt -= 1;
10088                         continue;
10089                 }
10090                 if (rfatt > lo->rfatt.max) {
10091                         rfatt -= 1;
10092                         bbatt += 4;
10093                         continue;
10094                 }
10095                 if (rfatt < lo->rfatt.min) {
10096                         rfatt += 1;
10097                         bbatt -= 4;
10098                         continue;
10099                 }
10100                 break;
10101         }
10102
10103         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10104         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10105 }
10106
10107 static void
10108 bwn_phy_lock(struct bwn_mac *mac)
10109 {
10110         struct bwn_softc *sc = mac->mac_sc;
10111         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10112
10113         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10114             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10115
10116         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10117                 bwn_psctl(mac, BWN_PS_AWAKE);
10118 }
10119
10120 static void
10121 bwn_phy_unlock(struct bwn_mac *mac)
10122 {
10123         struct bwn_softc *sc = mac->mac_sc;
10124         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10125
10126         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10127             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10128
10129         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10130                 bwn_psctl(mac, 0);
10131 }
10132
10133 static void
10134 bwn_rf_lock(struct bwn_mac *mac)
10135 {
10136
10137         BWN_WRITE_4(mac, BWN_MACCTL,
10138             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10139         BWN_READ_4(mac, BWN_MACCTL);
10140         DELAY(10);
10141 }
10142
10143 static void
10144 bwn_rf_unlock(struct bwn_mac *mac)
10145 {
10146
10147         BWN_READ_2(mac, BWN_PHYVER);
10148         BWN_WRITE_4(mac, BWN_MACCTL,
10149             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10150 }
10151
10152 static struct bwn_pio_txqueue *
10153 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10154     struct bwn_pio_txpkt **pack)
10155 {
10156         struct bwn_pio *pio = &mac->mac_method.pio;
10157         struct bwn_pio_txqueue *tq = NULL;
10158         unsigned int index;
10159
10160         switch (cookie & 0xf000) {
10161         case 0x1000:
10162                 tq = &pio->wme[WME_AC_BK];
10163                 break;
10164         case 0x2000:
10165                 tq = &pio->wme[WME_AC_BE];
10166                 break;
10167         case 0x3000:
10168                 tq = &pio->wme[WME_AC_VI];
10169                 break;
10170         case 0x4000:
10171                 tq = &pio->wme[WME_AC_VO];
10172                 break;
10173         case 0x5000:
10174                 tq = &pio->mcast;
10175                 break;
10176         }
10177         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10178         if (tq == NULL)
10179                 return (NULL);
10180         index = (cookie & 0x0fff);
10181         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10182         if (index >= N(tq->tq_pkts))
10183                 return (NULL);
10184         *pack = &tq->tq_pkts[index];
10185         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10186         return (tq);
10187 }
10188
10189 static void
10190 bwn_txpwr(void *arg, int npending)
10191 {
10192         struct bwn_mac *mac = arg;
10193         struct bwn_softc *sc = mac->mac_sc;
10194
10195         BWN_LOCK(sc);
10196         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10197             mac->mac_phy.set_txpwr != NULL)
10198                 mac->mac_phy.set_txpwr(mac);
10199         BWN_UNLOCK(sc);
10200 }
10201
10202 static void
10203 bwn_task_15s(struct bwn_mac *mac)
10204 {
10205         uint16_t reg;
10206
10207         if (mac->mac_fw.opensource) {
10208                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10209                 if (reg) {
10210                         bwn_restart(mac, "fw watchdog");
10211                         return;
10212                 }
10213                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10214         }
10215         if (mac->mac_phy.task_15s)
10216                 mac->mac_phy.task_15s(mac);
10217
10218         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10219 }
10220
10221 static void
10222 bwn_task_30s(struct bwn_mac *mac)
10223 {
10224
10225         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10226                 return;
10227         mac->mac_noise.noi_running = 1;
10228         mac->mac_noise.noi_nsamples = 0;
10229
10230         bwn_noise_gensample(mac);
10231 }
10232
10233 static void
10234 bwn_task_60s(struct bwn_mac *mac)
10235 {
10236
10237         if (mac->mac_phy.task_60s)
10238                 mac->mac_phy.task_60s(mac);
10239         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10240 }
10241
10242 static void
10243 bwn_tasks(void *arg)
10244 {
10245         struct bwn_mac *mac = arg;
10246         struct bwn_softc *sc = mac->mac_sc;
10247
10248         BWN_ASSERT_LOCKED(sc);
10249         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10250                 return;
10251
10252         if (mac->mac_task_state % 4 == 0)
10253                 bwn_task_60s(mac);
10254         if (mac->mac_task_state % 2 == 0)
10255                 bwn_task_30s(mac);
10256         bwn_task_15s(mac);
10257
10258         mac->mac_task_state++;
10259         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10260 }
10261
10262 static int
10263 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10264 {
10265         struct bwn_softc *sc = mac->mac_sc;
10266
10267         KASSERT(a == 0, ("not support APHY\n"));
10268
10269         switch (plcp->o.raw[0] & 0xf) {
10270         case 0xb:
10271                 return (BWN_OFDM_RATE_6MB);
10272         case 0xf:
10273                 return (BWN_OFDM_RATE_9MB);
10274         case 0xa:
10275                 return (BWN_OFDM_RATE_12MB);
10276         case 0xe:
10277                 return (BWN_OFDM_RATE_18MB);
10278         case 0x9:
10279                 return (BWN_OFDM_RATE_24MB);
10280         case 0xd:
10281                 return (BWN_OFDM_RATE_36MB);
10282         case 0x8:
10283                 return (BWN_OFDM_RATE_48MB);
10284         case 0xc:
10285                 return (BWN_OFDM_RATE_54MB);
10286         }
10287         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10288             plcp->o.raw[0] & 0xf);
10289         return (-1);
10290 }
10291
10292 static int
10293 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10294 {
10295         struct bwn_softc *sc = mac->mac_sc;
10296
10297         switch (plcp->o.raw[0]) {
10298         case 0x0a:
10299                 return (BWN_CCK_RATE_1MB);
10300         case 0x14:
10301                 return (BWN_CCK_RATE_2MB);
10302         case 0x37:
10303                 return (BWN_CCK_RATE_5MB);
10304         case 0x6e:
10305                 return (BWN_CCK_RATE_11MB);
10306         }
10307         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10308         return (-1);
10309 }
10310
10311 static void
10312 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10313     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10314     int rssi, int noise)
10315 {
10316         struct bwn_softc *sc = mac->mac_sc;
10317         const struct ieee80211_frame_min *wh;
10318         uint64_t tsf;
10319         uint16_t low_mactime_now;
10320
10321         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10322                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10323
10324         wh = mtod(m, const struct ieee80211_frame_min *);
10325         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10326                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10327
10328         bwn_tsf_read(mac, &tsf);
10329         low_mactime_now = tsf;
10330         tsf = tsf & ~0xffffULL;
10331         tsf += le16toh(rxhdr->mac_time);
10332         if (low_mactime_now < le16toh(rxhdr->mac_time))
10333                 tsf -= 0x10000;
10334
10335         sc->sc_rx_th.wr_tsf = tsf;
10336         sc->sc_rx_th.wr_rate = rate;
10337         sc->sc_rx_th.wr_antsignal = rssi;
10338         sc->sc_rx_th.wr_antnoise = noise;
10339 }
10340
10341 static void
10342 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10343 {
10344         uint32_t low, high;
10345
10346         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10347             ("%s:%d: fail", __func__, __LINE__));
10348
10349         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10350         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10351         *tsf = high;
10352         *tsf <<= 32;
10353         *tsf |= low;
10354 }
10355
10356 static int
10357 bwn_dma_attach(struct bwn_mac *mac)
10358 {
10359         struct bwn_dma *dma = &mac->mac_method.dma;
10360         struct bwn_softc *sc = mac->mac_sc;
10361         bus_addr_t lowaddr = 0;
10362         int error;
10363
10364         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10365                 return (0);
10366
10367         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10368
10369         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10370
10371         dma->dmatype = bwn_dma_gettype(mac);
10372         if (dma->dmatype == BWN_DMA_30BIT)
10373                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10374         else if (dma->dmatype == BWN_DMA_32BIT)
10375                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10376         else
10377                 lowaddr = BUS_SPACE_MAXADDR;
10378
10379         /*
10380          * Create top level DMA tag
10381          */
10382         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10383                                BWN_ALIGN, 0,            /* alignment, bounds */
10384                                lowaddr,                 /* lowaddr */
10385                                BUS_SPACE_MAXADDR,       /* highaddr */
10386                                NULL, NULL,              /* filter, filterarg */
10387                                MAXBSIZE,                /* maxsize */
10388                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10389                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10390                                0,                       /* flags */
10391                                NULL, NULL,              /* lockfunc, lockarg */
10392                                &dma->parent_dtag);
10393         if (error) {
10394                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10395                 return (error);
10396         }
10397
10398         /*
10399          * Create TX/RX mbuf DMA tag
10400          */
10401         error = bus_dma_tag_create(dma->parent_dtag,
10402                                 1,
10403                                 0,
10404                                 BUS_SPACE_MAXADDR,
10405                                 BUS_SPACE_MAXADDR,
10406                                 NULL, NULL,
10407                                 MCLBYTES,
10408                                 1,
10409                                 BUS_SPACE_MAXSIZE_32BIT,
10410                                 0,
10411                                 NULL, NULL,
10412                                 &dma->rxbuf_dtag);
10413         if (error) {
10414                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10415                 goto fail0;
10416         }
10417         error = bus_dma_tag_create(dma->parent_dtag,
10418                                 1,
10419                                 0,
10420                                 BUS_SPACE_MAXADDR,
10421                                 BUS_SPACE_MAXADDR,
10422                                 NULL, NULL,
10423                                 MCLBYTES,
10424                                 1,
10425                                 BUS_SPACE_MAXSIZE_32BIT,
10426                                 0,
10427                                 NULL, NULL,
10428                                 &dma->txbuf_dtag);
10429         if (error) {
10430                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10431                 goto fail1;
10432         }
10433
10434         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10435         if (!dma->wme[WME_AC_BK])
10436                 goto fail2;
10437
10438         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10439         if (!dma->wme[WME_AC_BE])
10440                 goto fail3;
10441
10442         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10443         if (!dma->wme[WME_AC_VI])
10444                 goto fail4;
10445
10446         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10447         if (!dma->wme[WME_AC_VO])
10448                 goto fail5;
10449
10450         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10451         if (!dma->mcast)
10452                 goto fail6;
10453         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10454         if (!dma->rx)
10455                 goto fail7;
10456
10457         return (error);
10458
10459 fail7:  bwn_dma_ringfree(&dma->mcast);
10460 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10461 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10462 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10463 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10464 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10465 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10466 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10467         return (error);
10468 }
10469
10470 static struct bwn_dma_ring *
10471 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10472     uint16_t cookie, int *slot)
10473 {
10474         struct bwn_dma *dma = &mac->mac_method.dma;
10475         struct bwn_dma_ring *dr;
10476         struct bwn_softc *sc = mac->mac_sc;
10477
10478         BWN_ASSERT_LOCKED(mac->mac_sc);
10479
10480         switch (cookie & 0xf000) {
10481         case 0x1000:
10482                 dr = dma->wme[WME_AC_BK];
10483                 break;
10484         case 0x2000:
10485                 dr = dma->wme[WME_AC_BE];
10486                 break;
10487         case 0x3000:
10488                 dr = dma->wme[WME_AC_VI];
10489                 break;
10490         case 0x4000:
10491                 dr = dma->wme[WME_AC_VO];
10492                 break;
10493         case 0x5000:
10494                 dr = dma->mcast;
10495                 break;
10496         default:
10497                 dr = NULL;
10498                 KASSERT(0 == 1,
10499                     ("invalid cookie value %d", cookie & 0xf000));
10500         }
10501         *slot = (cookie & 0x0fff);
10502         if (*slot < 0 || *slot >= dr->dr_numslots) {
10503                 /*
10504                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10505                  * that it occurs events which have same H/W sequence numbers.
10506                  * When it's occurred just prints a WARNING msgs and ignores.
10507                  */
10508                 KASSERT(status->seq == dma->lastseq,
10509                     ("%s:%d: fail", __func__, __LINE__));
10510                 device_printf(sc->sc_dev,
10511                     "out of slot ranges (0 < %d < %d)\n", *slot,
10512                     dr->dr_numslots);
10513                 return (NULL);
10514         }
10515         dma->lastseq = status->seq;
10516         return (dr);
10517 }
10518
10519 static void
10520 bwn_dma_stop(struct bwn_mac *mac)
10521 {
10522         struct bwn_dma *dma;
10523
10524         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10525                 return;
10526         dma = &mac->mac_method.dma;
10527
10528         bwn_dma_ringstop(&dma->rx);
10529         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10530         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10531         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10532         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10533         bwn_dma_ringstop(&dma->mcast);
10534 }
10535
10536 static void
10537 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10538 {
10539
10540         if (dr == NULL)
10541                 return;
10542
10543         bwn_dma_cleanup(*dr);
10544 }
10545
10546 static void
10547 bwn_pio_stop(struct bwn_mac *mac)
10548 {
10549         struct bwn_pio *pio;
10550
10551         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10552                 return;
10553         pio = &mac->mac_method.pio;
10554
10555         bwn_destroy_queue_tx(&pio->mcast);
10556         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10557         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10558         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10559         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10560 }
10561
10562 static void
10563 bwn_led_attach(struct bwn_mac *mac)
10564 {
10565         struct bwn_softc *sc = mac->mac_sc;
10566         const uint8_t *led_act = NULL;
10567         uint16_t val[BWN_LED_MAX];
10568         int i;
10569
10570         sc->sc_led_idle = (2350 * hz) / 1000;
10571         sc->sc_led_blink = 1;
10572
10573         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10574                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10575                     bwn_vendor_led_act[i].vid) {
10576                         led_act = bwn_vendor_led_act[i].led_act;
10577                         break;
10578                 }
10579         }
10580         if (led_act == NULL)
10581                 led_act = bwn_default_led_act;
10582
10583         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10584         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10585         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10586         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10587
10588         for (i = 0; i < BWN_LED_MAX; ++i) {
10589                 struct bwn_led *led = &sc->sc_leds[i];
10590
10591                 if (val[i] == 0xff) {
10592                         led->led_act = led_act[i];
10593                 } else {
10594                         if (val[i] & BWN_LED_ACT_LOW)
10595                                 led->led_flags |= BWN_LED_F_ACTLOW;
10596                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10597                 }
10598                 led->led_mask = (1 << i);
10599
10600                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10601                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10602                     led->led_act == BWN_LED_ACT_BLINK) {
10603                         led->led_flags |= BWN_LED_F_BLINK;
10604                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10605                                 led->led_flags |= BWN_LED_F_POLLABLE;
10606                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10607                                 led->led_flags |= BWN_LED_F_SLOW;
10608
10609                         if (sc->sc_blink_led == NULL) {
10610                                 sc->sc_blink_led = led;
10611                                 if (led->led_flags & BWN_LED_F_SLOW)
10612                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10613                         }
10614                 }
10615
10616                 DPRINTF(sc, BWN_DEBUG_LED,
10617                     "%dth led, act %d, lowact %d\n", i,
10618                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10619         }
10620         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10621 }
10622
10623 static __inline uint16_t
10624 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10625 {
10626
10627         if (led->led_flags & BWN_LED_F_ACTLOW)
10628                 on = !on;
10629         if (on)
10630                 val |= led->led_mask;
10631         else
10632                 val &= ~led->led_mask;
10633         return val;
10634 }
10635
10636 static void
10637 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10638 {
10639         struct bwn_softc *sc = mac->mac_sc;
10640         struct ifnet *ifp = sc->sc_ifp;
10641         struct ieee80211com *ic = ifp->if_l2com;
10642         uint16_t val;
10643         int i;
10644
10645         if (nstate == IEEE80211_S_INIT) {
10646                 callout_stop(&sc->sc_led_blink_ch);
10647                 sc->sc_led_blinking = 0;
10648         }
10649
10650         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10651                 return;
10652
10653         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10654         for (i = 0; i < BWN_LED_MAX; ++i) {
10655                 struct bwn_led *led = &sc->sc_leds[i];
10656                 int on;
10657
10658                 if (led->led_act == BWN_LED_ACT_UNKN ||
10659                     led->led_act == BWN_LED_ACT_NULL)
10660                         continue;
10661
10662                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10663                     nstate != IEEE80211_S_INIT)
10664                         continue;
10665
10666                 switch (led->led_act) {
10667                 case BWN_LED_ACT_ON:    /* Always on */
10668                         on = 1;
10669                         break;
10670                 case BWN_LED_ACT_OFF:   /* Always off */
10671                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10672                         on = 0;
10673                         break;
10674                 default:
10675                         on = 1;
10676                         switch (nstate) {
10677                         case IEEE80211_S_INIT:
10678                                 on = 0;
10679                                 break;
10680                         case IEEE80211_S_RUN:
10681                                 if (led->led_act == BWN_LED_ACT_11G &&
10682                                     ic->ic_curmode != IEEE80211_MODE_11G)
10683                                         on = 0;
10684                                 break;
10685                         default:
10686                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10687                                         on = 0;
10688                                 break;
10689                         }
10690                         break;
10691                 }
10692
10693                 val = bwn_led_onoff(led, val, on);
10694         }
10695         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10696 }
10697
10698 static void
10699 bwn_led_event(struct bwn_mac *mac, int event)
10700 {
10701         struct bwn_softc *sc = mac->mac_sc;
10702         struct bwn_led *led = sc->sc_blink_led;
10703         int rate;
10704
10705         if (event == BWN_LED_EVENT_POLL) {
10706                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10707                         return;
10708                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10709                         return;
10710         }
10711
10712         sc->sc_led_ticks = ticks;
10713         if (sc->sc_led_blinking)
10714                 return;
10715
10716         switch (event) {
10717         case BWN_LED_EVENT_RX:
10718                 rate = sc->sc_rx_rate;
10719                 break;
10720         case BWN_LED_EVENT_TX:
10721                 rate = sc->sc_tx_rate;
10722                 break;
10723         case BWN_LED_EVENT_POLL:
10724                 rate = 0;
10725                 break;
10726         default:
10727                 panic("unknown LED event %d\n", event);
10728                 break;
10729         }
10730         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10731             bwn_led_duration[rate].off_dur);
10732 }
10733
10734 static void
10735 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10736 {
10737         struct bwn_softc *sc = mac->mac_sc;
10738         struct bwn_led *led = sc->sc_blink_led;
10739         uint16_t val;
10740
10741         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10742         val = bwn_led_onoff(led, val, 1);
10743         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10744
10745         if (led->led_flags & BWN_LED_F_SLOW) {
10746                 BWN_LED_SLOWDOWN(on_dur);
10747                 BWN_LED_SLOWDOWN(off_dur);
10748         }
10749
10750         sc->sc_led_blinking = 1;
10751         sc->sc_led_blink_offdur = off_dur;
10752
10753         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10754 }
10755
10756 static void
10757 bwn_led_blink_next(void *arg)
10758 {
10759         struct bwn_mac *mac = arg;
10760         struct bwn_softc *sc = mac->mac_sc;
10761         uint16_t val;
10762
10763         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10764         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10765         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10766
10767         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10768             bwn_led_blink_end, mac);
10769 }
10770
10771 static void
10772 bwn_led_blink_end(void *arg)
10773 {
10774         struct bwn_mac *mac = arg;
10775         struct bwn_softc *sc = mac->mac_sc;
10776
10777         sc->sc_led_blinking = 0;
10778 }
10779
10780 static int
10781 bwn_suspend(device_t dev)
10782 {
10783         struct bwn_softc *sc = device_get_softc(dev);
10784
10785         bwn_stop(sc, 1);
10786         return (0);
10787 }
10788
10789 static int
10790 bwn_resume(device_t dev)
10791 {
10792         struct bwn_softc *sc = device_get_softc(dev);
10793         struct ifnet *ifp = sc->sc_ifp;
10794
10795         if (ifp->if_flags & IFF_UP)
10796                 bwn_init(sc);
10797         return (0);
10798 }
10799
10800 static void
10801 bwn_rfswitch(void *arg)
10802 {
10803         struct bwn_softc *sc = arg;
10804         struct bwn_mac *mac = sc->sc_curmac;
10805         int cur = 0, prev = 0;
10806
10807         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10808             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10809
10810         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10811                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10812                         & BWN_RF_HWENABLED_HI_MASK))
10813                         cur = 1;
10814         } else {
10815                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10816                     & BWN_RF_HWENABLED_LO_MASK)
10817                         cur = 1;
10818         }
10819
10820         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10821                 prev = 1;
10822
10823         if (cur != prev) {
10824                 if (cur)
10825                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10826                 else
10827                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10828
10829                 device_printf(sc->sc_dev,
10830                     "status of RF switch is changed to %s\n",
10831                     cur ? "ON" : "OFF");
10832                 if (cur != mac->mac_phy.rf_on) {
10833                         if (cur)
10834                                 bwn_rf_turnon(mac);
10835                         else
10836                                 bwn_rf_turnoff(mac);
10837                 }
10838         }
10839
10840         callout_schedule(&sc->sc_rfswitch_ch, hz);
10841 }
10842
10843 static void
10844 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10845 {
10846         struct bwn_phy *phy = &mac->mac_phy;
10847         struct bwn_phy_lp *plp = &phy->phy_lp;
10848
10849         plp->plp_antenna = BWN_ANT_DEFAULT;
10850 }
10851
10852 static int
10853 bwn_phy_lp_init(struct bwn_mac *mac)
10854 {
10855         static const struct bwn_stxtable tables[] = {
10856                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10857                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10858                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10859                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10860                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10861                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10862                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10863                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10864                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10865                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10866                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10867                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10868                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10869                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10870                 { 2, 11, 0x40, 0, 0x0f }
10871         };
10872         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10873         struct bwn_softc *sc = mac->mac_sc;
10874         const struct bwn_stxtable *st;
10875         struct ifnet *ifp = sc->sc_ifp;
10876         struct ieee80211com *ic = ifp->if_l2com;
10877         int i, error;
10878         uint16_t tmp;
10879
10880         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10881         bwn_phy_lp_bbinit(mac);
10882
10883         /* initialize RF */
10884         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10885         DELAY(1);
10886         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10887         DELAY(1);
10888
10889         if (mac->mac_phy.rf_ver == 0x2062)
10890                 bwn_phy_lp_b2062_init(mac);
10891         else {
10892                 bwn_phy_lp_b2063_init(mac);
10893
10894                 /* synchronize stx table. */
10895                 for (i = 0; i < N(tables); i++) {
10896                         st = &tables[i];
10897                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10898                         tmp >>= st->st_rfshift;
10899                         tmp <<= st->st_physhift;
10900                         BWN_PHY_SETMASK(mac,
10901                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10902                             ~(st->st_mask << st->st_physhift), tmp);
10903                 }
10904
10905                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10906                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10907         }
10908
10909         /* calibrate RC */
10910         if (mac->mac_phy.rev >= 2)
10911                 bwn_phy_lp_rxcal_r2(mac);
10912         else if (!plp->plp_rccap) {
10913                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10914                         bwn_phy_lp_rccal_r12(mac);
10915         } else
10916                 bwn_phy_lp_set_rccap(mac);
10917
10918         error = bwn_phy_lp_switch_channel(mac, 7);
10919         if (error)
10920                 device_printf(sc->sc_dev,
10921                     "failed to change channel 7 (%d)\n", error);
10922         bwn_phy_lp_txpctl_init(mac);
10923         bwn_phy_lp_calib(mac);
10924         return (0);
10925 }
10926
10927 static uint16_t
10928 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10929 {
10930
10931         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10932         return (BWN_READ_2(mac, BWN_PHYDATA));
10933 }
10934
10935 static void
10936 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10937 {
10938
10939         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10940         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10941 }
10942
10943 static void
10944 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10945     uint16_t set)
10946 {
10947
10948         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10949         BWN_WRITE_2(mac, BWN_PHYDATA,
10950             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10951 }
10952
10953 static uint16_t
10954 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10955 {
10956
10957         KASSERT(reg != 1, ("unaccessible register %d", reg));
10958         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10959                 reg |= 0x100;
10960         if (mac->mac_phy.rev >= 2)
10961                 reg |= 0x200;
10962         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10963         return BWN_READ_2(mac, BWN_RFDATALO);
10964 }
10965
10966 static void
10967 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10968 {
10969
10970         KASSERT(reg != 1, ("unaccessible register %d", reg));
10971         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10972         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10973 }
10974
10975 static void
10976 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10977 {
10978
10979         if (on) {
10980                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10981                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10982                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10983                 return;
10984         }
10985
10986         if (mac->mac_phy.rev >= 2) {
10987                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10988                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10989                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10990                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10991                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10992                 return;
10993         }
10994
10995         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10996         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10997         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10998         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10999 }
11000
11001 static int
11002 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11003 {
11004         struct bwn_phy *phy = &mac->mac_phy;
11005         struct bwn_phy_lp *plp = &phy->phy_lp;
11006         int error;
11007
11008         if (phy->rf_ver == 0x2063) {
11009                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11010                 if (error)
11011                         return (error);
11012         } else {
11013                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11014                 if (error)
11015                         return (error);
11016                 bwn_phy_lp_set_anafilter(mac, chan);
11017                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11018         }
11019
11020         plp->plp_chan = chan;
11021         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11022         return (0);
11023 }
11024
11025 static uint32_t
11026 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11027 {
11028         struct bwn_softc *sc = mac->mac_sc;
11029         struct ifnet *ifp = sc->sc_ifp;
11030         struct ieee80211com *ic = ifp->if_l2com;
11031
11032         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11033 }
11034
11035 static void
11036 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11037 {
11038         struct bwn_phy *phy = &mac->mac_phy;
11039         struct bwn_phy_lp *plp = &phy->phy_lp;
11040
11041         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11042                 return;
11043
11044         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11045         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11046         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11047         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11048         plp->plp_antenna = antenna;
11049 }
11050
11051 static void
11052 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11053 {
11054
11055         bwn_phy_lp_calib(mac);
11056 }
11057
11058 static void
11059 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11060 {
11061         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11062         struct bwn_softc *sc = mac->mac_sc;
11063         struct ifnet *ifp = sc->sc_ifp;
11064         struct ieee80211com *ic = ifp->if_l2com;
11065
11066         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11067                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11068                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11069                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11070                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11071                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11072                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11073                 return;
11074         }
11075
11076         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11077         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11078         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11079         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11080         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11081         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11082         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11083         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11084 }
11085
11086 static void
11087 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11088 {
11089
11090         bwn_phy_lp_tblinit(mac);
11091         if (mac->mac_phy.rev >= 2)
11092                 bwn_phy_lp_bbinit_r2(mac);
11093         else
11094                 bwn_phy_lp_bbinit_r01(mac);
11095 }
11096
11097 static void
11098 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11099 {
11100         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11101         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11102         struct bwn_softc *sc = mac->mac_sc;
11103         struct ifnet *ifp = sc->sc_ifp;
11104         struct ieee80211com *ic = ifp->if_l2com;
11105
11106         bwn_phy_lp_set_txgain(mac,
11107             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11108         bwn_phy_lp_set_bbmult(mac, 150);
11109 }
11110
11111 static void
11112 bwn_phy_lp_calib(struct bwn_mac *mac)
11113 {
11114         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11115         struct bwn_softc *sc = mac->mac_sc;
11116         struct ifnet *ifp = sc->sc_ifp;
11117         struct ieee80211com *ic = ifp->if_l2com;
11118         const struct bwn_rxcompco *rc = NULL;
11119         struct bwn_txgain ogain;
11120         int i, omode, oafeovr, orf, obbmult;
11121         uint8_t mode, fc = 0;
11122
11123         if (plp->plp_chanfullcal != plp->plp_chan) {
11124                 plp->plp_chanfullcal = plp->plp_chan;
11125                 fc = 1;
11126         }
11127
11128         bwn_mac_suspend(mac);
11129
11130         /* BlueTooth Coexistance Override */
11131         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11132         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11133
11134         if (mac->mac_phy.rev >= 2)
11135                 bwn_phy_lp_digflt_save(mac);
11136         bwn_phy_lp_get_txpctlmode(mac);
11137         mode = plp->plp_txpctlmode;
11138         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11139         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11140                 bwn_phy_lp_bugfix(mac);
11141         if (mac->mac_phy.rev >= 2 && fc == 1) {
11142                 bwn_phy_lp_get_txpctlmode(mac);
11143                 omode = plp->plp_txpctlmode;
11144                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11145                 if (oafeovr)
11146                         ogain = bwn_phy_lp_get_txgain(mac);
11147                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11148                 obbmult = bwn_phy_lp_get_bbmult(mac);
11149                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11150                 if (oafeovr)
11151                         bwn_phy_lp_set_txgain(mac, &ogain);
11152                 bwn_phy_lp_set_bbmult(mac, obbmult);
11153                 bwn_phy_lp_set_txpctlmode(mac, omode);
11154                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11155         }
11156         bwn_phy_lp_set_txpctlmode(mac, mode);
11157         if (mac->mac_phy.rev >= 2)
11158                 bwn_phy_lp_digflt_restore(mac);
11159
11160         /* do RX IQ Calculation; assumes that noise is true. */
11161         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11162                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11163                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11164                                 rc = &bwn_rxcompco_5354[i];
11165                 }
11166         } else if (mac->mac_phy.rev >= 2)
11167                 rc = &bwn_rxcompco_r2;
11168         else {
11169                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11170                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11171                                 rc = &bwn_rxcompco_r12[i];
11172                 }
11173         }
11174         if (rc == NULL)
11175                 goto fail;
11176
11177         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11178         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11179
11180         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11181
11182         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11183                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11184                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11185         } else {
11186                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11187                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11188         }
11189
11190         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11191         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11192         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11193         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11194         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11195         bwn_phy_lp_set_deaf(mac, 0);
11196         /* XXX no checking return value? */
11197         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11198         bwn_phy_lp_clear_deaf(mac, 0);
11199         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11200         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11201         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11202
11203         /* disable RX GAIN override. */
11204         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11205         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11206         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11207         if (mac->mac_phy.rev >= 2) {
11208                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11209                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11210                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11211                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11212                 }
11213         } else {
11214                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11215         }
11216
11217         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11218         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11219 fail:
11220         bwn_mac_enable(mac);
11221 }
11222
11223 static void
11224 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11225 {
11226
11227         if (on) {
11228                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11229                 return;
11230         }
11231
11232         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11233         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11234 }
11235
11236 static int
11237 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11238 {
11239         static const struct bwn_b206x_chan *bc = NULL;
11240         struct bwn_softc *sc = mac->mac_sc;
11241         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11242             tmp[6];
11243         uint16_t old, scale, tmp16;
11244         int i, div;
11245
11246         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11247                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11248                         bc = &bwn_b2063_chantable[i];
11249                         break;
11250                 }
11251         }
11252         if (bc == NULL)
11253                 return (EINVAL);
11254
11255         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11256         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11257         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11258         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11259         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11260         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11261         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11262         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11263         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11264         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11265         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11266         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11267
11268         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11269         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11270
11271         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11272         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11273         freqref = freqxtal * 3;
11274         div = (freqxtal <= 26000000 ? 1 : 2);
11275         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11276         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11277                 999999) / 1000000) + 1;
11278
11279         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11280         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11281             0xfff8, timeout >> 2);
11282         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11283             0xff9f,timeout << 5);
11284         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11285
11286         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11287         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11288         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11289
11290         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11291             (timeoutref + 1)) - 1;
11292         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11293             0xf0, count >> 8);
11294         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11295
11296         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11297         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11298         while (tmp[1] >= freqref) {
11299                 tmp[0]++;
11300                 tmp[1] -= freqref;
11301         }
11302         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11303         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11304         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11305         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11306         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11307
11308         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11309         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11310         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11311         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11312
11313         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11314         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11315
11316         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11317                 scale = 1;
11318                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11319         } else {
11320                 scale = 0;
11321                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11322         }
11323         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11324         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11325
11326         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11327             (scale + 1);
11328         if (tmp[5] > 150)
11329                 tmp[5] = 0;
11330
11331         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11332         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11333
11334         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11335         if (freqxtal > 26000000)
11336                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11337         else
11338                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11339
11340         if (val[0] == 45)
11341                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11342         else
11343                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11344
11345         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11346         DELAY(1);
11347         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11348
11349         /* VCO Calibration */
11350         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11351         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11352         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11353         DELAY(1);
11354         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11355         DELAY(1);
11356         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11357         DELAY(1);
11358         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11359         DELAY(300);
11360         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11361
11362         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11363         return (0);
11364 }
11365
11366 static int
11367 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11368 {
11369         struct bwn_softc *sc = mac->mac_sc;
11370         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11371         const struct bwn_b206x_chan *bc = NULL;
11372         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11373         uint32_t tmp[9];
11374         int i;
11375
11376         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11377                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11378                         bc = &bwn_b2062_chantable[i];
11379                         break;
11380                 }
11381         }
11382
11383         if (bc == NULL)
11384                 return (EINVAL);
11385
11386         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11387         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11388         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11389         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11390         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11391         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11392         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11393         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11394         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11395         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11396
11397         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11398         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11399         bwn_phy_lp_b2062_reset_pllbias(mac);
11400         tmp[0] = freqxtal / 1000;
11401         tmp[1] = plp->plp_div * 1000;
11402         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11403         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11404                 tmp[2] *= 2;
11405         tmp[3] = 48 * tmp[0];
11406         tmp[5] = tmp[2] / tmp[3];
11407         tmp[6] = tmp[2] % tmp[3];
11408         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11409         tmp[4] = tmp[6] * 0x100;
11410         tmp[5] = tmp[4] / tmp[3];
11411         tmp[6] = tmp[4] % tmp[3];
11412         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11413         tmp[4] = tmp[6] * 0x100;
11414         tmp[5] = tmp[4] / tmp[3];
11415         tmp[6] = tmp[4] % tmp[3];
11416         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11417         tmp[4] = tmp[6] * 0x100;
11418         tmp[5] = tmp[4] / tmp[3];
11419         tmp[6] = tmp[4] % tmp[3];
11420         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11421             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11422         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11423         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11424         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11425         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11426
11427         bwn_phy_lp_b2062_vco_calib(mac);
11428         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11429                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11430                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11431                 bwn_phy_lp_b2062_reset_pllbias(mac);
11432                 bwn_phy_lp_b2062_vco_calib(mac);
11433                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11434                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11435                         return (EIO);
11436                 }
11437         }
11438         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11439         return (0);
11440 }
11441
11442 static void
11443 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11444 {
11445         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11446         uint16_t tmp = (channel == 14);
11447
11448         if (mac->mac_phy.rev < 2) {
11449                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11450                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11451                         bwn_phy_lp_set_rccap(mac);
11452                 return;
11453         }
11454
11455         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11456 }
11457
11458 static void
11459 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11460 {
11461         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11462         struct bwn_softc *sc = mac->mac_sc;
11463         struct ifnet *ifp = sc->sc_ifp;
11464         struct ieee80211com *ic = ifp->if_l2com;
11465         uint16_t iso, tmp[3];
11466
11467         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11468
11469         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11470                 iso = plp->plp_txisoband_m;
11471         else if (freq <= 5320)
11472                 iso = plp->plp_txisoband_l;
11473         else if (freq <= 5700)
11474                 iso = plp->plp_txisoband_m;
11475         else
11476                 iso = plp->plp_txisoband_h;
11477
11478         tmp[0] = ((iso - 26) / 12) << 12;
11479         tmp[1] = tmp[0] + 0x1000;
11480         tmp[2] = tmp[0] + 0x2000;
11481
11482         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11483         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11484 }
11485
11486 static void
11487 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11488 {
11489         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11490         int i;
11491         static const uint16_t addr[] = {
11492                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11493                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11494                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11495                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11496                 BWN_PHY_OFDM(0xcf),
11497         };
11498         static const uint16_t val[] = {
11499                 0xde5e, 0xe832, 0xe331, 0x4d26,
11500                 0x0026, 0x1420, 0x0020, 0xfe08,
11501                 0x0008,
11502         };
11503
11504         for (i = 0; i < N(addr); i++) {
11505                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11506                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11507         }
11508 }
11509
11510 static void
11511 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11512 {
11513         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11514         struct bwn_softc *sc = mac->mac_sc;
11515         uint16_t ctl;
11516
11517         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11518         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11519         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11520                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11521                 break;
11522         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11523                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11524                 break;
11525         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11526                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11527                 break;
11528         default:
11529                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11530                 device_printf(sc->sc_dev, "unknown command mode\n");
11531                 break;
11532         }
11533 }
11534
11535 static void
11536 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11537 {
11538         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11539         uint16_t ctl;
11540         uint8_t old;
11541
11542         bwn_phy_lp_get_txpctlmode(mac);
11543         old = plp->plp_txpctlmode;
11544         if (old == mode)
11545                 return;
11546         plp->plp_txpctlmode = mode;
11547
11548         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11549                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11550                     plp->plp_tssiidx);
11551                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11552                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11553
11554                 /* disable TX GAIN override */
11555                 if (mac->mac_phy.rev < 2)
11556                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11557                 else {
11558                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11559                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11560                 }
11561                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11562
11563                 plp->plp_txpwridx = -1;
11564         }
11565         if (mac->mac_phy.rev >= 2) {
11566                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11567                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11568                 else
11569                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11570         }
11571
11572         /* writes TX Power Control mode */
11573         switch (plp->plp_txpctlmode) {
11574         case BWN_PHYLP_TXPCTL_OFF:
11575                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11576                 break;
11577         case BWN_PHYLP_TXPCTL_ON_HW:
11578                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11579                 break;
11580         case BWN_PHYLP_TXPCTL_ON_SW:
11581                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11582                 break;
11583         default:
11584                 ctl = 0;
11585                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11586         }
11587         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11588             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11589 }
11590
11591 static void
11592 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11593 {
11594         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11595         struct bwn_softc *sc = mac->mac_sc;
11596         const unsigned int size = 256;
11597         struct bwn_txgain tg;
11598         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11599         uint16_t tssinpt, tssiidx, value[2];
11600         uint8_t mode;
11601         int8_t txpwridx;
11602
11603         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11604             M_NOWAIT | M_ZERO);
11605         if (tabs == NULL) {
11606                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11607                 return;
11608         }
11609
11610         bwn_phy_lp_get_txpctlmode(mac);
11611         mode = plp->plp_txpctlmode;
11612         txpwridx = plp->plp_txpwridx;
11613         tssinpt = plp->plp_tssinpt;
11614         tssiidx = plp->plp_tssiidx;
11615
11616         bwn_tab_read_multi(mac,
11617             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11618             BWN_TAB_4(7, 0x140), size, tabs);
11619
11620         bwn_phy_lp_tblinit(mac);
11621         bwn_phy_lp_bbinit(mac);
11622         bwn_phy_lp_txpctl_init(mac);
11623         bwn_phy_lp_rf_onoff(mac, 1);
11624         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11625
11626         bwn_tab_write_multi(mac,
11627             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11628             BWN_TAB_4(7, 0x140), size, tabs);
11629
11630         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11631         plp->plp_tssinpt = tssinpt;
11632         plp->plp_tssiidx = tssiidx;
11633         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11634         if (txpwridx != -1) {
11635                 /* set TX power by index */
11636                 plp->plp_txpwridx = txpwridx;
11637                 bwn_phy_lp_get_txpctlmode(mac);
11638                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11639                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11640                 if (mac->mac_phy.rev >= 2) {
11641                         rxcomp = bwn_tab_read(mac,
11642                             BWN_TAB_4(7, txpwridx + 320));
11643                         txgain = bwn_tab_read(mac,
11644                             BWN_TAB_4(7, txpwridx + 192));
11645                         tg.tg_pad = (txgain >> 16) & 0xff;
11646                         tg.tg_gm = txgain & 0xff;
11647                         tg.tg_pga = (txgain >> 8) & 0xff;
11648                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11649                         bwn_phy_lp_set_txgain(mac, &tg);
11650                 } else {
11651                         rxcomp = bwn_tab_read(mac,
11652                             BWN_TAB_4(10, txpwridx + 320));
11653                         txgain = bwn_tab_read(mac,
11654                             BWN_TAB_4(10, txpwridx + 192));
11655                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11656                             0xf800, (txgain >> 4) & 0x7fff);
11657                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11658                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11659                 }
11660                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11661
11662                 /* set TX IQCC */
11663                 value[0] = (rxcomp >> 10) & 0x3ff;
11664                 value[1] = rxcomp & 0x3ff;
11665                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11666
11667                 coeff = bwn_tab_read(mac,
11668                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11669                     BWN_TAB_4(10, txpwridx + 448));
11670                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11671                 if (mac->mac_phy.rev >= 2) {
11672                         rfpwr = bwn_tab_read(mac,
11673                             BWN_TAB_4(7, txpwridx + 576));
11674                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11675                             rfpwr & 0xffff);
11676                 }
11677                 bwn_phy_lp_set_txgain_override(mac);
11678         }
11679         if (plp->plp_rccap)
11680                 bwn_phy_lp_set_rccap(mac);
11681         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11682         bwn_phy_lp_set_txpctlmode(mac, mode);
11683         free(tabs, M_DEVBUF);
11684 }
11685
11686 static void
11687 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11688 {
11689         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11690         int i;
11691         static const uint16_t addr[] = {
11692                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11693                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11694                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11695                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11696                 BWN_PHY_OFDM(0xcf),
11697         };
11698
11699         for (i = 0; i < N(addr); i++)
11700                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11701 }
11702
11703 static void
11704 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11705 {
11706         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11707
11708         if (mac->mac_phy.rev < 2) {
11709                 bwn_phy_lp_tblinit_r01(mac);
11710                 bwn_phy_lp_tblinit_txgain(mac);
11711                 bwn_phy_lp_set_gaintbl(mac, freq);
11712                 return;
11713         }
11714
11715         bwn_phy_lp_tblinit_r2(mac);
11716         bwn_phy_lp_tblinit_txgain(mac);
11717 }
11718
11719 struct bwn_wpair {
11720         uint16_t                reg;
11721         uint16_t                value;
11722 };
11723
11724 struct bwn_smpair {
11725         uint16_t                offset;
11726         uint16_t                mask;
11727         uint16_t                set;
11728 };
11729
11730 static void
11731 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11732 {
11733         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11734         struct bwn_softc *sc = mac->mac_sc;
11735         struct ifnet *ifp = sc->sc_ifp;
11736         struct ieee80211com *ic = ifp->if_l2com;
11737         static const struct bwn_wpair v1[] = {
11738                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11739                 { BWN_PHY_AFE_CTL, 0x8800 },
11740                 { BWN_PHY_AFE_CTL_OVR, 0 },
11741                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11742                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11743                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11744                 { BWN_PHY_OFDM(0xf9), 0 },
11745                 { BWN_PHY_TR_LOOKUP_1, 0 }
11746         };
11747         static const struct bwn_smpair v2[] = {
11748                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11749                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11750                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11751                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11752                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11753         };
11754         static const struct bwn_smpair v3[] = {
11755                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11756                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11757                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11758                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11759                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11760                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11761                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11762                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11763                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11764                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11765
11766         };
11767         int i;
11768
11769         for (i = 0; i < N(v1); i++)
11770                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11771         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11772         for (i = 0; i < N(v2); i++)
11773                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11774
11775         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11776         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11777         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11778         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11779                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11780                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11781         } else {
11782                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11783         }
11784         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11785         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11786         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11787         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11788         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11789         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11790         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11791         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11792         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11793         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11794         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11795         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11796             (siba_get_chiprev(sc->sc_dev) == 0)) {
11797                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11798                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11799         } else {
11800                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11801                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11802         }
11803         for (i = 0; i < N(v3); i++)
11804                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11805         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11806             (siba_get_chiprev(sc->sc_dev) == 0)) {
11807                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11808                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11809         }
11810
11811         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11812                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11813                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11814                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11815                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11816                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11817                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11818         } else
11819                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11820
11821         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11822         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11823         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11824         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11825         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11826         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11827         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11828             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11829             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11830
11831         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11832             (siba_get_chiprev(sc->sc_dev) == 0)) {
11833                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11834                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11835                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11836         }
11837
11838         bwn_phy_lp_digflt_save(mac);
11839 }
11840
11841 static void
11842 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11843 {
11844         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11845         struct bwn_softc *sc = mac->mac_sc;
11846         struct ifnet *ifp = sc->sc_ifp;
11847         struct ieee80211com *ic = ifp->if_l2com;
11848         static const struct bwn_smpair v1[] = {
11849                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11850                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11851                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11852                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11853                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11854                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11855                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11856         };
11857         static const struct bwn_smpair v2[] = {
11858                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11859                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11860                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11861                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11862                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11863                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11864                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11865                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11866                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11867                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11868                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11869                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11870                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11871                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11872                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11873                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11874         };
11875         static const struct bwn_smpair v3[] = {
11876                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11877                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11878                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11879                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11880                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11881                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11882                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11883                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11884         };
11885         static const struct bwn_smpair v4[] = {
11886                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11887                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11888                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11889                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11890                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11891                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11892                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11893                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11894         };
11895         static const struct bwn_smpair v5[] = {
11896                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11897                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11898                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11899                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11900                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11901                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11902                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11903                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11904         };
11905         int i;
11906         uint16_t tmp, tmp2;
11907
11908         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11909         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11910         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11911         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11912         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11913         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11914         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11915         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11916         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11917         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11918         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11919         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11920         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11921         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11922         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11923         for (i = 0; i < N(v1); i++)
11924                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11925         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11926             0xff00, plp->plp_rxpwroffset);
11927         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11928             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11929            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11930                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11931                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11932                 if (mac->mac_phy.rev == 0)
11933                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11934                             0xffcf, 0x0010);
11935                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11936         } else {
11937                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11938                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11939                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11940         }
11941         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11942         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11943         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11944                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11945         else
11946                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11947         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11948         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11949             0xfff9, (plp->plp_bxarch << 1));
11950         if (mac->mac_phy.rev == 1 &&
11951             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11952                 for (i = 0; i < N(v2); i++)
11953                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11954                             v2[i].set);
11955         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11956             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11957             ((mac->mac_phy.rev == 0) &&
11958              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11959                 for (i = 0; i < N(v3); i++)
11960                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11961                             v3[i].set);
11962         } else if (mac->mac_phy.rev == 1 ||
11963                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11964                 for (i = 0; i < N(v4); i++)
11965                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11966                             v4[i].set);
11967         } else {
11968                 for (i = 0; i < N(v5); i++)
11969                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11970                             v5[i].set);
11971         }
11972         if (mac->mac_phy.rev == 1 &&
11973             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11974                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11975                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11976                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11977                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11978         }
11979         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11980             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11981             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11982                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11983                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11984                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11985                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11986         }
11987         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11988                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11989                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11990                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11991                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11992                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11993                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11994                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11995                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11996         } else {
11997                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11998                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11999         }
12000         if (mac->mac_phy.rev == 1) {
12001                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12002                 tmp2 = (tmp & 0x03e0) >> 5;
12003                 tmp2 |= tmp2 << 5;
12004                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12005                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12006                 tmp2 = (tmp & 0x1f00) >> 8;
12007                 tmp2 |= tmp2 << 5;
12008                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12009                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12010                 tmp2 = tmp & 0x00ff;
12011                 tmp2 |= tmp << 8;
12012                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12013         }
12014 }
12015
12016 struct bwn_b2062_freq {
12017         uint16_t                freq;
12018         uint8_t                 value[6];
12019 };
12020
12021 static void
12022 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12023 {
12024 #define CALC_CTL7(freq, div)                                            \
12025         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12026 #define CALC_CTL18(freq, div)                                           \
12027         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12028 #define CALC_CTL19(freq, div)                                           \
12029         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12030         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12031         struct bwn_softc *sc = mac->mac_sc;
12032         struct ifnet *ifp = sc->sc_ifp;
12033         struct ieee80211com *ic = ifp->if_l2com;
12034         static const struct bwn_b2062_freq freqdata_tab[] = {
12035                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12036                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12037                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12038                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12039                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12040                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12041         };
12042         static const struct bwn_wpair v1[] = {
12043                 { BWN_B2062_N_TXCTL3, 0 },
12044                 { BWN_B2062_N_TXCTL4, 0 },
12045                 { BWN_B2062_N_TXCTL5, 0 },
12046                 { BWN_B2062_N_TXCTL6, 0 },
12047                 { BWN_B2062_N_PDNCTL0, 0x40 },
12048                 { BWN_B2062_N_PDNCTL0, 0 },
12049                 { BWN_B2062_N_CALIB_TS, 0x10 },
12050                 { BWN_B2062_N_CALIB_TS, 0 }
12051         };
12052         const struct bwn_b2062_freq *f = NULL;
12053         uint32_t xtalfreq, ref;
12054         unsigned int i;
12055
12056         bwn_phy_lp_b2062_tblinit(mac);
12057
12058         for (i = 0; i < N(v1); i++)
12059                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12060         if (mac->mac_phy.rev > 0)
12061                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12062                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12063         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12064                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12065         else
12066                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12067
12068         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12069             ("%s:%d: fail", __func__, __LINE__));
12070         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12071         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12072
12073         if (xtalfreq <= 30000000) {
12074                 plp->plp_div = 1;
12075                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12076         } else {
12077                 plp->plp_div = 2;
12078                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12079         }
12080
12081         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12082             CALC_CTL7(xtalfreq, plp->plp_div));
12083         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12084             CALC_CTL18(xtalfreq, plp->plp_div));
12085         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12086             CALC_CTL19(xtalfreq, plp->plp_div));
12087
12088         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12089         ref &= 0xffff;
12090         for (i = 0; i < N(freqdata_tab); i++) {
12091                 if (ref < freqdata_tab[i].freq) {
12092                         f = &freqdata_tab[i];
12093                         break;
12094                 }
12095         }
12096         if (f == NULL)
12097                 f = &freqdata_tab[N(freqdata_tab) - 1];
12098         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12099             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12100         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12101             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12102         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12103         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12104 #undef CALC_CTL7
12105 #undef CALC_CTL18
12106 #undef CALC_CTL19
12107 }
12108
12109 static void
12110 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12111 {
12112
12113         bwn_phy_lp_b2063_tblinit(mac);
12114         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12115         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12116         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12117         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12118         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12119         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12120         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12121         if (mac->mac_phy.rev == 2) {
12122                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12123                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12124                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12125         } else {
12126                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12127                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12128         }
12129 }
12130
12131 static void
12132 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12133 {
12134         struct bwn_softc *sc = mac->mac_sc;
12135         static const struct bwn_wpair v1[] = {
12136                 { BWN_B2063_RX_BB_SP8, 0x0 },
12137                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12138                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12139                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12140                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12141                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12142                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12143                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12144         };
12145         static const struct bwn_wpair v2[] = {
12146                 { BWN_B2063_TX_BB_SP3, 0x0 },
12147                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12148                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12149                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12150                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12151         };
12152         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12153         int i;
12154         uint8_t tmp;
12155
12156         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12157
12158         for (i = 0; i < 2; i++)
12159                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12160         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12161         for (i = 2; i < N(v1); i++)
12162                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12163         for (i = 0; i < 10000; i++) {
12164                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12165                         break;
12166                 DELAY(1000);
12167         }
12168
12169         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12170                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12171
12172         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12173
12174         for (i = 0; i < N(v2); i++)
12175                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12176         if (freqxtal == 24000000) {
12177                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12178                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12179         } else {
12180                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12181                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12182         }
12183         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12184         for (i = 0; i < 10000; i++) {
12185                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12186                         break;
12187                 DELAY(1000);
12188         }
12189         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12190                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12191         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12192 }
12193
12194 static void
12195 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12196 {
12197         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12198         struct bwn_softc *sc = mac->mac_sc;
12199         struct bwn_phy_lp_iq_est ie;
12200         struct bwn_txgain tx_gains;
12201         static const uint32_t pwrtbl[21] = {
12202                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12203                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12204                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12205                 0x0004c, 0x0002c, 0x0001a,
12206         };
12207         uint32_t npwr, ipwr, sqpwr, tmp;
12208         int loopback, i, j, sum, error;
12209         uint16_t save[7];
12210         uint8_t txo, bbmult, txpctlmode;
12211
12212         error = bwn_phy_lp_switch_channel(mac, 7);
12213         if (error)
12214                 device_printf(sc->sc_dev,
12215                     "failed to change channel to 7 (%d)\n", error);
12216         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12217         bbmult = bwn_phy_lp_get_bbmult(mac);
12218         if (txo)
12219                 tx_gains = bwn_phy_lp_get_txgain(mac);
12220
12221         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12222         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12223         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12224         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12225         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12226         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12227         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12228
12229         bwn_phy_lp_get_txpctlmode(mac);
12230         txpctlmode = plp->plp_txpctlmode;
12231         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12232
12233         /* disable CRS */
12234         bwn_phy_lp_set_deaf(mac, 1);
12235         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12236         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12237         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12238         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12239         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12240         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12241         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12242         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12243         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12244         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12245         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12246         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12247         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12248         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12249         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12250         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12251         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12252         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12253         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12254         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12255         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12256         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12257         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12258         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12259
12260         loopback = bwn_phy_lp_loopback(mac);
12261         if (loopback == -1)
12262                 goto done;
12263         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12264         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12265         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12266         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12267         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12268
12269         tmp = 0;
12270         memset(&ie, 0, sizeof(ie));
12271         for (i = 128; i <= 159; i++) {
12272                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12273                 sum = 0;
12274                 for (j = 5; j <= 25; j++) {
12275                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12276                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12277                                 goto done;
12278                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12279                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12280                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12281                             12);
12282                         sum += ((ipwr - npwr) * (ipwr - npwr));
12283                         if ((i == 128) || (sum < tmp)) {
12284                                 plp->plp_rccap = i;
12285                                 tmp = sum;
12286                         }
12287                 }
12288         }
12289         bwn_phy_lp_ddfs_turnoff(mac);
12290 done:
12291         /* restore CRS */
12292         bwn_phy_lp_clear_deaf(mac, 1);
12293         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12294         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12295
12296         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12297         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12298         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12299         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12300         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12301         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12302         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12303
12304         bwn_phy_lp_set_bbmult(mac, bbmult);
12305         if (txo)
12306                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12307         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12308         if (plp->plp_rccap)
12309                 bwn_phy_lp_set_rccap(mac);
12310 }
12311
12312 static void
12313 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12314 {
12315         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12316         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12317
12318         if (mac->mac_phy.rev == 1)
12319                 rc_cap = MIN(rc_cap + 5, 15);
12320
12321         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12322             MAX(plp->plp_rccap - 4, 0x80));
12323         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12324         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12325             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12326 }
12327
12328 static uint32_t
12329 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12330 {
12331         uint32_t i, q, r;
12332
12333         if (div == 0)
12334                 return (0);
12335
12336         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12337                 q <<= 1;
12338                 if (r << 1 >= div) {
12339                         q++;
12340                         r = (r << 1) - div;
12341                 }
12342         }
12343         if (r << 1 >= div)
12344                 q++;
12345         return (q);
12346 }
12347
12348 static void
12349 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12350 {
12351         struct bwn_softc *sc = mac->mac_sc;
12352
12353         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12354         DELAY(20);
12355         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12356                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12357                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12358         } else {
12359                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12360         }
12361         DELAY(5);
12362 }
12363
12364 static void
12365 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12366 {
12367
12368         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12369         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12370         DELAY(200);
12371 }
12372
12373 static void
12374 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12375 {
12376 #define FLAG_A  0x01
12377 #define FLAG_G  0x02
12378         struct bwn_softc *sc = mac->mac_sc;
12379         struct ifnet *ifp = sc->sc_ifp;
12380         struct ieee80211com *ic = ifp->if_l2com;
12381         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12382                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12383                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12384                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12385                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12386                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12387                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12388                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12389                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12390                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12391                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12392                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12393                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12399                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12426                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12427                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12428                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12429         };
12430         const struct bwn_b206x_rfinit_entry *br;
12431         unsigned int i;
12432
12433         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12434                 br = &bwn_b2062_init_tab[i];
12435                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12436                         if (br->br_flags & FLAG_G)
12437                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12438                 } else {
12439                         if (br->br_flags & FLAG_A)
12440                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12441                 }
12442         }
12443 #undef FLAG_A
12444 #undef FLAG_B
12445 }
12446
12447 static void
12448 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12449 {
12450 #define FLAG_A  0x01
12451 #define FLAG_G  0x02
12452         struct bwn_softc *sc = mac->mac_sc;
12453         struct ifnet *ifp = sc->sc_ifp;
12454         struct ieee80211com *ic = ifp->if_l2com;
12455         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12456                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12457                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12458                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12459                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12460                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12461                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12462                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12464                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12465                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12466                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12467                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12468                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12469                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12470                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12471                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12472                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12473                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12474                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12475                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12476                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12477                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12478                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12479                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12482                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12483                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12485                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12486                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12487                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12488                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12489                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12493                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12494                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12495                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12496                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12497                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12498         };
12499         const struct bwn_b206x_rfinit_entry *br;
12500         unsigned int i;
12501
12502         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12503                 br = &bwn_b2063_init_tab[i];
12504                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12505                         if (br->br_flags & FLAG_G)
12506                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12507                 } else {
12508                         if (br->br_flags & FLAG_A)
12509                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12510                 }
12511         }
12512 #undef FLAG_A
12513 #undef FLAG_B
12514 }
12515
12516 static void
12517 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12518     int count, void *_data)
12519 {
12520         unsigned int i;
12521         uint32_t offset, type;
12522         uint8_t *data = _data;
12523
12524         type = BWN_TAB_GETTYPE(typenoffset);
12525         offset = BWN_TAB_GETOFFSET(typenoffset);
12526         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12527
12528         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12529
12530         for (i = 0; i < count; i++) {
12531                 switch (type) {
12532                 case BWN_TAB_8BIT:
12533                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12534                         data++;
12535                         break;
12536                 case BWN_TAB_16BIT:
12537                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12538                             BWN_PHY_TABLEDATALO);
12539                         data += 2;
12540                         break;
12541                 case BWN_TAB_32BIT:
12542                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12543                             BWN_PHY_TABLEDATAHI);
12544                         *((uint32_t *)data) <<= 16;
12545                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12546                             BWN_PHY_TABLEDATALO);
12547                         data += 4;
12548                         break;
12549                 default:
12550                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12551                 }
12552         }
12553 }
12554
12555 static void
12556 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12557     int count, const void *_data)
12558 {
12559         uint32_t offset, type, value;
12560         const uint8_t *data = _data;
12561         unsigned int i;
12562
12563         type = BWN_TAB_GETTYPE(typenoffset);
12564         offset = BWN_TAB_GETOFFSET(typenoffset);
12565         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12566
12567         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12568
12569         for (i = 0; i < count; i++) {
12570                 switch (type) {
12571                 case BWN_TAB_8BIT:
12572                         value = *data;
12573                         data++;
12574                         KASSERT(!(value & ~0xff),
12575                             ("%s:%d: fail", __func__, __LINE__));
12576                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12577                         break;
12578                 case BWN_TAB_16BIT:
12579                         value = *((const uint16_t *)data);
12580                         data += 2;
12581                         KASSERT(!(value & ~0xffff),
12582                             ("%s:%d: fail", __func__, __LINE__));
12583                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12584                         break;
12585                 case BWN_TAB_32BIT:
12586                         value = *((const uint32_t *)data);
12587                         data += 4;
12588                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12589                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12590                         break;
12591                 default:
12592                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12593                 }
12594         }
12595 }
12596
12597 static struct bwn_txgain
12598 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12599 {
12600         struct bwn_txgain tg;
12601         uint16_t tmp;
12602
12603         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12604         if (mac->mac_phy.rev < 2) {
12605                 tmp = BWN_PHY_READ(mac,
12606                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12607                 tg.tg_gm = tmp & 0x0007;
12608                 tg.tg_pga = (tmp & 0x0078) >> 3;
12609                 tg.tg_pad = (tmp & 0x780) >> 7;
12610                 return (tg);
12611         }
12612
12613         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12614         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12615         tg.tg_gm = tmp & 0xff;
12616         tg.tg_pga = (tmp >> 8) & 0xff;
12617         return (tg);
12618 }
12619
12620 static uint8_t
12621 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12622 {
12623
12624         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12625 }
12626
12627 static void
12628 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12629 {
12630         uint16_t pa;
12631
12632         if (mac->mac_phy.rev < 2) {
12633                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12634                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12635                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12636                 bwn_phy_lp_set_txgain_override(mac);
12637                 return;
12638         }
12639
12640         pa = bwn_phy_lp_get_pa_gain(mac);
12641         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12642             (tg->tg_pga << 8) | tg->tg_gm);
12643         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12644             tg->tg_pad | (pa << 6));
12645         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12646         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12647             tg->tg_pad | (pa << 8));
12648         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12649         bwn_phy_lp_set_txgain_override(mac);
12650 }
12651
12652 static void
12653 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12654 {
12655
12656         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12657 }
12658
12659 static void
12660 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12661 {
12662         uint16_t trsw = (tx << 1) | rx;
12663
12664         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12665         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12666 }
12667
12668 static void
12669 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12670 {
12671         struct bwn_softc *sc = mac->mac_sc;
12672         struct ifnet *ifp = sc->sc_ifp;
12673         struct ieee80211com *ic = ifp->if_l2com;
12674         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12675
12676         if (mac->mac_phy.rev < 2) {
12677                 trsw = gain & 0x1;
12678                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12679                 ext_lna = (gain & 2) >> 1;
12680
12681                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12682                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12683                     0xfbff, ext_lna << 10);
12684                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12685                     0xf7ff, ext_lna << 11);
12686                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12687         } else {
12688                 low_gain = gain & 0xffff;
12689                 high_gain = (gain >> 16) & 0xf;
12690                 ext_lna = (gain >> 21) & 0x1;
12691                 trsw = ~(gain >> 20) & 0x1;
12692
12693                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12694                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12695                     0xfdff, ext_lna << 9);
12696                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12697                     0xfbff, ext_lna << 10);
12698                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12699                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12700                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12701                         tmp = (gain >> 2) & 0x3;
12702                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12703                             0xe7ff, tmp<<11);
12704                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12705                             tmp << 3);
12706                 }
12707         }
12708
12709         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12710         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12711         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12712         if (mac->mac_phy.rev >= 2) {
12713                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12714                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12715                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12716                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12717                 }
12718                 return;
12719         }
12720         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12721 }
12722
12723 static void
12724 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12725 {
12726         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12727
12728         if (user)
12729                 plp->plp_crsusr_off = 1;
12730         else
12731                 plp->plp_crssys_off = 1;
12732
12733         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12734 }
12735
12736 static void
12737 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12738 {
12739         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12740         struct bwn_softc *sc = mac->mac_sc;
12741         struct ifnet *ifp = sc->sc_ifp;
12742         struct ieee80211com *ic = ifp->if_l2com;
12743
12744         if (user)
12745                 plp->plp_crsusr_off = 0;
12746         else
12747                 plp->plp_crssys_off = 0;
12748
12749         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12750                 return;
12751
12752         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12753                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12754         else
12755                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12756 }
12757
12758 static unsigned int
12759 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12760 {
12761         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12762         static uint8_t sqrt_table[256] = {
12763                 10, 14, 17, 20, 22, 24, 26, 28,
12764                 30, 31, 33, 34, 36, 37, 38, 40,
12765                 41, 42, 43, 44, 45, 46, 47, 48,
12766                 50, 50, 51, 52, 53, 54, 55, 56,
12767                 57, 58, 59, 60, 60, 61, 62, 63,
12768                 64, 64, 65, 66, 67, 67, 68, 69,
12769                 70, 70, 71, 72, 72, 73, 74, 74,
12770                 75, 76, 76, 77, 78, 78, 79, 80,
12771                 80, 81, 81, 82, 83, 83, 84, 84,
12772                 85, 86, 86, 87, 87, 88, 88, 89,
12773                 90, 90, 91, 91, 92, 92, 93, 93,
12774                 94, 94, 95, 95, 96, 96, 97, 97,
12775                 98, 98, 99, 100, 100, 100, 101, 101,
12776                 102, 102, 103, 103, 104, 104, 105, 105,
12777                 106, 106, 107, 107, 108, 108, 109, 109,
12778                 110, 110, 110, 111, 111, 112, 112, 113,
12779                 113, 114, 114, 114, 115, 115, 116, 116,
12780                 117, 117, 117, 118, 118, 119, 119, 120,
12781                 120, 120, 121, 121, 122, 122, 122, 123,
12782                 123, 124, 124, 124, 125, 125, 126, 126,
12783                 126, 127, 127, 128, 128, 128, 129, 129,
12784                 130, 130, 130, 131, 131, 131, 132, 132,
12785                 133, 133, 133, 134, 134, 134, 135, 135,
12786                 136, 136, 136, 137, 137, 137, 138, 138,
12787                 138, 139, 139, 140, 140, 140, 141, 141,
12788                 141, 142, 142, 142, 143, 143, 143, 144,
12789                 144, 144, 145, 145, 145, 146, 146, 146,
12790                 147, 147, 147, 148, 148, 148, 149, 149,
12791                 150, 150, 150, 150, 151, 151, 151, 152,
12792                 152, 152, 153, 153, 153, 154, 154, 154,
12793                 155, 155, 155, 156, 156, 156, 157, 157,
12794                 157, 158, 158, 158, 159, 159, 159, 160
12795         };
12796
12797         if (x == 0)
12798                 return (0);
12799         if (x >= 256) {
12800                 unsigned int tmp;
12801
12802                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12803                         /* do nothing */ ;
12804                 return (tmp);
12805         }
12806         return (sqrt_table[x - 1] / 10);
12807 }
12808
12809 static int
12810 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12811 {
12812 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12813         int _t;                                                         \
12814         _t = _x - 20;                                                   \
12815         if (_t >= 0) {                                                  \
12816                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12817         } else {                                                        \
12818                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12819         }                                                               \
12820 } while (0)
12821 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12822         int _t;                                                         \
12823         _t = _x - 11;                                                   \
12824         if (_t >= 0)                                                    \
12825                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12826         else                                                            \
12827                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12828 } while (0)
12829         struct bwn_phy_lp_iq_est ie;
12830         uint16_t v0, v1;
12831         int tmp[2], ret;
12832
12833         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12834         v0 = v1 >> 8;
12835         v1 |= 0xff;
12836
12837         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12838         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12839
12840         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12841         if (ret == 0)
12842                 goto done;
12843
12844         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12845                 ret = 0;
12846                 goto done;
12847         }
12848
12849         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12850         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12851
12852         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12853         v0 = tmp[0] >> 3;
12854         v1 = tmp[1] >> 4;
12855 done:
12856         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12857         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12858         return ret;
12859 #undef CALC_COEFF
12860 #undef CALC_COEFF2
12861 }
12862
12863 static void
12864 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12865 {
12866         static const uint16_t noisescale[] = {
12867                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12868                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12869                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12870                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12871                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12872         };
12873         static const uint16_t crsgainnft[] = {
12874                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12875                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12876                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12877                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12878                 0x013d,
12879         };
12880         static const uint16_t filterctl[] = {
12881                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12882                 0xff53, 0x0127,
12883         };
12884         static const uint32_t psctl[] = {
12885                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12886                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12887                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12888                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12889                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12890                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12891                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12892                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12893         };
12894         static const uint16_t ofdmcckgain_r0[] = {
12895                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12896                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12897                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12898                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12899                 0x755d,
12900         };
12901         static const uint16_t ofdmcckgain_r1[] = {
12902                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12903                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12904                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12905                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12906                 0x755d,
12907         };
12908         static const uint16_t gaindelta[] = {
12909                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12910                 0x0000,
12911         };
12912         static const uint32_t txpwrctl[] = {
12913                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12914                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12915                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12916                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12917                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12918                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12919                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12920                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12921                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12922                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12923                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12924                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12925                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12926                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12950                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12951                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12952                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12953                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12954                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12955                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12956                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12957                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12958                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12959                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12960                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12961                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12962                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12963                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12964                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12965                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12966                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12967                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12968                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12969                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12970                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12971                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12972                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12973                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12974                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12975                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12976                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12977                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12978                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12979                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12980                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12981                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12982                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12983                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12991                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12992                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12993                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12994                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12995                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12996                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12997                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12998                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12999                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13000                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13001                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13002                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13003                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13004                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13005                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13006                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13007                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13008                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13009                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13010                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13011                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13012                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13013                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13014                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13015                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13016                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13017                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13018                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13019                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13020                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13021                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13022                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13023                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13024                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13025                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13026                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13027                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13028                 0x00000702,
13029         };
13030
13031         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13032
13033         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13034             bwn_tab_sigsq_tbl);
13035         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13036         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13037         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13038         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13039         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13040             bwn_tab_pllfrac_tbl);
13041         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13042             bwn_tabl_iqlocal_tbl);
13043         if (mac->mac_phy.rev == 0) {
13044                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13045                     ofdmcckgain_r0);
13046                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13047                     ofdmcckgain_r0);
13048         } else {
13049                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13050                     ofdmcckgain_r1);
13051                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13052                     ofdmcckgain_r1);
13053         }
13054         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13055         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13056 }
13057
13058 static void
13059 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13060 {
13061         struct bwn_softc *sc = mac->mac_sc;
13062         int i;
13063         static const uint16_t noisescale[] = {
13064                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13068                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13069                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13070                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13071         };
13072         static const uint32_t filterctl[] = {
13073                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13074                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13075         };
13076         static const uint32_t psctl[] = {
13077                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13078                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13079                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13080                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13081         };
13082         static const uint32_t gainidx[] = {
13083                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13084                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13085                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13086                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13087                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13088                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13089                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13090                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13091                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13092                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13093                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13094                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13095                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13096                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13097                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13098                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13099                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13100                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13101                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13102                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13103                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13104                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13105                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13106                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13107                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13108                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13109                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13110                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13111                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13112                 0x0000001a, 0x64ca55ad, 0x0000001a
13113         };
13114         static const uint16_t auxgainidx[] = {
13115                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13116                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13117                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13118                 0x0004, 0x0016
13119         };
13120         static const uint16_t swctl[] = {
13121                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13122                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13123                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13124                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13125                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13126                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13127                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13128                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13129         };
13130         static const uint8_t hf[] = {
13131                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13132                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13133         };
13134         static const uint32_t gainval[] = {
13135                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13136                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13137                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13138                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13139                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13141                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13142                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13143                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13144                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13145                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13146                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13147                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13148                 0x000000f1, 0x00000000, 0x00000000
13149         };
13150         static const uint16_t gain[] = {
13151                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13152                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13153                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13154                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13155                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13156                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13157                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13158                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13159                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13160                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13161                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13162                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13163         };
13164         static const uint32_t papdeps[] = {
13165                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13166                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13167                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13168                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13169                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13170                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13171                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13172                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13173                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13174                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13175                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13176                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13177                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13178         };
13179         static const uint32_t papdmult[] = {
13180                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13181                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13182                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13183                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13184                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13185                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13186                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13187                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13188                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13189                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13190                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13191                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13192                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13193         };
13194         static const uint32_t gainidx_a0[] = {
13195                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13196                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13197                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13198                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13199                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13200                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13201                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13202                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13203                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13204                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13205                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13206                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13207                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13208         };
13209         static const uint16_t auxgainidx_a0[] = {
13210                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13211                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13212                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13213                 0x0002, 0x0014
13214         };
13215         static const uint32_t gainval_a0[] = {
13216                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13217                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13218                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13219                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13220                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13221                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13222                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13223                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13224                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13225                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13226                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13227                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13228                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13229                 0x000000f7, 0x00000000, 0x00000000
13230         };
13231         static const uint16_t gain_a0[] = {
13232                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13233                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13234                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13235                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13236                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13237                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13238                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13239                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13240                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13241                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13242                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13243                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13244         };
13245
13246         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13247
13248         for (i = 0; i < 704; i++)
13249                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13250
13251         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13252             bwn_tab_sigsq_tbl);
13253         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13254         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13255         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13256         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13257         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13258         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13259         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13260         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13261         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13262         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13263             bwn_tab_pllfrac_tbl);
13264         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13265             bwn_tabl_iqlocal_tbl);
13266         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13267         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13268
13269         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13270             (siba_get_chiprev(sc->sc_dev) == 0)) {
13271                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13272                     gainidx_a0);
13273                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13274                     auxgainidx_a0);
13275                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13276                     gainval_a0);
13277                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13278         }
13279 }
13280
13281 static void
13282 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13283 {
13284         struct bwn_softc *sc = mac->mac_sc;
13285         struct ifnet *ifp = sc->sc_ifp;
13286         struct ieee80211com *ic = ifp->if_l2com;
13287         static struct bwn_txgain_entry txgain_r2[] = {
13288                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13289                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13290                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13291                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13292                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13293                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13294                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13295                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13296                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13297                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13298                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13299                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13300                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13301                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13302                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13303                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13304                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13305                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13306                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13307                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13308                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13309                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13310                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13311                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13312                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13313                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13314                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13315                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13316                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13317                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13318                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13319                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13320                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13321                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13322                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13323                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13324                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13325                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13326                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13327                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13328                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13329                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13330                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13331                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13332                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13333                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13334                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13335                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13336                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13337                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13338                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13339                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13340                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13341                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13342                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13343                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13344                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13345                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13346                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13347                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13348                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13349                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13350                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13351                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13352         };
13353         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13354                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13355                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13356                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13357                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13358                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13359                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13360                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13361                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13362                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13363                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13364                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13365                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13366                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13367                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13368                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13369                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13370                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13371                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13372                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13373                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13374                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13375                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13376                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13377                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13378                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13379                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13380                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13381                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13382                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13383                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13384                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13385                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13386                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13387                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13388                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13389                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13390                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13391                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13392                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13393                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13394                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13395                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13396                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13397                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13398                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13399                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13400                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13401                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13402                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13403                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13404                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13405                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13406                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13407                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13408                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13409                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13410                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13411                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13412                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13413                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13414                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13415                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13416                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13417                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13418         };
13419         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13420                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13421                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13422                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13423                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13424                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13425                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13426                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13427                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13428                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13429                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13430                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13431                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13432                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13433                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13434                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13435                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13436                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13437                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13438                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13439                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13440                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13441                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13442                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13443                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13444                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13445                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13446                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13447                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13448                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13449                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13450                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13451                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13452                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13453                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13454                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13455                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13456                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13457                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13458                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13459                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13460                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13461                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13462                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13463                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13464                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13465                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13466                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13467                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13468                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13469                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13470                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13471                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13472                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13473                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13474                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13475                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13476                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13477                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13478                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13479                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13480                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13481                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13482                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13483                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13484         };
13485         static struct bwn_txgain_entry txgain_r0[] = {
13486                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13487                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13488                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13489                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13490                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13491                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13492                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13493                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13494                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13495                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13496                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13497                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13498                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13499                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13500                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13501                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13502                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13503                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13504                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13505                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13506                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13507                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13508                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13509                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13510                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13511                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13512                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13513                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13514                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13515                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13516                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13517                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13518                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13519                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13520                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13521                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13522                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13523                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13524                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13525                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13526                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13527                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13528                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13529                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13530                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13531                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13532                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13533                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13534                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13535                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13536                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13537                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13538                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13539                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13540                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13541                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13542                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13543                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13544                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13545                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13546                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13547                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13548                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13549                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13550         };
13551         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13552                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13553                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13554                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13555                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13556                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13557                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13558                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13559                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13560                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13561                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13562                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13563                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13564                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13565                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13566                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13567                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13568                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13569                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13570                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13571                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13572                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13573                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13574                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13575                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13576                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13577                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13578                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13579                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13580                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13581                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13582                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13583                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13584                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13585                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13586                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13587                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13588                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13589                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13590                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13591                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13592                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13593                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13594                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13595                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13596                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13597                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13598                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13599                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13600                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13601                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13602                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13603                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13604                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13605                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13606                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13607                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13608                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13609                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13610                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13611                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13612                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13613                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13614                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13615                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13616         };
13617         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13618                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13619                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13620                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13621                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13622                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13623                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13624                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13625                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13626                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13627                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13628                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13629                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13630                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13631                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13632                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13633                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13634                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13635                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13636                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13637                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13638                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13639                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13640                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13641                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13642                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13643                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13644                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13645                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13646                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13647                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13648                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13649                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13650                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13651                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13652                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13653                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13654                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13655                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13656                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13657                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13658                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13659                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13660                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13661                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13662                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13663                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13664                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13665                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13666                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13667                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13668                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13669                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13670                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13671                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13672                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13673                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13674                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13675                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13676                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13677                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13678                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13679                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13680                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13681                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13682         };
13683         static struct bwn_txgain_entry txgain_r1[] = {
13684                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13685                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13686                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13687                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13688                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13689                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13690                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13691                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13692                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13693                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13694                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13695                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13696                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13697                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13698                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13699                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13700                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13701                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13702                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13703                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13704                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13705                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13706                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13707                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13708                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13709                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13710                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13711                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13712                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13713                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13714                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13715                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13716                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13717                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13718                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13719                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13720                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13721                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13722                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13723                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13724                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13725                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13726                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13727                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13728                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13729                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13730                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13731                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13732                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13733                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13734                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13735                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13736                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13737                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13738                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13739                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13740                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13741                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13742                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13743                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13744                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13745                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13746                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13747                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13748                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13749                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13750                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13751                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13752                 { 7, 11, 6, 0, 71 }
13753         };
13754         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13755                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13756                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13757                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13758                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13759                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13760                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13761                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13762                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13763                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13764                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13765                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13766                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13767                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13768                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13769                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13770                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13771                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13772                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13773                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13774                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13775                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13776                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13777                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13778                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13779                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13780                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13781                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13782                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13783                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13784                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13785                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13786                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13787                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13788                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13789                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13790                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13791                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13792                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13793                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13794                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13795                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13796                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13797                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13798                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13799                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13800                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13801                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13802                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13803                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13804                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13805                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13806                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13807                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13808                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13809                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13810                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13811                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13812                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13813                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13814                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13815                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13816                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13817                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13818                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13819         };
13820         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13821                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13822                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13823                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13824                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13825                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13826                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13827                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13828                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13829                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13830                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13831                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13832                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13833                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13834                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13835                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13836                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13837                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13838                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13839                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13840                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13841                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13842                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13843                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13844                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13845                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13846                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13847                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13848                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13849                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13850                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13851                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13852                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13853                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13854                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13855                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13856                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13857                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13858                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13859                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13860                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13861                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13862                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13863                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13864                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13865                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13866                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13867                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13868                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13869                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13870                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13871                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13872                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13873                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13874                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13875                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13876                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13877                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13878                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13879                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13880                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13881                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13882                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13883                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13884                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13885         };
13886
13887         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13888                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13889                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13890                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13891                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13892                             txgain_2ghz_r2);
13893                 else
13894                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13895                             txgain_5ghz_r2);
13896                 return;
13897         }
13898
13899         if (mac->mac_phy.rev == 0) {
13900                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13901                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13902                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13903                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13904                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13905                             txgain_2ghz_r0);
13906                 else
13907                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13908                             txgain_5ghz_r0);
13909                 return;
13910         }
13911
13912         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13913             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13914                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13915         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13916                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13917         else
13918                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13919 }
13920
13921 static void
13922 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13923 {
13924         uint32_t offset, type;
13925
13926         type = BWN_TAB_GETTYPE(typeoffset);
13927         offset = BWN_TAB_GETOFFSET(typeoffset);
13928         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13929
13930         switch (type) {
13931         case BWN_TAB_8BIT:
13932                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13933                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13934                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13935                 break;
13936         case BWN_TAB_16BIT:
13937                 KASSERT(!(value & ~0xffff),
13938                     ("%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_32BIT:
13943                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13944                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13945                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13946                 break;
13947         default:
13948                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13949         }
13950 }
13951
13952 static int
13953 bwn_phy_lp_loopback(struct bwn_mac *mac)
13954 {
13955         struct bwn_phy_lp_iq_est ie;
13956         int i, index = -1;
13957         uint32_t tmp;
13958
13959         memset(&ie, 0, sizeof(ie));
13960
13961         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13962         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13963         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13964         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13965         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13966         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13967         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13968         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13969         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13970         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13971         for (i = 0; i < 32; i++) {
13972                 bwn_phy_lp_set_rxgain_idx(mac, i);
13973                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13974                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13975                         continue;
13976                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13977                 if ((tmp > 4000) && (tmp < 10000)) {
13978                         index = i;
13979                         break;
13980                 }
13981         }
13982         bwn_phy_lp_ddfs_turnoff(mac);
13983         return (index);
13984 }
13985
13986 static void
13987 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13988 {
13989
13990         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13991 }
13992
13993 static void
13994 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13995     int incr1, int incr2, int scale_idx)
13996 {
13997
13998         bwn_phy_lp_ddfs_turnoff(mac);
13999         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14000         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14001         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14002         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14003         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14004         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14005         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14006         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14007         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14008         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14009 }
14010
14011 static uint8_t
14012 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14013     struct bwn_phy_lp_iq_est *ie)
14014 {
14015         int i;
14016
14017         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14018         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14019         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14020         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14021         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14022
14023         for (i = 0; i < 500; i++) {
14024                 if (!(BWN_PHY_READ(mac,
14025                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14026                         break;
14027                 DELAY(1000);
14028         }
14029         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14030                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14031                 return 0;
14032         }
14033
14034         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14035         ie->ie_iqprod <<= 16;
14036         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14037         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14038         ie->ie_ipwr <<= 16;
14039         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14040         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14041         ie->ie_qpwr <<= 16;
14042         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14043
14044         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14045         return 1;
14046 }
14047
14048 static uint32_t
14049 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14050 {
14051         uint32_t offset, type, value;
14052
14053         type = BWN_TAB_GETTYPE(typeoffset);
14054         offset = BWN_TAB_GETOFFSET(typeoffset);
14055         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14056
14057         switch (type) {
14058         case BWN_TAB_8BIT:
14059                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14060                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14061                 break;
14062         case BWN_TAB_16BIT:
14063                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14064                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14065                 break;
14066         case BWN_TAB_32BIT:
14067                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14068                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14069                 value <<= 16;
14070                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14071                 break;
14072         default:
14073                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14074                 value = 0;
14075         }
14076
14077         return (value);
14078 }
14079
14080 static void
14081 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14082 {
14083
14084         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14085         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14086 }
14087
14088 static void
14089 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14090 {
14091         uint16_t ctl;
14092
14093         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14094         ctl |= dac << 7;
14095         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14096 }
14097
14098 static void
14099 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14100 {
14101
14102         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14103         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14104 }
14105
14106 static void
14107 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14108 {
14109
14110         if (mac->mac_phy.rev < 2)
14111                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14112         else {
14113                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14114                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14115         }
14116         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14117 }
14118
14119 static uint16_t
14120 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14121 {
14122
14123         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14124 }
14125
14126 static uint8_t
14127 bwn_nbits(int32_t val)
14128 {
14129         uint32_t tmp;
14130         uint8_t nbits = 0;
14131
14132         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14133                 nbits++;
14134         return (nbits);
14135 }
14136
14137 static void
14138 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14139     struct bwn_txgain_entry *table)
14140 {
14141         int i;
14142
14143         for (i = offset; i < count; i++)
14144                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14145 }
14146
14147 static void
14148 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14149     struct bwn_txgain_entry data)
14150 {
14151
14152         if (mac->mac_phy.rev >= 2)
14153                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14154         else
14155                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14156 }
14157
14158 static void
14159 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14160     struct bwn_txgain_entry te)
14161 {
14162         struct bwn_softc *sc = mac->mac_sc;
14163         struct ifnet *ifp = sc->sc_ifp;
14164         struct ieee80211com *ic = ifp->if_l2com;
14165         uint32_t tmp;
14166
14167         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14168
14169         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14170         if (mac->mac_phy.rev >= 3) {
14171                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14172                     (0x10 << 24) : (0x70 << 24));
14173         } else {
14174                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14175                     (0x14 << 24) : (0x7f << 24));
14176         }
14177         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14178         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14179             te.te_bbmult << 20 | te.te_dac << 28);
14180 }
14181
14182 static void
14183 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14184     struct bwn_txgain_entry te)
14185 {
14186
14187         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14188
14189         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14190             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14191             te.te_dac);
14192         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14193 }
14194
14195 static void
14196 bwn_sysctl_node(struct bwn_softc *sc)
14197 {
14198         device_t dev = sc->sc_dev;
14199         struct bwn_mac *mac;
14200         struct bwn_stats *stats;
14201
14202         /* XXX assume that count of MAC is only 1. */
14203
14204         if ((mac = sc->sc_curmac) == NULL)
14205                 return;
14206         stats = &mac->mac_stats;
14207
14208         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14209             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14210             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14211         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14212             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14213             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14214         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14215             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14216             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14217
14218 #ifdef BWN_DEBUG
14219         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14220             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14221             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14222 #endif
14223 }
14224
14225 static device_method_t bwn_methods[] = {
14226         /* Device interface */
14227         DEVMETHOD(device_probe,         bwn_probe),
14228         DEVMETHOD(device_attach,        bwn_attach),
14229         DEVMETHOD(device_detach,        bwn_detach),
14230         DEVMETHOD(device_suspend,       bwn_suspend),
14231         DEVMETHOD(device_resume,        bwn_resume),
14232         KOBJMETHOD_END
14233 };
14234 static driver_t bwn_driver = {
14235         "bwn",
14236         bwn_methods,
14237         sizeof(struct bwn_softc)
14238 };
14239 static devclass_t bwn_devclass;
14240 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14241 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14242 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14243 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14244 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);