]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwn/if_bwn.c
Set ic_softc in all 802.11 drivers. Not required right now, but will be
[FreeBSD/FreeBSD.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/siba/siba_ids.h>
65 #include <dev/siba/sibareg.h>
66 #include <dev/siba/sibavar.h>
67
68 #include <net80211/ieee80211_var.h>
69 #include <net80211/ieee80211_radiotap.h>
70 #include <net80211/ieee80211_regdomain.h>
71 #include <net80211/ieee80211_phy.h>
72 #include <net80211/ieee80211_ratectl.h>
73
74 #include <dev/bwn/if_bwnreg.h>
75 #include <dev/bwn/if_bwnvar.h>
76
77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
78     "Broadcom driver parameters");
79
80 /*
81  * Tunable & sysctl variables.
82  */
83
84 #ifdef BWN_DEBUG
85 static  int bwn_debug = 0;
86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
87     "Broadcom debugging printfs");
88 enum {
89         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
90         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
91         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
92         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
93         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
94         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
95         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
96         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
97         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
98         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
99         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
100         BWN_DEBUG_LED           = 0x00000800,   /* led management */
101         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
102         BWN_DEBUG_LO            = 0x00002000,   /* LO */
103         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
104         BWN_DEBUG_WME           = 0x00008000,   /* WME */
105         BWN_DEBUG_RF            = 0x00010000,   /* RF */
106         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
107         BWN_DEBUG_ANY           = 0xffffffff
108 };
109 #define DPRINTF(sc, m, fmt, ...) do {                   \
110         if (sc->sc_debug & (m))                         \
111                 printf(fmt, __VA_ARGS__);               \
112 } while (0)
113 #else
114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
115 #endif
116
117 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
118 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
119     "uses Bad Frames Preemption");
120 static int      bwn_bluetooth = 1;
121 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
122     "turns on Bluetooth Coexistence");
123 static int      bwn_hwpctl = 0;
124 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
125     "uses H/W power control");
126 static int      bwn_msi_disable = 0;            /* MSI disabled  */
127 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
128 static int      bwn_usedma = 1;
129 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
130     "uses DMA");
131 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
132 static int      bwn_wme = 1;
133 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
134     "uses WME support");
135
136 static int      bwn_attach_pre(struct bwn_softc *);
137 static int      bwn_attach_post(struct bwn_softc *);
138 static void     bwn_sprom_bugfixes(device_t);
139 static void     bwn_init(void *);
140 static int      bwn_init_locked(struct bwn_softc *);
141 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t);
142 static void     bwn_start(struct ifnet *);
143 static int      bwn_attach_core(struct bwn_mac *);
144 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
145 static int      bwn_phy_getinfo(struct bwn_mac *, int);
146 static int      bwn_chiptest(struct bwn_mac *);
147 static int      bwn_setup_channels(struct bwn_mac *, int, int);
148 static int      bwn_phy_g_attach(struct bwn_mac *);
149 static void     bwn_phy_g_detach(struct bwn_mac *);
150 static void     bwn_phy_g_init_pre(struct bwn_mac *);
151 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
152 static int      bwn_phy_g_init(struct bwn_mac *);
153 static void     bwn_phy_g_exit(struct bwn_mac *);
154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
155 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
156                     uint16_t);
157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
158 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
159                     uint16_t);
160 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
161 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
162 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
164 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
165 static int      bwn_phy_g_im(struct bwn_mac *, int);
166 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
167 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
168 static void     bwn_phy_g_task_15s(struct bwn_mac *);
169 static void     bwn_phy_g_task_60s(struct bwn_mac *);
170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
171 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
173 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
174                     uint16_t);
175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
176 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
177                     uint32_t);
178 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
179                     uint16_t);
180 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
181                     const struct bwn_channelinfo *, int);
182 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
183                     const struct ieee80211_bpf_params *);
184 static void     bwn_updateslot(struct ifnet *);
185 static void     bwn_update_promisc(struct ifnet *);
186 static void     bwn_wme_init(struct bwn_mac *);
187 static int      bwn_wme_update(struct ieee80211com *);
188 static void     bwn_wme_clear(struct bwn_softc *);
189 static void     bwn_wme_load(struct bwn_mac *);
190 static void     bwn_wme_loadparams(struct bwn_mac *,
191                     const struct wmeParams *, uint16_t);
192 static void     bwn_scan_start(struct ieee80211com *);
193 static void     bwn_scan_end(struct ieee80211com *);
194 static void     bwn_set_channel(struct ieee80211com *);
195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
196                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
197                     const uint8_t [IEEE80211_ADDR_LEN],
198                     const uint8_t [IEEE80211_ADDR_LEN]);
199 static void     bwn_vap_delete(struct ieee80211vap *);
200 static void     bwn_stop(struct bwn_softc *, int);
201 static void     bwn_stop_locked(struct bwn_softc *, int);
202 static int      bwn_core_init(struct bwn_mac *);
203 static void     bwn_core_start(struct bwn_mac *);
204 static void     bwn_core_exit(struct bwn_mac *);
205 static void     bwn_bt_disable(struct bwn_mac *);
206 static int      bwn_chip_init(struct bwn_mac *);
207 static uint64_t bwn_hf_read(struct bwn_mac *);
208 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
209 static void     bwn_set_txretry(struct bwn_mac *, int, int);
210 static void     bwn_rate_init(struct bwn_mac *);
211 static void     bwn_set_phytxctl(struct bwn_mac *);
212 static void     bwn_spu_setdelay(struct bwn_mac *, int);
213 static void     bwn_bt_enable(struct bwn_mac *);
214 static void     bwn_set_macaddr(struct bwn_mac *);
215 static void     bwn_crypt_init(struct bwn_mac *);
216 static void     bwn_chip_exit(struct bwn_mac *);
217 static int      bwn_fw_fillinfo(struct bwn_mac *);
218 static int      bwn_fw_loaducode(struct bwn_mac *);
219 static int      bwn_gpio_init(struct bwn_mac *);
220 static int      bwn_fw_loadinitvals(struct bwn_mac *);
221 static int      bwn_phy_init(struct bwn_mac *);
222 static void     bwn_set_txantenna(struct bwn_mac *, int);
223 static void     bwn_set_opmode(struct bwn_mac *);
224 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
225 static uint8_t  bwn_plcp_getcck(const uint8_t);
226 static uint8_t  bwn_plcp_getofdm(const uint8_t);
227 static void     bwn_pio_init(struct bwn_mac *);
228 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
229 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
230                     int);
231 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
232                     struct bwn_pio_rxqueue *, int);
233 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
234 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
235                     uint16_t);
236 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
237 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
238 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
239 static void     bwn_pio_handle_txeof(struct bwn_mac *,
240                     const struct bwn_txstatus *);
241 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
242 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
243 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
244                     uint16_t);
245 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
246                     uint32_t);
247 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
248                     struct mbuf *);
249 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
250 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
251                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
252 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
253                     uint16_t, uint32_t);
254 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
255                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
256 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
257                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
258 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
259                     uint16_t, struct bwn_pio_txpkt **);
260 static void     bwn_dma_init(struct bwn_mac *);
261 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
262 static int      bwn_dma_mask2type(uint64_t);
263 static uint64_t bwn_dma_mask(struct bwn_mac *);
264 static uint16_t bwn_dma_base(int, int);
265 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
266 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
267                     int, struct bwn_dmadesc_generic **,
268                     struct bwn_dmadesc_meta **);
269 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
270                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
271                     int, int);
272 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
273 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
274 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
275 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
276 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
277 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
278                     int, struct bwn_dmadesc_generic **,
279                     struct bwn_dmadesc_meta **);
280 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
281                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
282                     int, int);
283 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
284 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
285 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
286 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
287 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
288 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
289 static void     bwn_dma_setup(struct bwn_dma_ring *);
290 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
291 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
292 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
293 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
294 static void     bwn_dma_rx(struct bwn_dma_ring *);
295 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
296 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
297                     struct bwn_dmadesc_meta *);
298 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
299 static int      bwn_dma_gettype(struct bwn_mac *);
300 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
301 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
302 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
303 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
304 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
305                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
306                     int);
307 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
308                     bus_size_t, int);
309 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
310 static void     bwn_dma_handle_txeof(struct bwn_mac *,
311                     const struct bwn_txstatus *);
312 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
313                     struct mbuf *);
314 static int      bwn_dma_getslot(struct bwn_dma_ring *);
315 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
316                     uint8_t);
317 static int      bwn_dma_attach(struct bwn_mac *);
318 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
319                     int, int, int);
320 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
321                     const struct bwn_txstatus *, uint16_t, int *);
322 static void     bwn_dma_free(struct bwn_mac *);
323 static void     bwn_phy_g_init_sub(struct bwn_mac *);
324 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
325 static void     bwn_phy_init_b5(struct bwn_mac *);
326 static void     bwn_phy_init_b6(struct bwn_mac *);
327 static void     bwn_phy_init_a(struct bwn_mac *);
328 static void     bwn_loopback_calcgain(struct bwn_mac *);
329 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
330 static void     bwn_lo_g_init(struct bwn_mac *);
331 static void     bwn_lo_g_adjust(struct bwn_mac *);
332 static void     bwn_lo_get_powervector(struct bwn_mac *);
333 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
334                     const struct bwn_bbatt *, const struct bwn_rfatt *);
335 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
336 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
337 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
338 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
339                     const struct bwn_bbatt *, const struct bwn_rfatt *,
340                     uint8_t);
341 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
342 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
343 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
344 static void     bwn_wa_init(struct bwn_mac *);
345 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
346                     uint16_t);
347 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
348 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
349                     uint32_t);
350 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
351                     uint16_t);
352 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
353 static void     bwn_mac_suspend(struct bwn_mac *);
354 static void     bwn_mac_enable(struct bwn_mac *);
355 static void     bwn_psctl(struct bwn_mac *, uint32_t);
356 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
357 static void     bwn_nrssi_offset(struct bwn_mac *);
358 static void     bwn_nrssi_threshold(struct bwn_mac *);
359 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
360 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
361                     int16_t);
362 static void     bwn_set_original_gains(struct bwn_mac *);
363 static void     bwn_hwpctl_early_init(struct bwn_mac *);
364 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
365 static uint16_t bwn_phy_g_chan2freq(uint8_t);
366 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
367 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
368                     const char *, struct bwn_fwfile *);
369 static void     bwn_release_firmware(struct bwn_mac *);
370 static void     bwn_do_release_fw(struct bwn_fwfile *);
371 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
372 static int      bwn_fwinitvals_write(struct bwn_mac *,
373                     const struct bwn_fwinitvals *, size_t, size_t);
374 static int      bwn_switch_channel(struct bwn_mac *, int);
375 static uint16_t bwn_ant2phy(int);
376 static void     bwn_mac_write_bssid(struct bwn_mac *);
377 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
378                     const uint8_t *);
379 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
380                     const uint8_t *, size_t, const uint8_t *);
381 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
382                     const uint8_t *);
383 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
384                     const uint8_t *);
385 static void     bwn_phy_exit(struct bwn_mac *);
386 static void     bwn_core_stop(struct bwn_mac *);
387 static int      bwn_switch_band(struct bwn_softc *,
388                     struct ieee80211_channel *);
389 static void     bwn_phy_reset(struct bwn_mac *);
390 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
391 static void     bwn_set_pretbtt(struct bwn_mac *);
392 static int      bwn_intr(void *);
393 static void     bwn_intrtask(void *, int);
394 static void     bwn_restart(struct bwn_mac *, const char *);
395 static void     bwn_intr_ucode_debug(struct bwn_mac *);
396 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
397 static void     bwn_intr_atim_end(struct bwn_mac *);
398 static void     bwn_intr_beacon(struct bwn_mac *);
399 static void     bwn_intr_pmq(struct bwn_mac *);
400 static void     bwn_intr_noise(struct bwn_mac *);
401 static void     bwn_intr_txeof(struct bwn_mac *);
402 static void     bwn_hwreset(void *, int);
403 static void     bwn_handle_fwpanic(struct bwn_mac *);
404 static void     bwn_load_beacon0(struct bwn_mac *);
405 static void     bwn_load_beacon1(struct bwn_mac *);
406 static uint32_t bwn_jssi_read(struct bwn_mac *);
407 static void     bwn_noise_gensample(struct bwn_mac *);
408 static void     bwn_handle_txeof(struct bwn_mac *,
409                     const struct bwn_txstatus *);
410 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
411 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
412 static void     bwn_start_locked(struct ifnet *);
413 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
414                     struct mbuf *);
415 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
416 static int      bwn_set_txhdr(struct bwn_mac *,
417                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
418                     uint16_t);
419 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
420                     const uint8_t);
421 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
422 static uint8_t  bwn_get_fbrate(uint8_t);
423 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
424 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
425 static void     bwn_phy_lock(struct bwn_mac *);
426 static void     bwn_phy_unlock(struct bwn_mac *);
427 static void     bwn_rf_lock(struct bwn_mac *);
428 static void     bwn_rf_unlock(struct bwn_mac *);
429 static void     bwn_txpwr(void *, int);
430 static void     bwn_tasks(void *);
431 static void     bwn_task_15s(struct bwn_mac *);
432 static void     bwn_task_30s(struct bwn_mac *);
433 static void     bwn_task_60s(struct bwn_mac *);
434 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
435                     uint8_t);
436 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
437 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
438                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
439                     int, int);
440 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
441 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
442 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
443 static void     bwn_watchdog(void *);
444 static void     bwn_dma_stop(struct bwn_mac *);
445 static void     bwn_pio_stop(struct bwn_mac *);
446 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
447 static void     bwn_led_attach(struct bwn_mac *);
448 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
449 static void     bwn_led_event(struct bwn_mac *, int);
450 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
451 static void     bwn_led_blink_next(void *);
452 static void     bwn_led_blink_end(void *);
453 static void     bwn_rfswitch(void *);
454 static void     bwn_rf_turnon(struct bwn_mac *);
455 static void     bwn_rf_turnoff(struct bwn_mac *);
456 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
457 static int      bwn_phy_lp_init(struct bwn_mac *);
458 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
459 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
460 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
461                     uint16_t);
462 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
463 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
464 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
465 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
466 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
467 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
468 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
469 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
470 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
471 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
472 static void     bwn_phy_lp_calib(struct bwn_mac *);
473 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
474 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
475 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
476 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
477 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
478 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
479 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
480 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
481 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
482 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
483 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
484 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
485 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
486 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
487 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
488 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
489 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
490 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
491 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
492 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
493 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
494 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
495                     const void *);
496 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
497 static struct bwn_txgain
498                 bwn_phy_lp_get_txgain(struct bwn_mac *);
499 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
500 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
501 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
502 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
503 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
504 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
505 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
506 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
507 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
508 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
509 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
510 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
511 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
512 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
513 static int      bwn_phy_lp_loopback(struct bwn_mac *);
514 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
515 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
516                     int);
517 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
518                     struct bwn_phy_lp_iq_est *);
519 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
520 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
521 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
522 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
523 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
524 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
525 static uint8_t  bwn_nbits(int32_t);
526 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
527                     struct bwn_txgain_entry *);
528 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
529                     struct bwn_txgain_entry);
530 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
531                     struct bwn_txgain_entry);
532 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
533                     struct bwn_txgain_entry);
534 static void     bwn_sysctl_node(struct bwn_softc *);
535
536 static struct resource_spec bwn_res_spec_legacy[] = {
537         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
538         { -1,                   0,              0 }
539 };
540
541 static struct resource_spec bwn_res_spec_msi[] = {
542         { SYS_RES_IRQ,          1,              RF_ACTIVE },
543         { -1,                   0,              0 }
544 };
545
546 static const struct bwn_channelinfo bwn_chantable_bg = {
547         .channels = {
548                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
549                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
550                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
551                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
552                 { 2472, 13, 30 }, { 2484, 14, 30 } },
553         .nchannels = 14
554 };
555
556 static const struct bwn_channelinfo bwn_chantable_a = {
557         .channels = {
558                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
559                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
560                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
561                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
562                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
563                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
564                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
565                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
566                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
567                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
568                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
569                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
570                 { 6080, 216, 30 } },
571         .nchannels = 37
572 };
573
574 static const struct bwn_channelinfo bwn_chantable_n = {
575         .channels = {
576                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
577                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
578                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
579                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
580                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
581                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
582                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
583                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
584                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
585                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
586                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
587                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
588                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
589                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
590                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
591                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
592                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
593                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
594                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
595                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
596                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
597                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
598                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
599                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
600                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
601                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
602                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
603                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
604                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
605                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
606                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
607                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
608                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
609                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
610                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
611                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
612                 { 6130, 226, 30 }, { 6140, 228, 30 } },
613         .nchannels = 110
614 };
615
616 static const uint8_t bwn_b2063_chantable_data[33][12] = {
617         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
622         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
623         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
624         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
628         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
629         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
630         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
631         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
633         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
634         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
635         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
636         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
638         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
642         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
649         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
650 };
651
652 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
653         { 1, 2412, bwn_b2063_chantable_data[0] },
654         { 2, 2417, bwn_b2063_chantable_data[0] },
655         { 3, 2422, bwn_b2063_chantable_data[0] },
656         { 4, 2427, bwn_b2063_chantable_data[1] },
657         { 5, 2432, bwn_b2063_chantable_data[1] },
658         { 6, 2437, bwn_b2063_chantable_data[1] },
659         { 7, 2442, bwn_b2063_chantable_data[1] },
660         { 8, 2447, bwn_b2063_chantable_data[1] },
661         { 9, 2452, bwn_b2063_chantable_data[2] },
662         { 10, 2457, bwn_b2063_chantable_data[2] },
663         { 11, 2462, bwn_b2063_chantable_data[3] },
664         { 12, 2467, bwn_b2063_chantable_data[3] },
665         { 13, 2472, bwn_b2063_chantable_data[3] },
666         { 14, 2484, bwn_b2063_chantable_data[4] },
667         { 34, 5170, bwn_b2063_chantable_data[5] },
668         { 36, 5180, bwn_b2063_chantable_data[6] },
669         { 38, 5190, bwn_b2063_chantable_data[7] },
670         { 40, 5200, bwn_b2063_chantable_data[8] },
671         { 42, 5210, bwn_b2063_chantable_data[9] },
672         { 44, 5220, bwn_b2063_chantable_data[10] },
673         { 46, 5230, bwn_b2063_chantable_data[11] },
674         { 48, 5240, bwn_b2063_chantable_data[12] },
675         { 52, 5260, bwn_b2063_chantable_data[13] },
676         { 56, 5280, bwn_b2063_chantable_data[14] },
677         { 60, 5300, bwn_b2063_chantable_data[14] },
678         { 64, 5320, bwn_b2063_chantable_data[15] },
679         { 100, 5500, bwn_b2063_chantable_data[16] },
680         { 104, 5520, bwn_b2063_chantable_data[17] },
681         { 108, 5540, bwn_b2063_chantable_data[18] },
682         { 112, 5560, bwn_b2063_chantable_data[19] },
683         { 116, 5580, bwn_b2063_chantable_data[20] },
684         { 120, 5600, bwn_b2063_chantable_data[21] },
685         { 124, 5620, bwn_b2063_chantable_data[21] },
686         { 128, 5640, bwn_b2063_chantable_data[22] },
687         { 132, 5660, bwn_b2063_chantable_data[22] },
688         { 136, 5680, bwn_b2063_chantable_data[22] },
689         { 140, 5700, bwn_b2063_chantable_data[23] },
690         { 149, 5745, bwn_b2063_chantable_data[23] },
691         { 153, 5765, bwn_b2063_chantable_data[23] },
692         { 157, 5785, bwn_b2063_chantable_data[23] },
693         { 161, 5805, bwn_b2063_chantable_data[23] },
694         { 165, 5825, bwn_b2063_chantable_data[23] },
695         { 184, 4920, bwn_b2063_chantable_data[24] },
696         { 188, 4940, bwn_b2063_chantable_data[25] },
697         { 192, 4960, bwn_b2063_chantable_data[26] },
698         { 196, 4980, bwn_b2063_chantable_data[27] },
699         { 200, 5000, bwn_b2063_chantable_data[28] },
700         { 204, 5020, bwn_b2063_chantable_data[29] },
701         { 208, 5040, bwn_b2063_chantable_data[30] },
702         { 212, 5060, bwn_b2063_chantable_data[31] },
703         { 216, 5080, bwn_b2063_chantable_data[32] }
704 };
705
706 static const uint8_t bwn_b2062_chantable_data[22][12] = {
707         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
708         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
720         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
728         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
729 };
730
731 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
732         { 1, 2412, bwn_b2062_chantable_data[0] },
733         { 2, 2417, bwn_b2062_chantable_data[0] },
734         { 3, 2422, bwn_b2062_chantable_data[0] },
735         { 4, 2427, bwn_b2062_chantable_data[0] },
736         { 5, 2432, bwn_b2062_chantable_data[0] },
737         { 6, 2437, bwn_b2062_chantable_data[0] },
738         { 7, 2442, bwn_b2062_chantable_data[0] },
739         { 8, 2447, bwn_b2062_chantable_data[0] },
740         { 9, 2452, bwn_b2062_chantable_data[0] },
741         { 10, 2457, bwn_b2062_chantable_data[0] },
742         { 11, 2462, bwn_b2062_chantable_data[0] },
743         { 12, 2467, bwn_b2062_chantable_data[0] },
744         { 13, 2472, bwn_b2062_chantable_data[0] },
745         { 14, 2484, bwn_b2062_chantable_data[0] },
746         { 34, 5170, bwn_b2062_chantable_data[1] },
747         { 38, 5190, bwn_b2062_chantable_data[2] },
748         { 42, 5210, bwn_b2062_chantable_data[2] },
749         { 46, 5230, bwn_b2062_chantable_data[3] },
750         { 36, 5180, bwn_b2062_chantable_data[4] },
751         { 40, 5200, bwn_b2062_chantable_data[5] },
752         { 44, 5220, bwn_b2062_chantable_data[6] },
753         { 48, 5240, bwn_b2062_chantable_data[3] },
754         { 52, 5260, bwn_b2062_chantable_data[3] },
755         { 56, 5280, bwn_b2062_chantable_data[3] },
756         { 60, 5300, bwn_b2062_chantable_data[7] },
757         { 64, 5320, bwn_b2062_chantable_data[8] },
758         { 100, 5500, bwn_b2062_chantable_data[9] },
759         { 104, 5520, bwn_b2062_chantable_data[10] },
760         { 108, 5540, bwn_b2062_chantable_data[10] },
761         { 112, 5560, bwn_b2062_chantable_data[10] },
762         { 116, 5580, bwn_b2062_chantable_data[11] },
763         { 120, 5600, bwn_b2062_chantable_data[12] },
764         { 124, 5620, bwn_b2062_chantable_data[12] },
765         { 128, 5640, bwn_b2062_chantable_data[12] },
766         { 132, 5660, bwn_b2062_chantable_data[12] },
767         { 136, 5680, bwn_b2062_chantable_data[12] },
768         { 140, 5700, bwn_b2062_chantable_data[12] },
769         { 149, 5745, bwn_b2062_chantable_data[12] },
770         { 153, 5765, bwn_b2062_chantable_data[12] },
771         { 157, 5785, bwn_b2062_chantable_data[12] },
772         { 161, 5805, bwn_b2062_chantable_data[12] },
773         { 165, 5825, bwn_b2062_chantable_data[12] },
774         { 184, 4920, bwn_b2062_chantable_data[13] },
775         { 188, 4940, bwn_b2062_chantable_data[14] },
776         { 192, 4960, bwn_b2062_chantable_data[15] },
777         { 196, 4980, bwn_b2062_chantable_data[16] },
778         { 200, 5000, bwn_b2062_chantable_data[17] },
779         { 204, 5020, bwn_b2062_chantable_data[18] },
780         { 208, 5040, bwn_b2062_chantable_data[19] },
781         { 212, 5060, bwn_b2062_chantable_data[20] },
782         { 216, 5080, bwn_b2062_chantable_data[21] }
783 };
784
785 /* for LP PHY */
786 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
787         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
788         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
789         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
790         { 13, -66, 13 }, { 14, -66, 13 },
791 };
792
793 /* for LP PHY */
794 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
795         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
796         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
797         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
798         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
799         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
800         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
801         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
802         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
803         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
804         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
805         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
806         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
807         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
808 };
809
810 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
811
812 static const uint8_t bwn_tab_sigsq_tbl[] = {
813         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
814         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
816         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
817         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
818         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
819 };
820
821 static const uint8_t bwn_tab_pllfrac_tbl[] = {
822         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
823         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
824 };
825
826 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
827         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
828         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
829         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
830         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
831         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
832         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
837         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839 };
840
841 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
842 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
843 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
844 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
845 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
846 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
847
848 #define VENDOR_LED_ACT(vendor)                          \
849 {                                                       \
850         .vid = PCI_VENDOR_##vendor,                     \
851         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
852 }
853
854 static const struct {
855         uint16_t        vid;
856         uint8_t         led_act[BWN_LED_MAX];
857 } bwn_vendor_led_act[] = {
858         VENDOR_LED_ACT(COMPAQ),
859         VENDOR_LED_ACT(ASUSTEK)
860 };
861
862 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
863         { BWN_VENDOR_LED_ACT_DEFAULT };
864
865 #undef VENDOR_LED_ACT
866
867 static const struct {
868         int             on_dur;
869         int             off_dur;
870 } bwn_led_duration[109] = {
871         [0]     = { 400, 100 },
872         [2]     = { 150, 75 },
873         [4]     = { 90, 45 },
874         [11]    = { 66, 34 },
875         [12]    = { 53, 26 },
876         [18]    = { 42, 21 },
877         [22]    = { 35, 17 },
878         [24]    = { 32, 16 },
879         [36]    = { 21, 10 },
880         [48]    = { 16, 8 },
881         [72]    = { 11, 5 },
882         [96]    = { 9, 4 },
883         [108]   = { 7, 3 }
884 };
885
886 static const uint16_t bwn_wme_shm_offsets[] = {
887         [0] = BWN_WME_BESTEFFORT,
888         [1] = BWN_WME_BACKGROUND,
889         [2] = BWN_WME_VOICE,
890         [3] = BWN_WME_VIDEO,
891 };
892
893 static const struct siba_devid bwn_devs[] = {
894         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
895         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
896         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
897         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
898         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
899         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
900         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
901         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
902         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
903 };
904
905 static int
906 bwn_probe(device_t dev)
907 {
908         int i;
909
910         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
911                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
912                     siba_get_device(dev) == bwn_devs[i].sd_device &&
913                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
914                         return (BUS_PROBE_DEFAULT);
915         }
916
917         return (ENXIO);
918 }
919
920 static int
921 bwn_attach(device_t dev)
922 {
923         struct bwn_mac *mac;
924         struct bwn_softc *sc = device_get_softc(dev);
925         int error, i, msic, reg;
926
927         sc->sc_dev = dev;
928 #ifdef BWN_DEBUG
929         sc->sc_debug = bwn_debug;
930 #endif
931
932         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933                 error = bwn_attach_pre(sc);
934                 if (error != 0)
935                         return (error);
936                 bwn_sprom_bugfixes(dev);
937                 sc->sc_flags |= BWN_FLAG_ATTACHED;
938         }
939
940         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
941                 if (siba_get_pci_device(dev) != 0x4313 &&
942                     siba_get_pci_device(dev) != 0x431a &&
943                     siba_get_pci_device(dev) != 0x4321) {
944                         device_printf(sc->sc_dev,
945                             "skip 802.11 cores\n");
946                         return (ENODEV);
947                 }
948         }
949
950         mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
951             M_NOWAIT | M_ZERO);
952         if (mac == NULL)
953                 return (ENOMEM);
954         mac->mac_sc = sc;
955         mac->mac_status = BWN_MAC_STATUS_UNINIT;
956         if (bwn_bfp != 0)
957                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
958
959         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
960         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
961         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
962
963         error = bwn_attach_core(mac);
964         if (error)
965                 goto fail0;
966         bwn_led_attach(mac);
967
968         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
969             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
970             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
971             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
972             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
973             mac->mac_phy.rf_rev);
974         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
975                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
976                     mac->mac_method.dma.dmatype);
977         else
978                 device_printf(sc->sc_dev, "PIO\n");
979
980         /*
981          * setup PCI resources and interrupt.
982          */
983         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
984                 msic = pci_msi_count(dev);
985                 if (bootverbose)
986                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
987         } else
988                 msic = 0;
989
990         mac->mac_intr_spec = bwn_res_spec_legacy;
991         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
992                 if (pci_alloc_msi(dev, &msic) == 0) {
993                         device_printf(sc->sc_dev,
994                             "Using %d MSI messages\n", msic);
995                         mac->mac_intr_spec = bwn_res_spec_msi;
996                         mac->mac_msi = 1;
997                 }
998         }
999
1000         error = bus_alloc_resources(dev, mac->mac_intr_spec,
1001             mac->mac_res_irq);
1002         if (error) {
1003                 device_printf(sc->sc_dev,
1004                     "couldn't allocate IRQ resources (%d)\n", error);
1005                 goto fail1;
1006         }
1007
1008         if (mac->mac_msi == 0)
1009                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1010                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1011                     &mac->mac_intrhand[0]);
1012         else {
1013                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1014                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1015                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1016                             &mac->mac_intrhand[i]);
1017                         if (error != 0) {
1018                                 device_printf(sc->sc_dev,
1019                                     "couldn't setup interrupt (%d)\n", error);
1020                                 break;
1021                         }
1022                 }
1023         }
1024
1025         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1026
1027         /*
1028          * calls attach-post routine
1029          */
1030         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1031                 bwn_attach_post(sc);
1032
1033         return (0);
1034 fail1:
1035         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1036                 pci_release_msi(dev);
1037 fail0:
1038         free(mac, M_DEVBUF);
1039         return (error);
1040 }
1041
1042 static int
1043 bwn_is_valid_ether_addr(uint8_t *addr)
1044 {
1045         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1046
1047         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1048                 return (FALSE);
1049
1050         return (TRUE);
1051 }
1052
1053 static int
1054 bwn_attach_post(struct bwn_softc *sc)
1055 {
1056         struct ieee80211com *ic;
1057         struct ifnet *ifp = sc->sc_ifp;
1058
1059         ic = ifp->if_l2com;
1060         ic->ic_ifp = ifp;
1061         ic->ic_softc = sc;
1062         ic->ic_name = device_get_nameunit(sc->sc_dev);
1063         /* XXX not right but it's not used anywhere important */
1064         ic->ic_phytype = IEEE80211_T_OFDM;
1065         ic->ic_opmode = IEEE80211_M_STA;
1066         ic->ic_caps =
1067                   IEEE80211_C_STA               /* station mode supported */
1068                 | IEEE80211_C_MONITOR           /* monitor mode */
1069                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1070                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1071                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1072                 | IEEE80211_C_WME               /* WME/WMM supported */
1073                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1074                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1075                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1076                 ;
1077
1078         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1079
1080         /* call MI attach routine. */
1081         ieee80211_ifattach(ic,
1082             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1083             siba_sprom_get_mac_80211a(sc->sc_dev) :
1084             siba_sprom_get_mac_80211bg(sc->sc_dev));
1085
1086         ic->ic_headroom = sizeof(struct bwn_txhdr);
1087
1088         /* override default methods */
1089         ic->ic_raw_xmit = bwn_raw_xmit;
1090         ic->ic_updateslot = bwn_updateslot;
1091         ic->ic_update_promisc = bwn_update_promisc;
1092         ic->ic_wme.wme_update = bwn_wme_update;
1093
1094         ic->ic_scan_start = bwn_scan_start;
1095         ic->ic_scan_end = bwn_scan_end;
1096         ic->ic_set_channel = bwn_set_channel;
1097
1098         ic->ic_vap_create = bwn_vap_create;
1099         ic->ic_vap_delete = bwn_vap_delete;
1100
1101         ieee80211_radiotap_attach(ic,
1102             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1103             BWN_TX_RADIOTAP_PRESENT,
1104             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1105             BWN_RX_RADIOTAP_PRESENT);
1106
1107         bwn_sysctl_node(sc);
1108
1109         if (bootverbose)
1110                 ieee80211_announce(ic);
1111         return (0);
1112 }
1113
1114 static void
1115 bwn_phy_detach(struct bwn_mac *mac)
1116 {
1117
1118         if (mac->mac_phy.detach != NULL)
1119                 mac->mac_phy.detach(mac);
1120 }
1121
1122 static int
1123 bwn_detach(device_t dev)
1124 {
1125         struct bwn_softc *sc = device_get_softc(dev);
1126         struct bwn_mac *mac = sc->sc_curmac;
1127         struct ifnet *ifp = sc->sc_ifp;
1128         struct ieee80211com *ic = ifp->if_l2com;
1129         int i;
1130
1131         sc->sc_flags |= BWN_FLAG_INVALID;
1132
1133         if (device_is_attached(sc->sc_dev)) {
1134                 bwn_stop(sc, 1);
1135                 bwn_dma_free(mac);
1136                 callout_drain(&sc->sc_led_blink_ch);
1137                 callout_drain(&sc->sc_rfswitch_ch);
1138                 callout_drain(&sc->sc_task_ch);
1139                 callout_drain(&sc->sc_watchdog_ch);
1140                 bwn_phy_detach(mac);
1141                 if (ifp != NULL) {
1142                         ieee80211_draintask(ic, &mac->mac_hwreset);
1143                         ieee80211_draintask(ic, &mac->mac_txpower);
1144                         ieee80211_ifdetach(ic);
1145                         if_free(ifp);
1146                 }
1147         }
1148         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1149         taskqueue_free(sc->sc_tq);
1150
1151         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1152                 if (mac->mac_intrhand[i] != NULL) {
1153                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1154                             mac->mac_intrhand[i]);
1155                         mac->mac_intrhand[i] = NULL;
1156                 }
1157         }
1158         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1159         if (mac->mac_msi != 0)
1160                 pci_release_msi(dev);
1161
1162         BWN_LOCK_DESTROY(sc);
1163         return (0);
1164 }
1165
1166 static int
1167 bwn_attach_pre(struct bwn_softc *sc)
1168 {
1169         struct ifnet *ifp;
1170         int error = 0;
1171
1172         BWN_LOCK_INIT(sc);
1173         TAILQ_INIT(&sc->sc_maclist);
1174         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1175         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1176         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1177
1178         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1179                 taskqueue_thread_enqueue, &sc->sc_tq);
1180         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1181                 "%s taskq", device_get_nameunit(sc->sc_dev));
1182
1183         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1184         if (ifp == NULL) {
1185                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1186                 error = ENOSPC;
1187                 goto fail;
1188         }
1189
1190         /* set these up early for if_printf use */
1191         if_initname(ifp, device_get_name(sc->sc_dev),
1192             device_get_unit(sc->sc_dev));
1193
1194         ifp->if_softc = sc;
1195         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1196         ifp->if_init = bwn_init;
1197         ifp->if_ioctl = bwn_ioctl;
1198         ifp->if_start = bwn_start;
1199         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1200         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1201         IFQ_SET_READY(&ifp->if_snd);
1202
1203         return (0);
1204
1205 fail:   BWN_LOCK_DESTROY(sc);
1206         return (error);
1207 }
1208
1209 static void
1210 bwn_sprom_bugfixes(device_t dev)
1211 {
1212 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1213         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1214          (siba_get_pci_device(dev) == _device) &&                       \
1215          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1216          (siba_get_pci_subdevice(dev) == _subdevice))
1217
1218         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1219             siba_get_pci_subdevice(dev) == 0x4e &&
1220             siba_get_pci_revid(dev) > 0x40)
1221                 siba_sprom_set_bf_lo(dev,
1222                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1223         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1224             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1225                 siba_sprom_set_bf_lo(dev,
1226                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1227         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1228                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1229                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1230                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1231                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1232                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1233                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1234                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1235                         siba_sprom_set_bf_lo(dev,
1236                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1237         }
1238 #undef  BWN_ISDEV
1239 }
1240
1241 static int
1242 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1243 {
1244 #define IS_RUNNING(ifp) \
1245         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1246         struct bwn_softc *sc = ifp->if_softc;
1247         struct ieee80211com *ic = ifp->if_l2com;
1248         struct ifreq *ifr = (struct ifreq *)data;
1249         int error = 0, startall;
1250
1251         switch (cmd) {
1252         case SIOCSIFFLAGS:
1253                 startall = 0;
1254                 if (IS_RUNNING(ifp)) {
1255                         bwn_update_promisc(ifp);
1256                 } else if (ifp->if_flags & IFF_UP) {
1257                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1258                                 bwn_init(sc);
1259                                 startall = 1;
1260                         }
1261                 } else
1262                         bwn_stop(sc, 1);
1263                 if (startall)
1264                         ieee80211_start_all(ic);
1265                 break;
1266         case SIOCGIFMEDIA:
1267                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1268                 break;
1269         case SIOCGIFADDR:
1270                 error = ether_ioctl(ifp, cmd, data);
1271                 break;
1272         default:
1273                 error = EINVAL;
1274                 break;
1275         }
1276         return (error);
1277 }
1278
1279 static void
1280 bwn_start(struct ifnet *ifp)
1281 {
1282         struct bwn_softc *sc = ifp->if_softc;
1283
1284         BWN_LOCK(sc);
1285         bwn_start_locked(ifp);
1286         BWN_UNLOCK(sc);
1287 }
1288
1289 static void
1290 bwn_start_locked(struct ifnet *ifp)
1291 {
1292         struct bwn_softc *sc = ifp->if_softc;
1293         struct bwn_mac *mac = sc->sc_curmac;
1294         struct ieee80211_frame *wh;
1295         struct ieee80211_node *ni;
1296         struct ieee80211_key *k;
1297         struct mbuf *m;
1298
1299         BWN_ASSERT_LOCKED(sc);
1300
1301         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1302             mac->mac_status < BWN_MAC_STATUS_STARTED)
1303                 return;
1304
1305         for (;;) {
1306                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1307                 if (m == NULL)
1308                         break;
1309
1310                 if (bwn_tx_isfull(sc, m))
1311                         break;
1312                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1313                 if (ni == NULL) {
1314                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1315                         m_freem(m);
1316                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1317                         continue;
1318                 }
1319                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1320                 wh = mtod(m, struct ieee80211_frame *);
1321                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1322                         k = ieee80211_crypto_encap(ni, m);
1323                         if (k == NULL) {
1324                                 ieee80211_free_node(ni);
1325                                 m_freem(m);
1326                                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1327                                 continue;
1328                         }
1329                 }
1330                 wh = NULL;      /* Catch any invalid use */
1331
1332                 if (bwn_tx_start(sc, ni, m) != 0) {
1333                         if (ni != NULL)
1334                                 ieee80211_free_node(ni);
1335                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1336                         continue;
1337                 }
1338
1339                 sc->sc_watchdog_timer = 5;
1340         }
1341 }
1342
1343 static int
1344 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1345 {
1346         struct bwn_dma_ring *dr;
1347         struct bwn_mac *mac = sc->sc_curmac;
1348         struct bwn_pio_txqueue *tq;
1349         struct ifnet *ifp = sc->sc_ifp;
1350         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1351
1352         BWN_ASSERT_LOCKED(sc);
1353
1354         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1355                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1356                 if (dr->dr_stop == 1 ||
1357                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1358                         dr->dr_stop = 1;
1359                         goto full;
1360                 }
1361         } else {
1362                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1363                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1364                     pktlen > (tq->tq_size - tq->tq_used)) {
1365                         tq->tq_stop = 1;
1366                         goto full;
1367                 }
1368         }
1369         return (0);
1370 full:
1371         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1372         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1373         return (1);
1374 }
1375
1376 static int
1377 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1378 {
1379         struct bwn_mac *mac = sc->sc_curmac;
1380         int error;
1381
1382         BWN_ASSERT_LOCKED(sc);
1383
1384         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1385                 m_freem(m);
1386                 return (ENXIO);
1387         }
1388
1389         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1390             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1391         if (error) {
1392                 m_freem(m);
1393                 return (error);
1394         }
1395         return (0);
1396 }
1397
1398 static int
1399 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1400 {
1401         struct bwn_pio_txpkt *tp;
1402         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1403         struct bwn_softc *sc = mac->mac_sc;
1404         struct bwn_txhdr txhdr;
1405         struct mbuf *m_new;
1406         uint32_t ctl32;
1407         int error;
1408         uint16_t ctl16;
1409
1410         BWN_ASSERT_LOCKED(sc);
1411
1412         /* XXX TODO send packets after DTIM */
1413
1414         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1415         tp = TAILQ_FIRST(&tq->tq_pktlist);
1416         tp->tp_ni = ni;
1417         tp->tp_m = m;
1418
1419         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1420         if (error) {
1421                 device_printf(sc->sc_dev, "tx fail\n");
1422                 return (error);
1423         }
1424
1425         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1426         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1427         tq->tq_free--;
1428
1429         if (siba_get_revid(sc->sc_dev) >= 8) {
1430                 /*
1431                  * XXX please removes m_defrag(9)
1432                  */
1433                 m_new = m_defrag(m, M_NOWAIT);
1434                 if (m_new == NULL) {
1435                         device_printf(sc->sc_dev,
1436                             "%s: can't defrag TX buffer\n",
1437                             __func__);
1438                         return (ENOBUFS);
1439                 }
1440                 if (m_new->m_next != NULL)
1441                         device_printf(sc->sc_dev,
1442                             "TODO: fragmented packets for PIO\n");
1443                 tp->tp_m = m_new;
1444
1445                 /* send HEADER */
1446                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1447                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1448                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1449                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1450                 /* send BODY */
1451                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1452                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1453                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1454                     ctl32 | BWN_PIO8_TXCTL_EOF);
1455         } else {
1456                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1457                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1458                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1459                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1460                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1461                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1462                     ctl16 | BWN_PIO_TXCTL_EOF);
1463         }
1464
1465         return (0);
1466 }
1467
1468 static struct bwn_pio_txqueue *
1469 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1470 {
1471
1472         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1473                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1474
1475         switch (prio) {
1476         case 0:
1477                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1478         case 1:
1479                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1480         case 2:
1481                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1482         case 3:
1483                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1484         }
1485         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1486         return (NULL);
1487 }
1488
1489 static int
1490 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1491 {
1492 #define BWN_GET_TXHDRCACHE(slot)                                        \
1493         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1494         struct bwn_dma *dma = &mac->mac_method.dma;
1495         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1496         struct bwn_dmadesc_generic *desc;
1497         struct bwn_dmadesc_meta *mt;
1498         struct bwn_softc *sc = mac->mac_sc;
1499         struct ifnet *ifp = sc->sc_ifp;
1500         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1501         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1502
1503         BWN_ASSERT_LOCKED(sc);
1504         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1505
1506         /* XXX send after DTIM */
1507
1508         slot = bwn_dma_getslot(dr);
1509         dr->getdesc(dr, slot, &desc, &mt);
1510         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1511             ("%s:%d: fail", __func__, __LINE__));
1512
1513         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1514             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1515             BWN_DMA_COOKIE(dr, slot));
1516         if (error)
1517                 goto fail;
1518         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1519             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1520             &mt->mt_paddr, BUS_DMA_NOWAIT);
1521         if (error) {
1522                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1523                     __func__, error);
1524                 goto fail;
1525         }
1526         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1527             BUS_DMASYNC_PREWRITE);
1528         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1529         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1530             BUS_DMASYNC_PREWRITE);
1531
1532         slot = bwn_dma_getslot(dr);
1533         dr->getdesc(dr, slot, &desc, &mt);
1534         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1535             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1536         mt->mt_m = m;
1537         mt->mt_ni = ni;
1538
1539         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1540             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1541         if (error && error != EFBIG) {
1542                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1543                     __func__, error);
1544                 goto fail;
1545         }
1546         if (error) {    /* error == EFBIG */
1547                 struct mbuf *m_new;
1548
1549                 m_new = m_defrag(m, M_NOWAIT);
1550                 if (m_new == NULL) {
1551                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1552                             __func__);
1553                         error = ENOBUFS;
1554                         goto fail;
1555                 } else {
1556                         m = m_new;
1557                 }
1558
1559                 mt->mt_m = m;
1560                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1561                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1562                 if (error) {
1563                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1564                             __func__, error);
1565                         goto fail;
1566                 }
1567         }
1568         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1569         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1570         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1571             BUS_DMASYNC_PREWRITE);
1572
1573         /* XXX send after DTIM */
1574
1575         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1576         return (0);
1577 fail:
1578         dr->dr_curslot = backup[0];
1579         dr->dr_usedslot = backup[1];
1580         return (error);
1581 #undef BWN_GET_TXHDRCACHE
1582 }
1583
1584 static void
1585 bwn_watchdog(void *arg)
1586 {
1587         struct bwn_softc *sc = arg;
1588         struct ifnet *ifp = sc->sc_ifp;
1589
1590         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1591                 if_printf(ifp, "device timeout\n");
1592                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1593         }
1594         callout_schedule(&sc->sc_watchdog_ch, hz);
1595 }
1596
1597 static int
1598 bwn_attach_core(struct bwn_mac *mac)
1599 {
1600         struct bwn_softc *sc = mac->mac_sc;
1601         int error, have_bg = 0, have_a = 0;
1602         uint32_t high;
1603
1604         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1605             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1606
1607         siba_powerup(sc->sc_dev, 0);
1608
1609         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1610         bwn_reset_core(mac,
1611             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1612         error = bwn_phy_getinfo(mac, high);
1613         if (error)
1614                 goto fail;
1615
1616         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1617         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1618         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1619             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1620             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1621                 have_a = have_bg = 0;
1622                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1623                         have_a = 1;
1624                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1625                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1626                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1627                         have_bg = 1;
1628                 else
1629                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1630                             mac->mac_phy.type));
1631         }
1632         /* XXX turns off PHY A because it's not supported */
1633         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1634             mac->mac_phy.type != BWN_PHYTYPE_N) {
1635                 have_a = 0;
1636                 have_bg = 1;
1637         }
1638
1639         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1640                 mac->mac_phy.attach = bwn_phy_g_attach;
1641                 mac->mac_phy.detach = bwn_phy_g_detach;
1642                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1643                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1644                 mac->mac_phy.init = bwn_phy_g_init;
1645                 mac->mac_phy.exit = bwn_phy_g_exit;
1646                 mac->mac_phy.phy_read = bwn_phy_g_read;
1647                 mac->mac_phy.phy_write = bwn_phy_g_write;
1648                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1649                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1650                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1651                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1652                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1653                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1654                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1655                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1656                 mac->mac_phy.set_im = bwn_phy_g_im;
1657                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1658                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1659                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1660                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1661         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1662                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1663                 mac->mac_phy.init = bwn_phy_lp_init;
1664                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1665                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1666                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1667                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1668                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1669                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1670                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1671                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1672                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1673                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1674                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1675         } else {
1676                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1677                     mac->mac_phy.type);
1678                 error = ENXIO;
1679                 goto fail;
1680         }
1681
1682         mac->mac_phy.gmode = have_bg;
1683         if (mac->mac_phy.attach != NULL) {
1684                 error = mac->mac_phy.attach(mac);
1685                 if (error) {
1686                         device_printf(sc->sc_dev, "failed\n");
1687                         goto fail;
1688                 }
1689         }
1690
1691         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1692
1693         error = bwn_chiptest(mac);
1694         if (error)
1695                 goto fail;
1696         error = bwn_setup_channels(mac, have_bg, have_a);
1697         if (error) {
1698                 device_printf(sc->sc_dev, "failed to setup channels\n");
1699                 goto fail;
1700         }
1701
1702         if (sc->sc_curmac == NULL)
1703                 sc->sc_curmac = mac;
1704
1705         error = bwn_dma_attach(mac);
1706         if (error != 0) {
1707                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1708                 goto fail;
1709         }
1710
1711         mac->mac_phy.switch_analog(mac, 0);
1712
1713         siba_dev_down(sc->sc_dev, 0);
1714 fail:
1715         siba_powerdown(sc->sc_dev);
1716         return (error);
1717 }
1718
1719 static void
1720 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1721 {
1722         struct bwn_softc *sc = mac->mac_sc;
1723         uint32_t low, ctl;
1724
1725         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1726
1727         siba_dev_up(sc->sc_dev, flags);
1728         DELAY(2000);
1729
1730         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1731             ~BWN_TGSLOW_PHYRESET;
1732         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1733         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1734         DELAY(1000);
1735         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1736         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1737         DELAY(1000);
1738
1739         if (mac->mac_phy.switch_analog != NULL)
1740                 mac->mac_phy.switch_analog(mac, 1);
1741
1742         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1743         if (flags & BWN_TGSLOW_SUPPORT_G)
1744                 ctl |= BWN_MACCTL_GMODE;
1745         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1746 }
1747
1748 static int
1749 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1750 {
1751         struct bwn_phy *phy = &mac->mac_phy;
1752         struct bwn_softc *sc = mac->mac_sc;
1753         uint32_t tmp;
1754
1755         /* PHY */
1756         tmp = BWN_READ_2(mac, BWN_PHYVER);
1757         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1758         phy->rf_on = 1;
1759         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1760         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1761         phy->rev = (tmp & BWN_PHYVER_VERSION);
1762         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1763             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1764                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1765             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1766             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1767             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1768                 goto unsupphy;
1769
1770         /* RADIO */
1771         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1772                 if (siba_get_chiprev(sc->sc_dev) == 0)
1773                         tmp = 0x3205017f;
1774                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1775                         tmp = 0x4205017f;
1776                 else
1777                         tmp = 0x5205017f;
1778         } else {
1779                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1780                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1781                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1782                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1783         }
1784         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1785         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1786         phy->rf_manuf = (tmp & 0x00000fff);
1787         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1788                 goto unsupradio;
1789         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1790              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1791             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1792             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1793             (phy->type == BWN_PHYTYPE_N &&
1794              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1795             (phy->type == BWN_PHYTYPE_LP &&
1796              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1797                 goto unsupradio;
1798
1799         return (0);
1800 unsupphy:
1801         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1802             "analog %#x)\n",
1803             phy->type, phy->rev, phy->analog);
1804         return (ENXIO);
1805 unsupradio:
1806         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1807             "rev %#x)\n",
1808             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1809         return (ENXIO);
1810 }
1811
1812 static int
1813 bwn_chiptest(struct bwn_mac *mac)
1814 {
1815 #define TESTVAL0        0x55aaaa55
1816 #define TESTVAL1        0xaa5555aa
1817         struct bwn_softc *sc = mac->mac_sc;
1818         uint32_t v, backup;
1819
1820         BWN_LOCK(sc);
1821
1822         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1823
1824         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1825         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1826                 goto error;
1827         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1828         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1829                 goto error;
1830
1831         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1832
1833         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1834             (siba_get_revid(sc->sc_dev) <= 10)) {
1835                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1836                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1837                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1838                         goto error;
1839                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1840                         goto error;
1841         }
1842         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1843
1844         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1845         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1846                 goto error;
1847
1848         BWN_UNLOCK(sc);
1849         return (0);
1850 error:
1851         BWN_UNLOCK(sc);
1852         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1853         return (ENODEV);
1854 }
1855
1856 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1857 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1858
1859 static int
1860 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1861 {
1862         struct bwn_softc *sc = mac->mac_sc;
1863         struct ifnet *ifp = sc->sc_ifp;
1864         struct ieee80211com *ic = ifp->if_l2com;
1865
1866         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1867         ic->ic_nchans = 0;
1868
1869         if (have_bg)
1870                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1871                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1872         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1873                 if (have_a)
1874                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1875                             &ic->ic_nchans, &bwn_chantable_n,
1876                             IEEE80211_CHAN_HTA);
1877         } else {
1878                 if (have_a)
1879                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1880                             &ic->ic_nchans, &bwn_chantable_a,
1881                             IEEE80211_CHAN_A);
1882         }
1883
1884         mac->mac_phy.supports_2ghz = have_bg;
1885         mac->mac_phy.supports_5ghz = have_a;
1886
1887         return (ic->ic_nchans == 0 ? ENXIO : 0);
1888 }
1889
1890 static uint32_t
1891 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1892 {
1893         uint32_t ret;
1894
1895         BWN_ASSERT_LOCKED(mac->mac_sc);
1896
1897         if (way == BWN_SHARED) {
1898                 KASSERT((offset & 0x0001) == 0,
1899                     ("%s:%d warn", __func__, __LINE__));
1900                 if (offset & 0x0003) {
1901                         bwn_shm_ctlword(mac, way, offset >> 2);
1902                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1903                         ret <<= 16;
1904                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1905                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1906                         goto out;
1907                 }
1908                 offset >>= 2;
1909         }
1910         bwn_shm_ctlword(mac, way, offset);
1911         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1912 out:
1913         return (ret);
1914 }
1915
1916 static uint16_t
1917 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1918 {
1919         uint16_t ret;
1920
1921         BWN_ASSERT_LOCKED(mac->mac_sc);
1922
1923         if (way == BWN_SHARED) {
1924                 KASSERT((offset & 0x0001) == 0,
1925                     ("%s:%d warn", __func__, __LINE__));
1926                 if (offset & 0x0003) {
1927                         bwn_shm_ctlword(mac, way, offset >> 2);
1928                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1929                         goto out;
1930                 }
1931                 offset >>= 2;
1932         }
1933         bwn_shm_ctlword(mac, way, offset);
1934         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1935 out:
1936
1937         return (ret);
1938 }
1939
1940 static void
1941 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1942     uint16_t offset)
1943 {
1944         uint32_t control;
1945
1946         control = way;
1947         control <<= 16;
1948         control |= offset;
1949         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1950 }
1951
1952 static void
1953 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1954     uint32_t value)
1955 {
1956         BWN_ASSERT_LOCKED(mac->mac_sc);
1957
1958         if (way == BWN_SHARED) {
1959                 KASSERT((offset & 0x0001) == 0,
1960                     ("%s:%d warn", __func__, __LINE__));
1961                 if (offset & 0x0003) {
1962                         bwn_shm_ctlword(mac, way, offset >> 2);
1963                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1964                                     (value >> 16) & 0xffff);
1965                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1966                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1967                         return;
1968                 }
1969                 offset >>= 2;
1970         }
1971         bwn_shm_ctlword(mac, way, offset);
1972         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1973 }
1974
1975 static void
1976 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1977     uint16_t value)
1978 {
1979         BWN_ASSERT_LOCKED(mac->mac_sc);
1980
1981         if (way == BWN_SHARED) {
1982                 KASSERT((offset & 0x0001) == 0,
1983                     ("%s:%d warn", __func__, __LINE__));
1984                 if (offset & 0x0003) {
1985                         bwn_shm_ctlword(mac, way, offset >> 2);
1986                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1987                         return;
1988                 }
1989                 offset >>= 2;
1990         }
1991         bwn_shm_ctlword(mac, way, offset);
1992         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1993 }
1994
1995 static void
1996 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1997     int txpow)
1998 {
1999
2000         c->ic_freq = freq;
2001         c->ic_flags = flags;
2002         c->ic_ieee = ieee;
2003         c->ic_minpower = 0;
2004         c->ic_maxpower = 2 * txpow;
2005         c->ic_maxregpower = txpow;
2006 }
2007
2008 static void
2009 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2010     const struct bwn_channelinfo *ci, int flags)
2011 {
2012         struct ieee80211_channel *c;
2013         int i;
2014
2015         c = &chans[*nchans];
2016
2017         for (i = 0; i < ci->nchannels; i++) {
2018                 const struct bwn_channel *hc;
2019
2020                 hc = &ci->channels[i];
2021                 if (*nchans >= maxchans)
2022                         break;
2023                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2024                 c++, (*nchans)++;
2025                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2026                         /* g channel have a separate b-only entry */
2027                         if (*nchans >= maxchans)
2028                                 break;
2029                         c[0] = c[-1];
2030                         c[-1].ic_flags = IEEE80211_CHAN_B;
2031                         c++, (*nchans)++;
2032                 }
2033                 if (flags == IEEE80211_CHAN_HTG) {
2034                         /* HT g channel have a separate g-only entry */
2035                         if (*nchans >= maxchans)
2036                                 break;
2037                         c[-1].ic_flags = IEEE80211_CHAN_G;
2038                         c[0] = c[-1];
2039                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2040                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2041                         c++, (*nchans)++;
2042                 }
2043                 if (flags == IEEE80211_CHAN_HTA) {
2044                         /* HT a channel have a separate a-only entry */
2045                         if (*nchans >= maxchans)
2046                                 break;
2047                         c[-1].ic_flags = IEEE80211_CHAN_A;
2048                         c[0] = c[-1];
2049                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2050                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2051                         c++, (*nchans)++;
2052                 }
2053         }
2054 }
2055
2056 static int
2057 bwn_phy_g_attach(struct bwn_mac *mac)
2058 {
2059         struct bwn_softc *sc = mac->mac_sc;
2060         struct bwn_phy *phy = &mac->mac_phy;
2061         struct bwn_phy_g *pg = &phy->phy_g;
2062         unsigned int i;
2063         int16_t pab0, pab1, pab2;
2064         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2065         int8_t bg;
2066
2067         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2068         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2069         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2070         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2071
2072         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2073                 device_printf(sc->sc_dev, "not supported anymore\n");
2074
2075         pg->pg_flags = 0;
2076         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2077             pab2 == -1) {
2078                 pg->pg_idletssi = 52;
2079                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2080                 return (0);
2081         }
2082
2083         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2084         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2085         if (pg->pg_tssi2dbm == NULL) {
2086                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2087                 return (ENOMEM);
2088         }
2089         for (i = 0; i < 64; i++) {
2090                 int32_t m1, m2, f, q, delta;
2091                 int8_t j = 0;
2092
2093                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2094                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2095                 f = 256;
2096
2097                 do {
2098                         if (j > 15) {
2099                                 device_printf(sc->sc_dev,
2100                                     "failed to generate tssi2dBm\n");
2101                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2102                                 return (ENOMEM);
2103                         }
2104                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2105                             f, 2048);
2106                         delta = abs(q - f);
2107                         f = q;
2108                         j++;
2109                 } while (delta >= 2);
2110
2111                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2112                     128);
2113         }
2114
2115         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2116         return (0);
2117 }
2118
2119 static void
2120 bwn_phy_g_detach(struct bwn_mac *mac)
2121 {
2122         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2123
2124         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2125                 free(pg->pg_tssi2dbm, M_DEVBUF);
2126                 pg->pg_tssi2dbm = NULL;
2127         }
2128         pg->pg_flags = 0;
2129 }
2130
2131 static void
2132 bwn_phy_g_init_pre(struct bwn_mac *mac)
2133 {
2134         struct bwn_phy *phy = &mac->mac_phy;
2135         struct bwn_phy_g *pg = &phy->phy_g;
2136         void *tssi2dbm;
2137         int idletssi;
2138         unsigned int i;
2139
2140         tssi2dbm = pg->pg_tssi2dbm;
2141         idletssi = pg->pg_idletssi;
2142
2143         memset(pg, 0, sizeof(*pg));
2144
2145         pg->pg_tssi2dbm = tssi2dbm;
2146         pg->pg_idletssi = idletssi;
2147
2148         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2149
2150         for (i = 0; i < N(pg->pg_nrssi); i++)
2151                 pg->pg_nrssi[i] = -1000;
2152         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2153                 pg->pg_nrssi_lt[i] = i;
2154         pg->pg_lofcal = 0xffff;
2155         pg->pg_initval = 0xffff;
2156         pg->pg_immode = BWN_IMMODE_NONE;
2157         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2158         pg->pg_avgtssi = 0xff;
2159
2160         pg->pg_loctl.tx_bias = 0xff;
2161         TAILQ_INIT(&pg->pg_loctl.calib_list);
2162 }
2163
2164 static int
2165 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2166 {
2167         struct bwn_phy *phy = &mac->mac_phy;
2168         struct bwn_phy_g *pg = &phy->phy_g;
2169         struct bwn_softc *sc = mac->mac_sc;
2170         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2171         static const struct bwn_rfatt rfatt0[] = {
2172                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2173                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2174                 { 3, 1 }, { 4, 1 }
2175         };
2176         static const struct bwn_rfatt rfatt1[] = {
2177                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2178                 { 14, 1 }
2179         };
2180         static const struct bwn_rfatt rfatt2[] = {
2181                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2182                 { 9, 1 }
2183         };
2184         static const struct bwn_bbatt bbatt_0[] = {
2185                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2186         };
2187
2188         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2189
2190         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2191                 pg->pg_bbatt.att = 0;
2192         else
2193                 pg->pg_bbatt.att = 2;
2194
2195         /* prepare Radio Attenuation */
2196         pg->pg_rfatt.padmix = 0;
2197
2198         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2199             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2200                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2201                         pg->pg_rfatt.att = 2;
2202                         goto done;
2203                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2204                         pg->pg_rfatt.att = 3;
2205                         goto done;
2206                 }
2207         }
2208
2209         if (phy->type == BWN_PHYTYPE_A) {
2210                 pg->pg_rfatt.att = 0x60;
2211                 goto done;
2212         }
2213
2214         switch (phy->rf_ver) {
2215         case 0x2050:
2216                 switch (phy->rf_rev) {
2217                 case 0:
2218                         pg->pg_rfatt.att = 5;
2219                         goto done;
2220                 case 1:
2221                         if (phy->type == BWN_PHYTYPE_G) {
2222                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2223                                     SIBA_BOARDVENDOR_BCM &&
2224                                     siba_get_pci_subdevice(sc->sc_dev) ==
2225                                     SIBA_BOARD_BCM4309G &&
2226                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2227                                         pg->pg_rfatt.att = 3;
2228                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2229                                     SIBA_BOARDVENDOR_BCM &&
2230                                     siba_get_pci_subdevice(sc->sc_dev) ==
2231                                     SIBA_BOARD_BU4306)
2232                                         pg->pg_rfatt.att = 3;
2233                                 else
2234                                         pg->pg_rfatt.att = 1;
2235                         } else {
2236                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2237                                     SIBA_BOARDVENDOR_BCM &&
2238                                     siba_get_pci_subdevice(sc->sc_dev) ==
2239                                     SIBA_BOARD_BCM4309G &&
2240                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2241                                         pg->pg_rfatt.att = 7;
2242                                 else
2243                                         pg->pg_rfatt.att = 6;
2244                         }
2245                         goto done;
2246                 case 2:
2247                         if (phy->type == BWN_PHYTYPE_G) {
2248                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2249                                     SIBA_BOARDVENDOR_BCM &&
2250                                     siba_get_pci_subdevice(sc->sc_dev) ==
2251                                     SIBA_BOARD_BCM4309G &&
2252                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2253                                         pg->pg_rfatt.att = 3;
2254                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2255                                     SIBA_BOARDVENDOR_BCM &&
2256                                     siba_get_pci_subdevice(sc->sc_dev) ==
2257                                     SIBA_BOARD_BU4306)
2258                                         pg->pg_rfatt.att = 5;
2259                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2260                                         pg->pg_rfatt.att = 4;
2261                                 else
2262                                         pg->pg_rfatt.att = 3;
2263                         } else
2264                                 pg->pg_rfatt.att = 6;
2265                         goto done;
2266                 case 3:
2267                         pg->pg_rfatt.att = 5;
2268                         goto done;
2269                 case 4:
2270                 case 5:
2271                         pg->pg_rfatt.att = 1;
2272                         goto done;
2273                 case 6:
2274                 case 7:
2275                         pg->pg_rfatt.att = 5;
2276                         goto done;
2277                 case 8:
2278                         pg->pg_rfatt.att = 0xa;
2279                         pg->pg_rfatt.padmix = 1;
2280                         goto done;
2281                 case 9:
2282                 default:
2283                         pg->pg_rfatt.att = 5;
2284                         goto done;
2285                 }
2286                 break;
2287         case 0x2053:
2288                 switch (phy->rf_rev) {
2289                 case 1:
2290                         pg->pg_rfatt.att = 6;
2291                         goto done;
2292                 }
2293                 break;
2294         }
2295         pg->pg_rfatt.att = 5;
2296 done:
2297         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2298
2299         if (!bwn_has_hwpctl(mac)) {
2300                 lo->rfatt.array = rfatt0;
2301                 lo->rfatt.len = N(rfatt0);
2302                 lo->rfatt.min = 0;
2303                 lo->rfatt.max = 9;
2304                 goto genbbatt;
2305         }
2306         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2307                 lo->rfatt.array = rfatt1;
2308                 lo->rfatt.len = N(rfatt1);
2309                 lo->rfatt.min = 0;
2310                 lo->rfatt.max = 14;
2311                 goto genbbatt;
2312         }
2313         lo->rfatt.array = rfatt2;
2314         lo->rfatt.len = N(rfatt2);
2315         lo->rfatt.min = 0;
2316         lo->rfatt.max = 9;
2317 genbbatt:
2318         lo->bbatt.array = bbatt_0;
2319         lo->bbatt.len = N(bbatt_0);
2320         lo->bbatt.min = 0;
2321         lo->bbatt.max = 8;
2322
2323         BWN_READ_4(mac, BWN_MACCTL);
2324         if (phy->rev == 1) {
2325                 phy->gmode = 0;
2326                 bwn_reset_core(mac, 0);
2327                 bwn_phy_g_init_sub(mac);
2328                 phy->gmode = 1;
2329                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2330         }
2331         return (0);
2332 }
2333
2334 static uint16_t
2335 bwn_phy_g_txctl(struct bwn_mac *mac)
2336 {
2337         struct bwn_phy *phy = &mac->mac_phy;
2338
2339         if (phy->rf_ver != 0x2050)
2340                 return (0);
2341         if (phy->rf_rev == 1)
2342                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2343         if (phy->rf_rev < 6)
2344                 return (BWN_TXCTL_PA2DB);
2345         if (phy->rf_rev == 8)
2346                 return (BWN_TXCTL_TXMIX);
2347         return (0);
2348 }
2349
2350 static int
2351 bwn_phy_g_init(struct bwn_mac *mac)
2352 {
2353
2354         bwn_phy_g_init_sub(mac);
2355         return (0);
2356 }
2357
2358 static void
2359 bwn_phy_g_exit(struct bwn_mac *mac)
2360 {
2361         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2362         struct bwn_lo_calib *cal, *tmp;
2363
2364         if (lo == NULL)
2365                 return;
2366         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2367                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2368                 free(cal, M_DEVBUF);
2369         }
2370 }
2371
2372 static uint16_t
2373 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2374 {
2375
2376         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2377         return (BWN_READ_2(mac, BWN_PHYDATA));
2378 }
2379
2380 static void
2381 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2382 {
2383
2384         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2385         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2386 }
2387
2388 static uint16_t
2389 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2390 {
2391
2392         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2393         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2394         return (BWN_READ_2(mac, BWN_RFDATALO));
2395 }
2396
2397 static void
2398 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2399 {
2400
2401         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2402         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2403         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2404 }
2405
2406 static int
2407 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2408 {
2409
2410         return (mac->mac_phy.rev >= 6);
2411 }
2412
2413 static void
2414 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2415 {
2416         struct bwn_phy *phy = &mac->mac_phy;
2417         struct bwn_phy_g *pg = &phy->phy_g;
2418         unsigned int channel;
2419         uint16_t rfover, rfoverval;
2420
2421         if (on) {
2422                 if (phy->rf_on)
2423                         return;
2424
2425                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2426                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2427                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2428                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2429                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2430                             pg->pg_radioctx_over);
2431                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2432                             pg->pg_radioctx_overval);
2433                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2434                 }
2435                 channel = phy->chan;
2436                 bwn_phy_g_switch_chan(mac, 6, 1);
2437                 bwn_phy_g_switch_chan(mac, channel, 0);
2438                 return;
2439         }
2440
2441         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2442         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2443         pg->pg_radioctx_over = rfover;
2444         pg->pg_radioctx_overval = rfoverval;
2445         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2446         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2447         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2448 }
2449
2450 static int
2451 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2452 {
2453
2454         if ((newchan < 1) || (newchan > 14))
2455                 return (EINVAL);
2456         bwn_phy_g_switch_chan(mac, newchan, 0);
2457
2458         return (0);
2459 }
2460
2461 static uint32_t
2462 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2463 {
2464
2465         return (1);
2466 }
2467
2468 static void
2469 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2470 {
2471         struct bwn_phy *phy = &mac->mac_phy;
2472         uint64_t hf;
2473         int autodiv = 0;
2474         uint16_t tmp;
2475
2476         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2477                 autodiv = 1;
2478
2479         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2480         bwn_hf_write(mac, hf);
2481
2482         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2483             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2484             ((autodiv ? BWN_ANTAUTO1 : antenna)
2485                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2486
2487         if (autodiv) {
2488                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2489                 if (antenna == BWN_ANTAUTO1)
2490                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2491                 else
2492                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2493                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2494         }
2495         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2496         if (autodiv)
2497                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2498         else
2499                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2500         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2501         if (phy->rev >= 2) {
2502                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2503                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2504                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2505                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2506                     0x15);
2507                 if (phy->rev == 2)
2508                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2509                 else
2510                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2511                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2512                             8);
2513         }
2514         if (phy->rev >= 6)
2515                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2516
2517         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2518         bwn_hf_write(mac, hf);
2519 }
2520
2521 static int
2522 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2523 {
2524         struct bwn_phy *phy = &mac->mac_phy;
2525         struct bwn_phy_g *pg = &phy->phy_g;
2526
2527         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2528         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2529
2530         if (phy->rev == 0 || !phy->gmode)
2531                 return (ENODEV);
2532
2533         pg->pg_aci_wlan_automatic = 0;
2534         return (0);
2535 }
2536
2537 static int
2538 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2539 {
2540         struct bwn_phy *phy = &mac->mac_phy;
2541         struct bwn_phy_g *pg = &phy->phy_g;
2542         struct bwn_softc *sc = mac->mac_sc;
2543         unsigned int tssi;
2544         int cck, ofdm;
2545         int power;
2546         int rfatt, bbatt;
2547         unsigned int max;
2548
2549         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2550
2551         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2552         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2553         if (cck < 0 && ofdm < 0) {
2554                 if (ignore_tssi == 0)
2555                         return (BWN_TXPWR_RES_DONE);
2556                 cck = 0;
2557                 ofdm = 0;
2558         }
2559         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2560         if (pg->pg_avgtssi != 0xff)
2561                 tssi = (tssi + pg->pg_avgtssi) / 2;
2562         pg->pg_avgtssi = tssi;
2563         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2564
2565         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2566         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2567                 max -= 3;
2568         if (max >= 120) {
2569                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2570                 max = 80;
2571                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2572         }
2573
2574         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2575             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2576              tssi, 0x00), 0x3f)]);
2577         if (power == 0)
2578                 return (BWN_TXPWR_RES_DONE);
2579
2580         rfatt = -((power + 7) / 8);
2581         bbatt = (-(power / 2)) - (4 * rfatt);
2582         if ((rfatt == 0) && (bbatt == 0))
2583                 return (BWN_TXPWR_RES_DONE);
2584         pg->pg_bbatt_delta = bbatt;
2585         pg->pg_rfatt_delta = rfatt;
2586         return (BWN_TXPWR_RES_NEED_ADJUST);
2587 }
2588
2589 static void
2590 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2591 {
2592         struct bwn_phy *phy = &mac->mac_phy;
2593         struct bwn_phy_g *pg = &phy->phy_g;
2594         struct bwn_softc *sc = mac->mac_sc;
2595         int rfatt, bbatt;
2596         uint8_t txctl;
2597
2598         bwn_mac_suspend(mac);
2599
2600         BWN_ASSERT_LOCKED(sc);
2601
2602         bbatt = pg->pg_bbatt.att;
2603         bbatt += pg->pg_bbatt_delta;
2604         rfatt = pg->pg_rfatt.att;
2605         rfatt += pg->pg_rfatt_delta;
2606
2607         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2608         txctl = pg->pg_txctl;
2609         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2610                 if (rfatt <= 1) {
2611                         if (txctl == 0) {
2612                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2613                                 rfatt += 2;
2614                                 bbatt += 2;
2615                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2616                             BWN_BFL_PACTRL) {
2617                                 bbatt += 4 * (rfatt - 2);
2618                                 rfatt = 2;
2619                         }
2620                 } else if (rfatt > 4 && txctl) {
2621                         txctl = 0;
2622                         if (bbatt < 3) {
2623                                 rfatt -= 3;
2624                                 bbatt += 2;
2625                         } else {
2626                                 rfatt -= 2;
2627                                 bbatt -= 2;
2628                         }
2629                 }
2630         }
2631         pg->pg_txctl = txctl;
2632         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2633         pg->pg_rfatt.att = rfatt;
2634         pg->pg_bbatt.att = bbatt;
2635
2636         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2637
2638         bwn_phy_lock(mac);
2639         bwn_rf_lock(mac);
2640         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2641             pg->pg_txctl);
2642         bwn_rf_unlock(mac);
2643         bwn_phy_unlock(mac);
2644
2645         bwn_mac_enable(mac);
2646 }
2647
2648 static void
2649 bwn_phy_g_task_15s(struct bwn_mac *mac)
2650 {
2651         struct bwn_phy *phy = &mac->mac_phy;
2652         struct bwn_phy_g *pg = &phy->phy_g;
2653         struct bwn_softc *sc = mac->mac_sc;
2654         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2655         unsigned long expire, now;
2656         struct bwn_lo_calib *cal, *tmp;
2657         uint8_t expired = 0;
2658
2659         bwn_mac_suspend(mac);
2660
2661         if (lo == NULL)
2662                 goto fail;
2663
2664         BWN_GETTIME(now);
2665         if (bwn_has_hwpctl(mac)) {
2666                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2667                 if (time_before(lo->pwr_vec_read_time, expire)) {
2668                         bwn_lo_get_powervector(mac);
2669                         bwn_phy_g_dc_lookup_init(mac, 0);
2670                 }
2671                 goto fail;
2672         }
2673
2674         expire = now - BWN_LO_CALIB_EXPIRE;
2675         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2676                 if (!time_before(cal->calib_time, expire))
2677                         continue;
2678                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2679                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2680                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2681                         expired = 1;
2682                 }
2683
2684                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2685                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2686                     cal->ctl.i, cal->ctl.q);
2687
2688                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2689                 free(cal, M_DEVBUF);
2690         }
2691         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2692                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2693                     &pg->pg_rfatt);
2694                 if (cal == NULL) {
2695                         device_printf(sc->sc_dev,
2696                             "failed to recalibrate LO\n");
2697                         goto fail;
2698                 }
2699                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2700                 bwn_lo_write(mac, &cal->ctl);
2701         }
2702
2703 fail:
2704         bwn_mac_enable(mac);
2705 }
2706
2707 static void
2708 bwn_phy_g_task_60s(struct bwn_mac *mac)
2709 {
2710         struct bwn_phy *phy = &mac->mac_phy;
2711         struct bwn_softc *sc = mac->mac_sc;
2712         uint8_t old = phy->chan;
2713
2714         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2715                 return;
2716
2717         bwn_mac_suspend(mac);
2718         bwn_nrssi_slope_11g(mac);
2719         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2720                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2721                 bwn_switch_channel(mac, old);
2722         }
2723         bwn_mac_enable(mac);
2724 }
2725
2726 static void
2727 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2728 {
2729
2730         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2731 }
2732
2733 static int
2734 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2735         const struct ieee80211_bpf_params *params)
2736 {
2737         struct ieee80211com *ic = ni->ni_ic;
2738         struct ifnet *ifp = ic->ic_ifp;
2739         struct bwn_softc *sc = ifp->if_softc;
2740         struct bwn_mac *mac = sc->sc_curmac;
2741
2742         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2743             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2744                 ieee80211_free_node(ni);
2745                 m_freem(m);
2746                 return (ENETDOWN);
2747         }
2748
2749         BWN_LOCK(sc);
2750         if (bwn_tx_isfull(sc, m)) {
2751                 ieee80211_free_node(ni);
2752                 m_freem(m);
2753                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2754                 BWN_UNLOCK(sc);
2755                 return (ENOBUFS);
2756         }
2757
2758         if (bwn_tx_start(sc, ni, m) != 0) {
2759                 if (ni != NULL)
2760                         ieee80211_free_node(ni);
2761                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2762         }
2763         sc->sc_watchdog_timer = 5;
2764         BWN_UNLOCK(sc);
2765         return (0);
2766 }
2767
2768 /*
2769  * Callback from the 802.11 layer to update the slot time
2770  * based on the current setting.  We use it to notify the
2771  * firmware of ERP changes and the f/w takes care of things
2772  * like slot time and preamble.
2773  */
2774 static void
2775 bwn_updateslot(struct ifnet *ifp)
2776 {
2777         struct bwn_softc *sc = ifp->if_softc;
2778         struct ieee80211com *ic = ifp->if_l2com;
2779         struct bwn_mac *mac;
2780
2781         BWN_LOCK(sc);
2782         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2783                 mac = (struct bwn_mac *)sc->sc_curmac;
2784                 bwn_set_slot_time(mac,
2785                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2786         }
2787         BWN_UNLOCK(sc);
2788 }
2789
2790 /*
2791  * Callback from the 802.11 layer after a promiscuous mode change.
2792  * Note this interface does not check the operating mode as this
2793  * is an internal callback and we are expected to honor the current
2794  * state (e.g. this is used for setting the interface in promiscuous
2795  * mode when operating in hostap mode to do ACS).
2796  */
2797 static void
2798 bwn_update_promisc(struct ifnet *ifp)
2799 {
2800         struct bwn_softc *sc = ifp->if_softc;
2801         struct bwn_mac *mac = sc->sc_curmac;
2802
2803         BWN_LOCK(sc);
2804         mac = sc->sc_curmac;
2805         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2806                 if (ifp->if_flags & IFF_PROMISC)
2807                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2808                 else
2809                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2810                 bwn_set_opmode(mac);
2811         }
2812         BWN_UNLOCK(sc);
2813 }
2814
2815 /*
2816  * Callback from the 802.11 layer to update WME parameters.
2817  */
2818 static int
2819 bwn_wme_update(struct ieee80211com *ic)
2820 {
2821         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2822         struct bwn_mac *mac = sc->sc_curmac;
2823         struct wmeParams *wmep;
2824         int i;
2825
2826         BWN_LOCK(sc);
2827         mac = sc->sc_curmac;
2828         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2829                 bwn_mac_suspend(mac);
2830                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2831                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2832                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2833                 }
2834                 bwn_mac_enable(mac);
2835         }
2836         BWN_UNLOCK(sc);
2837         return (0);
2838 }
2839
2840 static void
2841 bwn_scan_start(struct ieee80211com *ic)
2842 {
2843         struct ifnet *ifp = ic->ic_ifp;
2844         struct bwn_softc *sc = ifp->if_softc;
2845         struct bwn_mac *mac;
2846
2847         BWN_LOCK(sc);
2848         mac = sc->sc_curmac;
2849         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2850                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2851                 bwn_set_opmode(mac);
2852                 /* disable CFP update during scan */
2853                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2854         }
2855         BWN_UNLOCK(sc);
2856 }
2857
2858 static void
2859 bwn_scan_end(struct ieee80211com *ic)
2860 {
2861         struct ifnet *ifp = ic->ic_ifp;
2862         struct bwn_softc *sc = ifp->if_softc;
2863         struct bwn_mac *mac;
2864
2865         BWN_LOCK(sc);
2866         mac = sc->sc_curmac;
2867         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2868                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2869                 bwn_set_opmode(mac);
2870                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2871         }
2872         BWN_UNLOCK(sc);
2873 }
2874
2875 static void
2876 bwn_set_channel(struct ieee80211com *ic)
2877 {
2878         struct ifnet *ifp = ic->ic_ifp;
2879         struct bwn_softc *sc = ifp->if_softc;
2880         struct bwn_mac *mac = sc->sc_curmac;
2881         struct bwn_phy *phy = &mac->mac_phy;
2882         int chan, error;
2883
2884         BWN_LOCK(sc);
2885
2886         error = bwn_switch_band(sc, ic->ic_curchan);
2887         if (error)
2888                 goto fail;
2889         bwn_mac_suspend(mac);
2890         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2891         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2892         if (chan != phy->chan)
2893                 bwn_switch_channel(mac, chan);
2894
2895         /* TX power level */
2896         if (ic->ic_curchan->ic_maxpower != 0 &&
2897             ic->ic_curchan->ic_maxpower != phy->txpower) {
2898                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2899                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2900                     BWN_TXPWR_IGNORE_TSSI);
2901         }
2902
2903         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2904         if (phy->set_antenna)
2905                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2906
2907         if (sc->sc_rf_enabled != phy->rf_on) {
2908                 if (sc->sc_rf_enabled) {
2909                         bwn_rf_turnon(mac);
2910                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2911                                 device_printf(sc->sc_dev,
2912                                     "please turn on the RF switch\n");
2913                 } else
2914                         bwn_rf_turnoff(mac);
2915         }
2916
2917         bwn_mac_enable(mac);
2918
2919 fail:
2920         /*
2921          * Setup radio tap channel freq and flags
2922          */
2923         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2924                 htole16(ic->ic_curchan->ic_freq);
2925         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2926                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2927
2928         BWN_UNLOCK(sc);
2929 }
2930
2931 static struct ieee80211vap *
2932 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2933     enum ieee80211_opmode opmode, int flags,
2934     const uint8_t bssid[IEEE80211_ADDR_LEN],
2935     const uint8_t mac0[IEEE80211_ADDR_LEN])
2936 {
2937         struct ifnet *ifp = ic->ic_ifp;
2938         struct bwn_softc *sc = ifp->if_softc;
2939         struct ieee80211vap *vap;
2940         struct bwn_vap *bvp;
2941         uint8_t mac[IEEE80211_ADDR_LEN];
2942
2943         IEEE80211_ADDR_COPY(mac, mac0);
2944         switch (opmode) {
2945         case IEEE80211_M_HOSTAP:
2946         case IEEE80211_M_MBSS:
2947         case IEEE80211_M_STA:
2948         case IEEE80211_M_WDS:
2949         case IEEE80211_M_MONITOR:
2950         case IEEE80211_M_IBSS:
2951         case IEEE80211_M_AHDEMO:
2952                 break;
2953         default:
2954                 return (NULL);
2955         }
2956
2957         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2958
2959         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2960             M_80211_VAP, M_NOWAIT | M_ZERO);
2961         if (bvp == NULL) {
2962                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2963                 return (NULL);
2964         }
2965         vap = &bvp->bv_vap;
2966         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2967         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2968         /* override with driver methods */
2969         bvp->bv_newstate = vap->iv_newstate;
2970         vap->iv_newstate = bwn_newstate;
2971
2972         /* override max aid so sta's cannot assoc when we're out of sta id's */
2973         vap->iv_max_aid = BWN_STAID_MAX;
2974
2975         ieee80211_ratectl_init(vap);
2976
2977         /* complete setup */
2978         ieee80211_vap_attach(vap, ieee80211_media_change,
2979             ieee80211_media_status);
2980         return (vap);
2981 }
2982
2983 static void
2984 bwn_vap_delete(struct ieee80211vap *vap)
2985 {
2986         struct bwn_vap *bvp = BWN_VAP(vap);
2987
2988         ieee80211_ratectl_deinit(vap);
2989         ieee80211_vap_detach(vap);
2990         free(bvp, M_80211_VAP);
2991 }
2992
2993 static void
2994 bwn_init(void *arg)
2995 {
2996         struct bwn_softc *sc = arg;
2997         struct ifnet *ifp = sc->sc_ifp;
2998         struct ieee80211com *ic = ifp->if_l2com;
2999         int error = 0;
3000
3001         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3002                 __func__, ifp->if_flags);
3003
3004         BWN_LOCK(sc);
3005         error = bwn_init_locked(sc);
3006         BWN_UNLOCK(sc);
3007
3008         if (error == 0)
3009                 ieee80211_start_all(ic);        /* start all vap's */
3010 }
3011
3012 static int
3013 bwn_init_locked(struct bwn_softc *sc)
3014 {
3015         struct bwn_mac *mac;
3016         struct ifnet *ifp = sc->sc_ifp;
3017         int error;
3018
3019         BWN_ASSERT_LOCKED(sc);
3020
3021         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3022         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3023         sc->sc_filters = 0;
3024         bwn_wme_clear(sc);
3025         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3026         sc->sc_rf_enabled = 1;
3027
3028         mac = sc->sc_curmac;
3029         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3030                 error = bwn_core_init(mac);
3031                 if (error != 0)
3032                         return (error);
3033         }
3034         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3035                 bwn_core_start(mac);
3036
3037         bwn_set_opmode(mac);
3038         bwn_set_pretbtt(mac);
3039         bwn_spu_setdelay(mac, 0);
3040         bwn_set_macaddr(mac);
3041
3042         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3043         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3044         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3045
3046         return (0);
3047 }
3048
3049 static void
3050 bwn_stop(struct bwn_softc *sc, int statechg)
3051 {
3052
3053         BWN_LOCK(sc);
3054         bwn_stop_locked(sc, statechg);
3055         BWN_UNLOCK(sc);
3056 }
3057
3058 static void
3059 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3060 {
3061         struct bwn_mac *mac = sc->sc_curmac;
3062         struct ifnet *ifp = sc->sc_ifp;
3063
3064         BWN_ASSERT_LOCKED(sc);
3065
3066         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3067                 /* XXX FIXME opmode not based on VAP */
3068                 bwn_set_opmode(mac);
3069                 bwn_set_macaddr(mac);
3070         }
3071
3072         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3073                 bwn_core_stop(mac);
3074
3075         callout_stop(&sc->sc_led_blink_ch);
3076         sc->sc_led_blinking = 0;
3077
3078         bwn_core_exit(mac);
3079         sc->sc_rf_enabled = 0;
3080
3081         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3082 }
3083
3084 static void
3085 bwn_wme_clear(struct bwn_softc *sc)
3086 {
3087 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3088         struct wmeParams *p;
3089         unsigned int i;
3090
3091         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3092             ("%s:%d: fail", __func__, __LINE__));
3093
3094         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3095                 p = &(sc->sc_wmeParams[i]);
3096
3097                 switch (bwn_wme_shm_offsets[i]) {
3098                 case BWN_WME_VOICE:
3099                         p->wmep_txopLimit = 0;
3100                         p->wmep_aifsn = 2;
3101                         /* XXX FIXME: log2(cwmin) */
3102                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3103                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3104                         break;
3105                 case BWN_WME_VIDEO:
3106                         p->wmep_txopLimit = 0;
3107                         p->wmep_aifsn = 2;
3108                         /* XXX FIXME: log2(cwmin) */
3109                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3110                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3111                         break;
3112                 case BWN_WME_BESTEFFORT:
3113                         p->wmep_txopLimit = 0;
3114                         p->wmep_aifsn = 3;
3115                         /* XXX FIXME: log2(cwmin) */
3116                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3117                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3118                         break;
3119                 case BWN_WME_BACKGROUND:
3120                         p->wmep_txopLimit = 0;
3121                         p->wmep_aifsn = 7;
3122                         /* XXX FIXME: log2(cwmin) */
3123                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3124                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3125                         break;
3126                 default:
3127                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3128                 }
3129         }
3130 }
3131
3132 static int
3133 bwn_core_init(struct bwn_mac *mac)
3134 {
3135         struct bwn_softc *sc = mac->mac_sc;
3136         uint64_t hf;
3137         int error;
3138
3139         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3140             ("%s:%d: fail", __func__, __LINE__));
3141
3142         siba_powerup(sc->sc_dev, 0);
3143         if (!siba_dev_isup(sc->sc_dev))
3144                 bwn_reset_core(mac,
3145                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3146
3147         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3148         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3149         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3150         BWN_GETTIME(mac->mac_phy.nexttime);
3151         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3152         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3153         mac->mac_stats.link_noise = -95;
3154         mac->mac_reason_intr = 0;
3155         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3156         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3157 #ifdef BWN_DEBUG
3158         if (sc->sc_debug & BWN_DEBUG_XMIT)
3159                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3160 #endif
3161         mac->mac_suspended = 1;
3162         mac->mac_task_state = 0;
3163         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3164
3165         mac->mac_phy.init_pre(mac);
3166
3167         siba_pcicore_intr(sc->sc_dev);
3168
3169         siba_fix_imcfglobug(sc->sc_dev);
3170         bwn_bt_disable(mac);
3171         if (mac->mac_phy.prepare_hw) {
3172                 error = mac->mac_phy.prepare_hw(mac);
3173                 if (error)
3174                         goto fail0;
3175         }
3176         error = bwn_chip_init(mac);
3177         if (error)
3178                 goto fail0;
3179         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3180             siba_get_revid(sc->sc_dev));
3181         hf = bwn_hf_read(mac);
3182         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3183                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3184                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3185                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3186                 if (mac->mac_phy.rev == 1)
3187                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3188         }
3189         if (mac->mac_phy.rf_ver == 0x2050) {
3190                 if (mac->mac_phy.rf_rev < 6)
3191                         hf |= BWN_HF_FORCE_VCO_RECALC;
3192                 if (mac->mac_phy.rf_rev == 6)
3193                         hf |= BWN_HF_4318_TSSI;
3194         }
3195         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3196                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3197         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3198             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3199                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3200         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3201         bwn_hf_write(mac, hf);
3202
3203         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3204         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3205         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3206         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3207
3208         bwn_rate_init(mac);
3209         bwn_set_phytxctl(mac);
3210
3211         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3212             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3213         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3214
3215         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3216                 bwn_pio_init(mac);
3217         else
3218                 bwn_dma_init(mac);
3219         bwn_wme_init(mac);
3220         bwn_spu_setdelay(mac, 1);
3221         bwn_bt_enable(mac);
3222
3223         siba_powerup(sc->sc_dev,
3224             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3225         bwn_set_macaddr(mac);
3226         bwn_crypt_init(mac);
3227
3228         /* XXX LED initializatin */
3229
3230         mac->mac_status = BWN_MAC_STATUS_INITED;
3231
3232         return (error);
3233
3234 fail0:
3235         siba_powerdown(sc->sc_dev);
3236         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3237             ("%s:%d: fail", __func__, __LINE__));
3238         return (error);
3239 }
3240
3241 static void
3242 bwn_core_start(struct bwn_mac *mac)
3243 {
3244         struct bwn_softc *sc = mac->mac_sc;
3245         uint32_t tmp;
3246
3247         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3248             ("%s:%d: fail", __func__, __LINE__));
3249
3250         if (siba_get_revid(sc->sc_dev) < 5)
3251                 return;
3252
3253         while (1) {
3254                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3255                 if (!(tmp & 0x00000001))
3256                         break;
3257                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3258         }
3259
3260         bwn_mac_enable(mac);
3261         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3262         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3263
3264         mac->mac_status = BWN_MAC_STATUS_STARTED;
3265 }
3266
3267 static void
3268 bwn_core_exit(struct bwn_mac *mac)
3269 {
3270         struct bwn_softc *sc = mac->mac_sc;
3271         uint32_t macctl;
3272
3273         BWN_ASSERT_LOCKED(mac->mac_sc);
3274
3275         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3276             ("%s:%d: fail", __func__, __LINE__));
3277
3278         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3279                 return;
3280         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3281
3282         macctl = BWN_READ_4(mac, BWN_MACCTL);
3283         macctl &= ~BWN_MACCTL_MCODE_RUN;
3284         macctl |= BWN_MACCTL_MCODE_JMP0;
3285         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3286
3287         bwn_dma_stop(mac);
3288         bwn_pio_stop(mac);
3289         bwn_chip_exit(mac);
3290         mac->mac_phy.switch_analog(mac, 0);
3291         siba_dev_down(sc->sc_dev, 0);
3292         siba_powerdown(sc->sc_dev);
3293 }
3294
3295 static void
3296 bwn_bt_disable(struct bwn_mac *mac)
3297 {
3298         struct bwn_softc *sc = mac->mac_sc;
3299
3300         (void)sc;
3301         /* XXX do nothing yet */
3302 }
3303
3304 static int
3305 bwn_chip_init(struct bwn_mac *mac)
3306 {
3307         struct bwn_softc *sc = mac->mac_sc;
3308         struct bwn_phy *phy = &mac->mac_phy;
3309         uint32_t macctl;
3310         int error;
3311
3312         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3313         if (phy->gmode)
3314                 macctl |= BWN_MACCTL_GMODE;
3315         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3316
3317         error = bwn_fw_fillinfo(mac);
3318         if (error)
3319                 return (error);
3320         error = bwn_fw_loaducode(mac);
3321         if (error)
3322                 return (error);
3323
3324         error = bwn_gpio_init(mac);
3325         if (error)
3326                 return (error);
3327
3328         error = bwn_fw_loadinitvals(mac);
3329         if (error) {
3330                 siba_gpio_set(sc->sc_dev, 0);
3331                 return (error);
3332         }
3333         phy->switch_analog(mac, 1);
3334         error = bwn_phy_init(mac);
3335         if (error) {
3336                 siba_gpio_set(sc->sc_dev, 0);
3337                 return (error);
3338         }
3339         if (phy->set_im)
3340                 phy->set_im(mac, BWN_IMMODE_NONE);
3341         if (phy->set_antenna)
3342                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3343         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3344
3345         if (phy->type == BWN_PHYTYPE_B)
3346                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3347         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3348         if (siba_get_revid(sc->sc_dev) < 5)
3349                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3350
3351         BWN_WRITE_4(mac, BWN_MACCTL,
3352             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3353         BWN_WRITE_4(mac, BWN_MACCTL,
3354             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3355         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3356
3357         bwn_set_opmode(mac);
3358         if (siba_get_revid(sc->sc_dev) < 3) {
3359                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3360                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3361                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3362                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3363         } else {
3364                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3365                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3366         }
3367         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3368         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3369         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3370         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3371         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3372         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3373         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3374         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3375             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3376         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3377         return (error);
3378 }
3379
3380 /* read hostflags */
3381 static uint64_t
3382 bwn_hf_read(struct bwn_mac *mac)
3383 {
3384         uint64_t ret;
3385
3386         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3387         ret <<= 16;
3388         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3389         ret <<= 16;
3390         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3391         return (ret);
3392 }
3393
3394 static void
3395 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3396 {
3397
3398         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3399             (value & 0x00000000ffffull));
3400         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3401             (value & 0x0000ffff0000ull) >> 16);
3402         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3403             (value & 0xffff00000000ULL) >> 32);
3404 }
3405
3406 static void
3407 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3408 {
3409
3410         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3411         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3412 }
3413
3414 static void
3415 bwn_rate_init(struct bwn_mac *mac)
3416 {
3417
3418         switch (mac->mac_phy.type) {
3419         case BWN_PHYTYPE_A:
3420         case BWN_PHYTYPE_G:
3421         case BWN_PHYTYPE_LP:
3422         case BWN_PHYTYPE_N:
3423                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3424                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3425                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3426                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3427                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3428                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3429                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3430                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3431                         break;
3432                 /* FALLTHROUGH */
3433         case BWN_PHYTYPE_B:
3434                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3435                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3436                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3437                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3438                 break;
3439         default:
3440                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3441         }
3442 }
3443
3444 static void
3445 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3446 {
3447         uint16_t offset;
3448
3449         if (ofdm) {
3450                 offset = 0x480;
3451                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3452         } else {
3453                 offset = 0x4c0;
3454                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3455         }
3456         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3457             bwn_shm_read_2(mac, BWN_SHARED, offset));
3458 }
3459
3460 static uint8_t
3461 bwn_plcp_getcck(const uint8_t bitrate)
3462 {
3463
3464         switch (bitrate) {
3465         case BWN_CCK_RATE_1MB:
3466                 return (0x0a);
3467         case BWN_CCK_RATE_2MB:
3468                 return (0x14);
3469         case BWN_CCK_RATE_5MB:
3470                 return (0x37);
3471         case BWN_CCK_RATE_11MB:
3472                 return (0x6e);
3473         }
3474         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3475         return (0);
3476 }
3477
3478 static uint8_t
3479 bwn_plcp_getofdm(const uint8_t bitrate)
3480 {
3481
3482         switch (bitrate) {
3483         case BWN_OFDM_RATE_6MB:
3484                 return (0xb);
3485         case BWN_OFDM_RATE_9MB:
3486                 return (0xf);
3487         case BWN_OFDM_RATE_12MB:
3488                 return (0xa);
3489         case BWN_OFDM_RATE_18MB:
3490                 return (0xe);
3491         case BWN_OFDM_RATE_24MB:
3492                 return (0x9);
3493         case BWN_OFDM_RATE_36MB:
3494                 return (0xd);
3495         case BWN_OFDM_RATE_48MB:
3496                 return (0x8);
3497         case BWN_OFDM_RATE_54MB:
3498                 return (0xc);
3499         }
3500         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3501         return (0);
3502 }
3503
3504 static void
3505 bwn_set_phytxctl(struct bwn_mac *mac)
3506 {
3507         uint16_t ctl;
3508
3509         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3510             BWN_TX_PHY_TXPWR);
3511         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3512         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3513         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3514 }
3515
3516 static void
3517 bwn_pio_init(struct bwn_mac *mac)
3518 {
3519         struct bwn_pio *pio = &mac->mac_method.pio;
3520
3521         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3522             & ~BWN_MACCTL_BIGENDIAN);
3523         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3524
3525         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3526         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3527         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3528         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3529         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3530         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3531 }
3532
3533 static void
3534 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3535     int index)
3536 {
3537         struct bwn_pio_txpkt *tp;
3538         struct bwn_softc *sc = mac->mac_sc;
3539         unsigned int i;
3540
3541         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3542         tq->tq_index = index;
3543
3544         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3545         if (siba_get_revid(sc->sc_dev) >= 8)
3546                 tq->tq_size = 1920;
3547         else {
3548                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3549                 tq->tq_size -= 80;
3550         }
3551
3552         TAILQ_INIT(&tq->tq_pktlist);
3553         for (i = 0; i < N(tq->tq_pkts); i++) {
3554                 tp = &(tq->tq_pkts[i]);
3555                 tp->tp_index = i;
3556                 tp->tp_queue = tq;
3557                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3558         }
3559 }
3560
3561 static uint16_t
3562 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3563 {
3564         struct bwn_softc *sc = mac->mac_sc;
3565         static const uint16_t bases[] = {
3566                 BWN_PIO_BASE0,
3567                 BWN_PIO_BASE1,
3568                 BWN_PIO_BASE2,
3569                 BWN_PIO_BASE3,
3570                 BWN_PIO_BASE4,
3571                 BWN_PIO_BASE5,
3572                 BWN_PIO_BASE6,
3573                 BWN_PIO_BASE7,
3574         };
3575         static const uint16_t bases_rev11[] = {
3576                 BWN_PIO11_BASE0,
3577                 BWN_PIO11_BASE1,
3578                 BWN_PIO11_BASE2,
3579                 BWN_PIO11_BASE3,
3580                 BWN_PIO11_BASE4,
3581                 BWN_PIO11_BASE5,
3582         };
3583
3584         if (siba_get_revid(sc->sc_dev) >= 11) {
3585                 if (index >= N(bases_rev11))
3586                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3587                 return (bases_rev11[index]);
3588         }
3589         if (index >= N(bases))
3590                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3591         return (bases[index]);
3592 }
3593
3594 static void
3595 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3596     int index)
3597 {
3598         struct bwn_softc *sc = mac->mac_sc;
3599
3600         prq->prq_mac = mac;
3601         prq->prq_rev = siba_get_revid(sc->sc_dev);
3602         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3603         bwn_dma_rxdirectfifo(mac, index, 1);
3604 }
3605
3606 static void
3607 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3608 {
3609         if (tq == NULL)
3610                 return;
3611         bwn_pio_cancel_tx_packets(tq);
3612 }
3613
3614 static void
3615 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3616 {
3617
3618         bwn_destroy_pioqueue_tx(pio);
3619 }
3620
3621 static uint16_t
3622 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3623     uint16_t offset)
3624 {
3625
3626         return (BWN_READ_2(mac, tq->tq_base + offset));
3627 }
3628
3629 static void
3630 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3631 {
3632         uint32_t ctl;
3633         int type;
3634         uint16_t base;
3635
3636         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3637         base = bwn_dma_base(type, idx);
3638         if (type == BWN_DMA_64BIT) {
3639                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3640                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3641                 if (enable)
3642                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3643                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3644         } else {
3645                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3646                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3647                 if (enable)
3648                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3649                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3650         }
3651 }
3652
3653 static uint64_t
3654 bwn_dma_mask(struct bwn_mac *mac)
3655 {
3656         uint32_t tmp;
3657         uint16_t base;
3658
3659         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3660         if (tmp & SIBA_TGSHIGH_DMA64)
3661                 return (BWN_DMA_BIT_MASK(64));
3662         base = bwn_dma_base(0, 0);
3663         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3664         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3665         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3666                 return (BWN_DMA_BIT_MASK(32));
3667
3668         return (BWN_DMA_BIT_MASK(30));
3669 }
3670
3671 static int
3672 bwn_dma_mask2type(uint64_t dmamask)
3673 {
3674
3675         if (dmamask == BWN_DMA_BIT_MASK(30))
3676                 return (BWN_DMA_30BIT);
3677         if (dmamask == BWN_DMA_BIT_MASK(32))
3678                 return (BWN_DMA_32BIT);
3679         if (dmamask == BWN_DMA_BIT_MASK(64))
3680                 return (BWN_DMA_64BIT);
3681         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3682         return (BWN_DMA_30BIT);
3683 }
3684
3685 static void
3686 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3687 {
3688         struct bwn_pio_txpkt *tp;
3689         unsigned int i;
3690
3691         for (i = 0; i < N(tq->tq_pkts); i++) {
3692                 tp = &(tq->tq_pkts[i]);
3693                 if (tp->tp_m) {
3694                         m_freem(tp->tp_m);
3695                         tp->tp_m = NULL;
3696                 }
3697         }
3698 }
3699
3700 static uint16_t
3701 bwn_dma_base(int type, int controller_idx)
3702 {
3703         static const uint16_t map64[] = {
3704                 BWN_DMA64_BASE0,
3705                 BWN_DMA64_BASE1,
3706                 BWN_DMA64_BASE2,
3707                 BWN_DMA64_BASE3,
3708                 BWN_DMA64_BASE4,
3709                 BWN_DMA64_BASE5,
3710         };
3711         static const uint16_t map32[] = {
3712                 BWN_DMA32_BASE0,
3713                 BWN_DMA32_BASE1,
3714                 BWN_DMA32_BASE2,
3715                 BWN_DMA32_BASE3,
3716                 BWN_DMA32_BASE4,
3717                 BWN_DMA32_BASE5,
3718         };
3719
3720         if (type == BWN_DMA_64BIT) {
3721                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3722                     ("%s:%d: fail", __func__, __LINE__));
3723                 return (map64[controller_idx]);
3724         }
3725         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3726             ("%s:%d: fail", __func__, __LINE__));
3727         return (map32[controller_idx]);
3728 }
3729
3730 static void
3731 bwn_dma_init(struct bwn_mac *mac)
3732 {
3733         struct bwn_dma *dma = &mac->mac_method.dma;
3734
3735         /* setup TX DMA channels. */
3736         bwn_dma_setup(dma->wme[WME_AC_BK]);
3737         bwn_dma_setup(dma->wme[WME_AC_BE]);
3738         bwn_dma_setup(dma->wme[WME_AC_VI]);
3739         bwn_dma_setup(dma->wme[WME_AC_VO]);
3740         bwn_dma_setup(dma->mcast);
3741         /* setup RX DMA channel. */
3742         bwn_dma_setup(dma->rx);
3743 }
3744
3745 static struct bwn_dma_ring *
3746 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3747     int for_tx, int type)
3748 {
3749         struct bwn_dma *dma = &mac->mac_method.dma;
3750         struct bwn_dma_ring *dr;
3751         struct bwn_dmadesc_generic *desc;
3752         struct bwn_dmadesc_meta *mt;
3753         struct bwn_softc *sc = mac->mac_sc;
3754         int error, i;
3755
3756         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3757         if (dr == NULL)
3758                 goto out;
3759         dr->dr_numslots = BWN_RXRING_SLOTS;
3760         if (for_tx)
3761                 dr->dr_numslots = BWN_TXRING_SLOTS;
3762
3763         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3764             M_DEVBUF, M_NOWAIT | M_ZERO);
3765         if (dr->dr_meta == NULL)
3766                 goto fail0;
3767
3768         dr->dr_type = type;
3769         dr->dr_mac = mac;
3770         dr->dr_base = bwn_dma_base(type, controller_index);
3771         dr->dr_index = controller_index;
3772         if (type == BWN_DMA_64BIT) {
3773                 dr->getdesc = bwn_dma_64_getdesc;
3774                 dr->setdesc = bwn_dma_64_setdesc;
3775                 dr->start_transfer = bwn_dma_64_start_transfer;
3776                 dr->suspend = bwn_dma_64_suspend;
3777                 dr->resume = bwn_dma_64_resume;
3778                 dr->get_curslot = bwn_dma_64_get_curslot;
3779                 dr->set_curslot = bwn_dma_64_set_curslot;
3780         } else {
3781                 dr->getdesc = bwn_dma_32_getdesc;
3782                 dr->setdesc = bwn_dma_32_setdesc;
3783                 dr->start_transfer = bwn_dma_32_start_transfer;
3784                 dr->suspend = bwn_dma_32_suspend;
3785                 dr->resume = bwn_dma_32_resume;
3786                 dr->get_curslot = bwn_dma_32_get_curslot;
3787                 dr->set_curslot = bwn_dma_32_set_curslot;
3788         }
3789         if (for_tx) {
3790                 dr->dr_tx = 1;
3791                 dr->dr_curslot = -1;
3792         } else {
3793                 if (dr->dr_index == 0) {
3794                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3795                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3796                 } else
3797                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3798         }
3799
3800         error = bwn_dma_allocringmemory(dr);
3801         if (error)
3802                 goto fail2;
3803
3804         if (for_tx) {
3805                 /*
3806                  * Assumption: BWN_TXRING_SLOTS can be divided by
3807                  * BWN_TX_SLOTS_PER_FRAME
3808                  */
3809                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3810                     ("%s:%d: fail", __func__, __LINE__));
3811
3812                 dr->dr_txhdr_cache =
3813                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3814                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3815                 KASSERT(dr->dr_txhdr_cache != NULL,
3816                     ("%s:%d: fail", __func__, __LINE__));
3817
3818                 /*
3819                  * Create TX ring DMA stuffs
3820                  */
3821                 error = bus_dma_tag_create(dma->parent_dtag,
3822                                     BWN_ALIGN, 0,
3823                                     BUS_SPACE_MAXADDR,
3824                                     BUS_SPACE_MAXADDR,
3825                                     NULL, NULL,
3826                                     BWN_HDRSIZE(mac),
3827                                     1,
3828                                     BUS_SPACE_MAXSIZE_32BIT,
3829                                     0,
3830                                     NULL, NULL,
3831                                     &dr->dr_txring_dtag);
3832                 if (error) {
3833                         device_printf(sc->sc_dev,
3834                             "can't create TX ring DMA tag: TODO frees\n");
3835                         goto fail1;
3836                 }
3837
3838                 for (i = 0; i < dr->dr_numslots; i += 2) {
3839                         dr->getdesc(dr, i, &desc, &mt);
3840
3841                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3842                         mt->mt_m = NULL;
3843                         mt->mt_ni = NULL;
3844                         mt->mt_islast = 0;
3845                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3846                             &mt->mt_dmap);
3847                         if (error) {
3848                                 device_printf(sc->sc_dev,
3849                                      "can't create RX buf DMA map\n");
3850                                 goto fail1;
3851                         }
3852
3853                         dr->getdesc(dr, i + 1, &desc, &mt);
3854
3855                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3856                         mt->mt_m = NULL;
3857                         mt->mt_ni = NULL;
3858                         mt->mt_islast = 1;
3859                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3860                             &mt->mt_dmap);
3861                         if (error) {
3862                                 device_printf(sc->sc_dev,
3863                                      "can't create RX buf DMA map\n");
3864                                 goto fail1;
3865                         }
3866                 }
3867         } else {
3868                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3869                     &dr->dr_spare_dmap);
3870                 if (error) {
3871                         device_printf(sc->sc_dev,
3872                             "can't create RX buf DMA map\n");
3873                         goto out;               /* XXX wrong! */
3874                 }
3875
3876                 for (i = 0; i < dr->dr_numslots; i++) {
3877                         dr->getdesc(dr, i, &desc, &mt);
3878
3879                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3880                             &mt->mt_dmap);
3881                         if (error) {
3882                                 device_printf(sc->sc_dev,
3883                                     "can't create RX buf DMA map\n");
3884                                 goto out;       /* XXX wrong! */
3885                         }
3886                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3887                         if (error) {
3888                                 device_printf(sc->sc_dev,
3889                                     "failed to allocate RX buf\n");
3890                                 goto out;       /* XXX wrong! */
3891                         }
3892                 }
3893
3894                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3895                     BUS_DMASYNC_PREWRITE);
3896
3897                 dr->dr_usedslot = dr->dr_numslots;
3898         }
3899
3900       out:
3901         return (dr);
3902
3903 fail2:
3904         free(dr->dr_txhdr_cache, M_DEVBUF);
3905 fail1:
3906         free(dr->dr_meta, M_DEVBUF);
3907 fail0:
3908         free(dr, M_DEVBUF);
3909         return (NULL);
3910 }
3911
3912 static void
3913 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3914 {
3915
3916         if (dr == NULL)
3917                 return;
3918
3919         bwn_dma_free_descbufs(*dr);
3920         bwn_dma_free_ringmemory(*dr);
3921
3922         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3923         free((*dr)->dr_meta, M_DEVBUF);
3924         free(*dr, M_DEVBUF);
3925
3926         *dr = NULL;
3927 }
3928
3929 static void
3930 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3931     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3932 {
3933         struct bwn_dmadesc32 *desc;
3934
3935         *meta = &(dr->dr_meta[slot]);
3936         desc = dr->dr_ring_descbase;
3937         desc = &(desc[slot]);
3938
3939         *gdesc = (struct bwn_dmadesc_generic *)desc;
3940 }
3941
3942 static void
3943 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3944     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3945     int start, int end, int irq)
3946 {
3947         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3948         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3949         uint32_t addr, addrext, ctl;
3950         int slot;
3951
3952         slot = (int)(&(desc->dma.dma32) - descbase);
3953         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3954             ("%s:%d: fail", __func__, __LINE__));
3955
3956         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3957         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3958         addr |= siba_dma_translation(sc->sc_dev);
3959         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3960         if (slot == dr->dr_numslots - 1)
3961                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3962         if (start)
3963                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3964         if (end)
3965                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3966         if (irq)
3967                 ctl |= BWN_DMA32_DCTL_IRQ;
3968         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3969             & BWN_DMA32_DCTL_ADDREXT_MASK;
3970
3971         desc->dma.dma32.control = htole32(ctl);
3972         desc->dma.dma32.address = htole32(addr);
3973 }
3974
3975 static void
3976 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3977 {
3978
3979         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3980             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3981 }
3982
3983 static void
3984 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3985 {
3986
3987         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3988             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3989 }
3990
3991 static void
3992 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3993 {
3994
3995         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3996             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3997 }
3998
3999 static int
4000 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4001 {
4002         uint32_t val;
4003
4004         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4005         val &= BWN_DMA32_RXDPTR;
4006
4007         return (val / sizeof(struct bwn_dmadesc32));
4008 }
4009
4010 static void
4011 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4012 {
4013
4014         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4015             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4016 }
4017
4018 static void
4019 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4020     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4021 {
4022         struct bwn_dmadesc64 *desc;
4023
4024         *meta = &(dr->dr_meta[slot]);
4025         desc = dr->dr_ring_descbase;
4026         desc = &(desc[slot]);
4027
4028         *gdesc = (struct bwn_dmadesc_generic *)desc;
4029 }
4030
4031 static void
4032 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4033     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4034     int start, int end, int irq)
4035 {
4036         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4037         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4038         int slot;
4039         uint32_t ctl0 = 0, ctl1 = 0;
4040         uint32_t addrlo, addrhi;
4041         uint32_t addrext;
4042
4043         slot = (int)(&(desc->dma.dma64) - descbase);
4044         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4045             ("%s:%d: fail", __func__, __LINE__));
4046
4047         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4048         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4049         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4050             30;
4051         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4052         if (slot == dr->dr_numslots - 1)
4053                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4054         if (start)
4055                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4056         if (end)
4057                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4058         if (irq)
4059                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4060         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4061         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4062             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4063
4064         desc->dma.dma64.control0 = htole32(ctl0);
4065         desc->dma.dma64.control1 = htole32(ctl1);
4066         desc->dma.dma64.address_low = htole32(addrlo);
4067         desc->dma.dma64.address_high = htole32(addrhi);
4068 }
4069
4070 static void
4071 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4072 {
4073
4074         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4075             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4076 }
4077
4078 static void
4079 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4080 {
4081
4082         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4083             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4084 }
4085
4086 static void
4087 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4088 {
4089
4090         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4091             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4092 }
4093
4094 static int
4095 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4096 {
4097         uint32_t val;
4098
4099         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4100         val &= BWN_DMA64_RXSTATDPTR;
4101
4102         return (val / sizeof(struct bwn_dmadesc64));
4103 }
4104
4105 static void
4106 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4107 {
4108
4109         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4110             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4111 }
4112
4113 static int
4114 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4115 {
4116         struct bwn_mac *mac = dr->dr_mac;
4117         struct bwn_dma *dma = &mac->mac_method.dma;
4118         struct bwn_softc *sc = mac->mac_sc;
4119         int error;
4120
4121         error = bus_dma_tag_create(dma->parent_dtag,
4122                             BWN_ALIGN, 0,
4123                             BUS_SPACE_MAXADDR,
4124                             BUS_SPACE_MAXADDR,
4125                             NULL, NULL,
4126                             BWN_DMA_RINGMEMSIZE,
4127                             1,
4128                             BUS_SPACE_MAXSIZE_32BIT,
4129                             0,
4130                             NULL, NULL,
4131                             &dr->dr_ring_dtag);
4132         if (error) {
4133                 device_printf(sc->sc_dev,
4134                     "can't create TX ring DMA tag: TODO frees\n");
4135                 return (-1);
4136         }
4137
4138         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4139             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4140             &dr->dr_ring_dmap);
4141         if (error) {
4142                 device_printf(sc->sc_dev,
4143                     "can't allocate DMA mem: TODO frees\n");
4144                 return (-1);
4145         }
4146         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4147             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4148             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4149         if (error) {
4150                 device_printf(sc->sc_dev,
4151                     "can't load DMA mem: TODO free\n");
4152                 return (-1);
4153         }
4154
4155         return (0);
4156 }
4157
4158 static void
4159 bwn_dma_setup(struct bwn_dma_ring *dr)
4160 {
4161         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4162         uint64_t ring64;
4163         uint32_t addrext, ring32, value;
4164         uint32_t trans = siba_dma_translation(sc->sc_dev);
4165
4166         if (dr->dr_tx) {
4167                 dr->dr_curslot = -1;
4168
4169                 if (dr->dr_type == BWN_DMA_64BIT) {
4170                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4171                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4172                             >> 30;
4173                         value = BWN_DMA64_TXENABLE;
4174                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4175                             & BWN_DMA64_TXADDREXT_MASK;
4176                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4177                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4178                             (ring64 & 0xffffffff));
4179                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4180                             ((ring64 >> 32) &
4181                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4182                 } else {
4183                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4184                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4185                         value = BWN_DMA32_TXENABLE;
4186                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4187                             & BWN_DMA32_TXADDREXT_MASK;
4188                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4189                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4190                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4191                 }
4192                 return;
4193         }
4194
4195         /*
4196          * set for RX
4197          */
4198         dr->dr_usedslot = dr->dr_numslots;
4199
4200         if (dr->dr_type == BWN_DMA_64BIT) {
4201                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4202                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4203                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4204                 value |= BWN_DMA64_RXENABLE;
4205                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4206                     & BWN_DMA64_RXADDREXT_MASK;
4207                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4208                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4209                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4210                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4211                     | (trans << 1));
4212                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4213                     sizeof(struct bwn_dmadesc64));
4214         } else {
4215                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4216                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4217                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4218                 value |= BWN_DMA32_RXENABLE;
4219                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4220                     & BWN_DMA32_RXADDREXT_MASK;
4221                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4222                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4223                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4224                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4225                     sizeof(struct bwn_dmadesc32));
4226         }
4227 }
4228
4229 static void
4230 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4231 {
4232
4233         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4234         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4235             dr->dr_ring_dmap);
4236 }
4237
4238 static void
4239 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4240 {
4241
4242         if (dr->dr_tx) {
4243                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4244                 if (dr->dr_type == BWN_DMA_64BIT) {
4245                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4246                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4247                 } else
4248                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4249         } else {
4250                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4251                 if (dr->dr_type == BWN_DMA_64BIT) {
4252                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4253                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4254                 } else
4255                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4256         }
4257 }
4258
4259 static void
4260 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4261 {
4262         struct bwn_dmadesc_generic *desc;
4263         struct bwn_dmadesc_meta *meta;
4264         struct bwn_mac *mac = dr->dr_mac;
4265         struct bwn_dma *dma = &mac->mac_method.dma;
4266         struct bwn_softc *sc = mac->mac_sc;
4267         int i;
4268
4269         if (!dr->dr_usedslot)
4270                 return;
4271         for (i = 0; i < dr->dr_numslots; i++) {
4272                 dr->getdesc(dr, i, &desc, &meta);
4273
4274                 if (meta->mt_m == NULL) {
4275                         if (!dr->dr_tx)
4276                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4277                                     __func__);
4278                         continue;
4279                 }
4280                 if (dr->dr_tx) {
4281                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4282                                 bus_dmamap_unload(dr->dr_txring_dtag,
4283                                     meta->mt_dmap);
4284                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4285                                 bus_dmamap_unload(dma->txbuf_dtag,
4286                                     meta->mt_dmap);
4287                 } else
4288                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4289                 bwn_dma_free_descbuf(dr, meta);
4290         }
4291 }
4292
4293 static int
4294 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4295     int type)
4296 {
4297         struct bwn_softc *sc = mac->mac_sc;
4298         uint32_t value;
4299         int i;
4300         uint16_t offset;
4301
4302         for (i = 0; i < 10; i++) {
4303                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4304                     BWN_DMA32_TXSTATUS;
4305                 value = BWN_READ_4(mac, base + offset);
4306                 if (type == BWN_DMA_64BIT) {
4307                         value &= BWN_DMA64_TXSTAT;
4308                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4309                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4310                             value == BWN_DMA64_TXSTAT_STOPPED)
4311                                 break;
4312                 } else {
4313                         value &= BWN_DMA32_TXSTATE;
4314                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4315                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4316                             value == BWN_DMA32_TXSTAT_STOPPED)
4317                                 break;
4318                 }
4319                 DELAY(1000);
4320         }
4321         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4322         BWN_WRITE_4(mac, base + offset, 0);
4323         for (i = 0; i < 10; i++) {
4324                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4325                                                    BWN_DMA32_TXSTATUS;
4326                 value = BWN_READ_4(mac, base + offset);
4327                 if (type == BWN_DMA_64BIT) {
4328                         value &= BWN_DMA64_TXSTAT;
4329                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4330                                 i = -1;
4331                                 break;
4332                         }
4333                 } else {
4334                         value &= BWN_DMA32_TXSTATE;
4335                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4336                                 i = -1;
4337                                 break;
4338                         }
4339                 }
4340                 DELAY(1000);
4341         }
4342         if (i != -1) {
4343                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4344                 return (ENODEV);
4345         }
4346         DELAY(1000);
4347
4348         return (0);
4349 }
4350
4351 static int
4352 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4353     int type)
4354 {
4355         struct bwn_softc *sc = mac->mac_sc;
4356         uint32_t value;
4357         int i;
4358         uint16_t offset;
4359
4360         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4361         BWN_WRITE_4(mac, base + offset, 0);
4362         for (i = 0; i < 10; i++) {
4363                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4364                     BWN_DMA32_RXSTATUS;
4365                 value = BWN_READ_4(mac, base + offset);
4366                 if (type == BWN_DMA_64BIT) {
4367                         value &= BWN_DMA64_RXSTAT;
4368                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4369                                 i = -1;
4370                                 break;
4371                         }
4372                 } else {
4373                         value &= BWN_DMA32_RXSTATE;
4374                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4375                                 i = -1;
4376                                 break;
4377                         }
4378                 }
4379                 DELAY(1000);
4380         }
4381         if (i != -1) {
4382                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4383                 return (ENODEV);
4384         }
4385
4386         return (0);
4387 }
4388
4389 static void
4390 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4391     struct bwn_dmadesc_meta *meta)
4392 {
4393
4394         if (meta->mt_m != NULL) {
4395                 m_freem(meta->mt_m);
4396                 meta->mt_m = NULL;
4397         }
4398         if (meta->mt_ni != NULL) {
4399                 ieee80211_free_node(meta->mt_ni);
4400                 meta->mt_ni = NULL;
4401         }
4402 }
4403
4404 static void
4405 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4406 {
4407         struct bwn_rxhdr4 *rxhdr;
4408         unsigned char *frame;
4409
4410         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4411         rxhdr->frame_len = 0;
4412
4413         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4414             sizeof(struct bwn_plcp6) + 2,
4415             ("%s:%d: fail", __func__, __LINE__));
4416         frame = mtod(m, char *) + dr->dr_frameoffset;
4417         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4418 }
4419
4420 static uint8_t
4421 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4422 {
4423         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4424
4425         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4426             == 0xff);
4427 }
4428
4429 static void
4430 bwn_wme_init(struct bwn_mac *mac)
4431 {
4432
4433         bwn_wme_load(mac);
4434
4435         /* enable WME support. */
4436         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4437         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4438             BWN_IFSCTL_USE_EDCF);
4439 }
4440
4441 static void
4442 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4443 {
4444         struct bwn_softc *sc = mac->mac_sc;
4445         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4446         uint16_t delay; /* microsec */
4447
4448         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4449         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4450                 delay = 500;
4451         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4452                 delay = max(delay, (uint16_t)2400);
4453
4454         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4455 }
4456
4457 static void
4458 bwn_bt_enable(struct bwn_mac *mac)
4459 {
4460         struct bwn_softc *sc = mac->mac_sc;
4461         uint64_t hf;
4462
4463         if (bwn_bluetooth == 0)
4464                 return;
4465         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4466                 return;
4467         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4468                 return;
4469
4470         hf = bwn_hf_read(mac);
4471         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4472                 hf |= BWN_HF_BT_COEXISTALT;
4473         else
4474                 hf |= BWN_HF_BT_COEXIST;
4475         bwn_hf_write(mac, hf);
4476 }
4477
4478 static void
4479 bwn_set_macaddr(struct bwn_mac *mac)
4480 {
4481
4482         bwn_mac_write_bssid(mac);
4483         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4484 }
4485
4486 static void
4487 bwn_clear_keys(struct bwn_mac *mac)
4488 {
4489         int i;
4490
4491         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4492                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4493                     ("%s:%d: fail", __func__, __LINE__));
4494
4495                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4496                     NULL, BWN_SEC_KEYSIZE, NULL);
4497                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4498                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4499                             NULL, BWN_SEC_KEYSIZE, NULL);
4500                 }
4501                 mac->mac_key[i].keyconf = NULL;
4502         }
4503 }
4504
4505 static void
4506 bwn_crypt_init(struct bwn_mac *mac)
4507 {
4508         struct bwn_softc *sc = mac->mac_sc;
4509
4510         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4511         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4512             ("%s:%d: fail", __func__, __LINE__));
4513         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4514         mac->mac_ktp *= 2;
4515         if (siba_get_revid(sc->sc_dev) >= 5)
4516                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4517         bwn_clear_keys(mac);
4518 }
4519
4520 static void
4521 bwn_chip_exit(struct bwn_mac *mac)
4522 {
4523         struct bwn_softc *sc = mac->mac_sc;
4524
4525         bwn_phy_exit(mac);
4526         siba_gpio_set(sc->sc_dev, 0);
4527 }
4528
4529 static int
4530 bwn_fw_fillinfo(struct bwn_mac *mac)
4531 {
4532         int error;
4533
4534         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4535         if (error == 0)
4536                 return (0);
4537         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4538         if (error == 0)
4539                 return (0);
4540         return (error);
4541 }
4542
4543 static int
4544 bwn_gpio_init(struct bwn_mac *mac)
4545 {
4546         struct bwn_softc *sc = mac->mac_sc;
4547         uint32_t mask = 0x1f, set = 0xf, value;
4548
4549         BWN_WRITE_4(mac, BWN_MACCTL,
4550             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4551         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4552             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4553
4554         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4555                 mask |= 0x0060;
4556                 set |= 0x0060;
4557         }
4558         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4559                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4560                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4561                 mask |= 0x0200;
4562                 set |= 0x0200;
4563         }
4564         if (siba_get_revid(sc->sc_dev) >= 2)
4565                 mask |= 0x0010;
4566
4567         value = siba_gpio_get(sc->sc_dev);
4568         if (value == -1)
4569                 return (0);
4570         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4571
4572         return (0);
4573 }
4574
4575 static int
4576 bwn_fw_loadinitvals(struct bwn_mac *mac)
4577 {
4578 #define GETFWOFFSET(fwp, offset)                                \
4579         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4580         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4581         const struct bwn_fwhdr *hdr;
4582         struct bwn_fw *fw = &mac->mac_fw;
4583         int error;
4584
4585         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4586         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4587             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4588         if (error)
4589                 return (error);
4590         if (fw->initvals_band.fw) {
4591                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4592                 error = bwn_fwinitvals_write(mac,
4593                     GETFWOFFSET(fw->initvals_band, hdr_len),
4594                     be32toh(hdr->size),
4595                     fw->initvals_band.fw->datasize - hdr_len);
4596         }
4597         return (error);
4598 #undef GETFWOFFSET
4599 }
4600
4601 static int
4602 bwn_phy_init(struct bwn_mac *mac)
4603 {
4604         struct bwn_softc *sc = mac->mac_sc;
4605         int error;
4606
4607         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4608         mac->mac_phy.rf_onoff(mac, 1);
4609         error = mac->mac_phy.init(mac);
4610         if (error) {
4611                 device_printf(sc->sc_dev, "PHY init failed\n");
4612                 goto fail0;
4613         }
4614         error = bwn_switch_channel(mac,
4615             mac->mac_phy.get_default_chan(mac));
4616         if (error) {
4617                 device_printf(sc->sc_dev,
4618                     "failed to switch default channel\n");
4619                 goto fail1;
4620         }
4621         return (0);
4622 fail1:
4623         if (mac->mac_phy.exit)
4624                 mac->mac_phy.exit(mac);
4625 fail0:
4626         mac->mac_phy.rf_onoff(mac, 0);
4627
4628         return (error);
4629 }
4630
4631 static void
4632 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4633 {
4634         uint16_t ant;
4635         uint16_t tmp;
4636
4637         ant = bwn_ant2phy(antenna);
4638
4639         /* For ACK/CTS */
4640         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4641         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4642         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4643         /* For Probe Resposes */
4644         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4645         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4646         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4647 }
4648
4649 static void
4650 bwn_set_opmode(struct bwn_mac *mac)
4651 {
4652         struct bwn_softc *sc = mac->mac_sc;
4653         struct ifnet *ifp = sc->sc_ifp;
4654         struct ieee80211com *ic = ifp->if_l2com;
4655         uint32_t ctl;
4656         uint16_t cfp_pretbtt;
4657
4658         ctl = BWN_READ_4(mac, BWN_MACCTL);
4659         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4660             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4661             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4662         ctl |= BWN_MACCTL_STA;
4663
4664         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4665             ic->ic_opmode == IEEE80211_M_MBSS)
4666                 ctl |= BWN_MACCTL_HOSTAP;
4667         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4668                 ctl &= ~BWN_MACCTL_STA;
4669         ctl |= sc->sc_filters;
4670
4671         if (siba_get_revid(sc->sc_dev) <= 4)
4672                 ctl |= BWN_MACCTL_PROMISC;
4673
4674         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4675
4676         cfp_pretbtt = 2;
4677         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4678                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4679                     siba_get_chiprev(sc->sc_dev) == 3)
4680                         cfp_pretbtt = 100;
4681                 else
4682                         cfp_pretbtt = 50;
4683         }
4684         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4685 }
4686
4687 static int
4688 bwn_dma_gettype(struct bwn_mac *mac)
4689 {
4690         uint32_t tmp;
4691         uint16_t base;
4692
4693         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4694         if (tmp & SIBA_TGSHIGH_DMA64)
4695                 return (BWN_DMA_64BIT);
4696         base = bwn_dma_base(0, 0);
4697         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4698         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4699         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4700                 return (BWN_DMA_32BIT);
4701
4702         return (BWN_DMA_30BIT);
4703 }
4704
4705 static void
4706 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4707 {
4708         if (!error) {
4709                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4710                 *((bus_addr_t *)arg) = seg->ds_addr;
4711         }
4712 }
4713
4714 static void
4715 bwn_phy_g_init_sub(struct bwn_mac *mac)
4716 {
4717         struct bwn_phy *phy = &mac->mac_phy;
4718         struct bwn_phy_g *pg = &phy->phy_g;
4719         struct bwn_softc *sc = mac->mac_sc;
4720         uint16_t i, tmp;
4721
4722         if (phy->rev == 1)
4723                 bwn_phy_init_b5(mac);
4724         else
4725                 bwn_phy_init_b6(mac);
4726
4727         if (phy->rev >= 2 || phy->gmode)
4728                 bwn_phy_init_a(mac);
4729
4730         if (phy->rev >= 2) {
4731                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4732                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4733         }
4734         if (phy->rev == 2) {
4735                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4736                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4737         }
4738         if (phy->rev > 5) {
4739                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4740                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4741         }
4742         if (phy->gmode || phy->rev >= 2) {
4743                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4744                 tmp &= BWN_PHYVER_VERSION;
4745                 if (tmp == 3 || tmp == 5) {
4746                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4747                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4748                 }
4749                 if (tmp == 5) {
4750                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4751                             0x1f00);
4752                 }
4753         }
4754         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4755                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4756         if (phy->rf_rev == 8) {
4757                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4758                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4759         }
4760         if (BWN_HAS_LOOPBACK(phy))
4761                 bwn_loopback_calcgain(mac);
4762
4763         if (phy->rf_rev != 8) {
4764                 if (pg->pg_initval == 0xffff)
4765                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4766                 else
4767                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4768         }
4769         bwn_lo_g_init(mac);
4770         if (BWN_HAS_TXMAG(phy)) {
4771                 BWN_RF_WRITE(mac, 0x52,
4772                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4773                     | pg->pg_loctl.tx_bias |
4774                     pg->pg_loctl.tx_magn);
4775         } else {
4776                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4777         }
4778         if (phy->rev >= 6) {
4779                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4780                     (pg->pg_loctl.tx_bias << 12));
4781         }
4782         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4783                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4784         else
4785                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4786         if (phy->rev < 2)
4787                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4788         else
4789                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4790         if (phy->gmode || phy->rev >= 2) {
4791                 bwn_lo_g_adjust(mac);
4792                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4793         }
4794
4795         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4796                 for (i = 0; i < 64; i++) {
4797                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4798                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4799                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4800                             -32), 31));
4801                 }
4802                 bwn_nrssi_threshold(mac);
4803         } else if (phy->gmode || phy->rev >= 2) {
4804                 if (pg->pg_nrssi[0] == -1000) {
4805                         KASSERT(pg->pg_nrssi[1] == -1000,
4806                             ("%s:%d: fail", __func__, __LINE__));
4807                         bwn_nrssi_slope_11g(mac);
4808                 } else
4809                         bwn_nrssi_threshold(mac);
4810         }
4811         if (phy->rf_rev == 8)
4812                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4813         bwn_phy_hwpctl_init(mac);
4814         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4815              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4816                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4817                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4818         }
4819 }
4820
4821 static uint8_t
4822 bwn_has_hwpctl(struct bwn_mac *mac)
4823 {
4824
4825         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4826                 return (0);
4827         return (mac->mac_phy.use_hwpctl(mac));
4828 }
4829
4830 static void
4831 bwn_phy_init_b5(struct bwn_mac *mac)
4832 {
4833         struct bwn_phy *phy = &mac->mac_phy;
4834         struct bwn_phy_g *pg = &phy->phy_g;
4835         struct bwn_softc *sc = mac->mac_sc;
4836         uint16_t offset, value;
4837         uint8_t old_channel;
4838
4839         if (phy->analog == 1)
4840                 BWN_RF_SET(mac, 0x007a, 0x0050);
4841         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4842             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4843                 value = 0x2120;
4844                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4845                         BWN_PHY_WRITE(mac, offset, value);
4846                         value += 0x202;
4847                 }
4848         }
4849         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4850         if (phy->rf_ver == 0x2050)
4851                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4852
4853         if (phy->gmode || phy->rev >= 2) {
4854                 if (phy->rf_ver == 0x2050) {
4855                         BWN_RF_SET(mac, 0x007a, 0x0020);
4856                         BWN_RF_SET(mac, 0x0051, 0x0004);
4857                 }
4858                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4859
4860                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4861                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4862
4863                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4864
4865                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4866                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4867                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4868         }
4869
4870         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4871                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4872
4873         if (phy->analog == 1) {
4874                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4875                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4876                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4877                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4878                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4879         } else
4880                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4881         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4882         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4883
4884         if (phy->analog == 1)
4885                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4886         else
4887                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4888
4889         if (phy->analog == 0)
4890                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4891
4892         old_channel = phy->chan;
4893         bwn_phy_g_switch_chan(mac, 7, 0);
4894
4895         if (phy->rf_ver != 0x2050) {
4896                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4897                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4898         }
4899
4900         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4901         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4902
4903         if (phy->rf_ver == 0x2050) {
4904                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4905                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4906         }
4907
4908         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4909         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4910         BWN_RF_SET(mac, 0x007a, 0x0007);
4911
4912         bwn_phy_g_switch_chan(mac, old_channel, 0);
4913         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4914         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4915         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4916
4917         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4918             pg->pg_txctl);
4919
4920         if (phy->rf_ver == 0x2050)
4921                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4922
4923         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4924 }
4925
4926 static void
4927 bwn_loopback_calcgain(struct bwn_mac *mac)
4928 {
4929         struct bwn_phy *phy = &mac->mac_phy;
4930         struct bwn_phy_g *pg = &phy->phy_g;
4931         struct bwn_softc *sc = mac->mac_sc;
4932         uint16_t backup_phy[16] = { 0 };
4933         uint16_t backup_radio[3];
4934         uint16_t backup_bband;
4935         uint16_t i, j, loop_i_max;
4936         uint16_t trsw_rx;
4937         uint16_t loop1_outer_done, loop1_inner_done;
4938
4939         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4940         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4941         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4942         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4943         if (phy->rev != 1) {
4944                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4945                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4946         }
4947         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4948         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4949         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4950         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4951         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4952         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4953         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4954         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4955         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4956         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4957         backup_bband = pg->pg_bbatt.att;
4958         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4959         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4960         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4961
4962         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4963         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4964         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4965         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4966         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4967         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4968         if (phy->rev != 1) {
4969                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4970                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4971                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4972                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4973         }
4974         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4975         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4976         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4977         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4978
4979         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4980         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4981         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4982
4983         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4984         if (phy->rev != 1) {
4985                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4986                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4987         }
4988         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4989
4990         if (phy->rf_rev == 8)
4991                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4992         else {
4993                 BWN_RF_WRITE(mac, 0x52, 0);
4994                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4995         }
4996         bwn_phy_g_set_bbatt(mac, 11);
4997
4998         if (phy->rev >= 3)
4999                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5000         else
5001                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5002         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5003
5004         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5005         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5006
5007         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5008         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5009
5010         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5011                 if (phy->rev >= 7) {
5012                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5013                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5014                 }
5015         }
5016         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5017
5018         j = 0;
5019         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5020         for (i = 0; i < loop_i_max; i++) {
5021                 for (j = 0; j < 16; j++) {
5022                         BWN_RF_WRITE(mac, 0x43, i);
5023                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5024                             (j << 8));
5025                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5026                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5027                         DELAY(20);
5028                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5029                                 goto done0;
5030                 }
5031         }
5032 done0:
5033         loop1_outer_done = i;
5034         loop1_inner_done = j;
5035         if (j >= 8) {
5036                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5037                 trsw_rx = 0x1b;
5038                 for (j = j - 8; j < 16; j++) {
5039                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5040                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5041                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5042                         DELAY(20);
5043                         trsw_rx -= 3;
5044                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5045                                 goto done1;
5046                 }
5047         } else
5048                 trsw_rx = 0x18;
5049 done1:
5050
5051         if (phy->rev != 1) {
5052                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5053                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5054         }
5055         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5056         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5057         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5058         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5059         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5060         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5061         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5062         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5063         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5064
5065         bwn_phy_g_set_bbatt(mac, backup_bband);
5066
5067         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5068         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5069         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5070
5071         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5072         DELAY(10);
5073         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5074         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5075         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5076         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5077
5078         pg->pg_max_lb_gain =
5079             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5080         pg->pg_trsw_rx_gain = trsw_rx * 2;
5081 }
5082
5083 static uint16_t
5084 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5085 {
5086         struct bwn_phy *phy = &mac->mac_phy;
5087         uint32_t tmp1 = 0, tmp2 = 0;
5088         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5089             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5090             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5091         static const uint8_t rcc_table[] = {
5092                 0x02, 0x03, 0x01, 0x0f,
5093                 0x06, 0x07, 0x05, 0x0f,
5094                 0x0a, 0x0b, 0x09, 0x0f,
5095                 0x0e, 0x0f, 0x0d, 0x0f,
5096         };
5097
5098         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5099             rfoverval = rfover = cck3 = 0;
5100         radio0 = BWN_RF_READ(mac, 0x43);
5101         radio1 = BWN_RF_READ(mac, 0x51);
5102         radio2 = BWN_RF_READ(mac, 0x52);
5103         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5104         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5105         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5106         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5107
5108         if (phy->type == BWN_PHYTYPE_B) {
5109                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5110                 reg0 = BWN_READ_2(mac, 0x3ec);
5111
5112                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5113                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5114         } else if (phy->gmode || phy->rev >= 2) {
5115                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5116                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5117                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5118                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5119                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5120                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5121
5122                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5123                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5124                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5125                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5126                 if (BWN_HAS_LOOPBACK(phy)) {
5127                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5128                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5129                         if (phy->rev >= 3)
5130                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5131                         else
5132                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5133                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5134                 }
5135
5136                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5137                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5138                         BWN_LPD(0, 1, 1)));
5139                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5140                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5141         }
5142         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5143
5144         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5145         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5146         reg1 = BWN_READ_2(mac, 0x3e6);
5147         reg2 = BWN_READ_2(mac, 0x3f4);
5148
5149         if (phy->analog == 0)
5150                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5151         else {
5152                 if (phy->analog >= 2)
5153                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5154                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5155                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5156         }
5157
5158         reg = BWN_RF_READ(mac, 0x60);
5159         index = (reg & 0x001e) >> 1;
5160         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5161
5162         if (phy->type == BWN_PHYTYPE_B)
5163                 BWN_RF_WRITE(mac, 0x78, 0x26);
5164         if (phy->gmode || phy->rev >= 2) {
5165                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5166                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5167                         BWN_LPD(0, 1, 1)));
5168         }
5169         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5170         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5171         if (phy->gmode || phy->rev >= 2) {
5172                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5173                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5174                         BWN_LPD(0, 0, 1)));
5175         }
5176         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5177         BWN_RF_SET(mac, 0x51, 0x0004);
5178         if (phy->rf_rev == 8)
5179                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5180         else {
5181                 BWN_RF_WRITE(mac, 0x52, 0);
5182                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5183         }
5184         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5185
5186         for (i = 0; i < 16; i++) {
5187                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5188                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5189                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5190                 if (phy->gmode || phy->rev >= 2) {
5191                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5192                             bwn_rf_2050_rfoverval(mac,
5193                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5194                 }
5195                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5196                 DELAY(10);
5197                 if (phy->gmode || phy->rev >= 2) {
5198                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5199                             bwn_rf_2050_rfoverval(mac,
5200                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5201                 }
5202                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5203                 DELAY(10);
5204                 if (phy->gmode || phy->rev >= 2) {
5205                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5206                             bwn_rf_2050_rfoverval(mac,
5207                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5208                 }
5209                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5210                 DELAY(20);
5211                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5212                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5213                 if (phy->gmode || phy->rev >= 2) {
5214                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5215                             bwn_rf_2050_rfoverval(mac,
5216                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5217                 }
5218                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5219         }
5220         DELAY(10);
5221
5222         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5223         tmp1++;
5224         tmp1 >>= 9;
5225
5226         for (i = 0; i < 16; i++) {
5227                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5228                 BWN_RF_WRITE(mac, 0x78, radio78);
5229                 DELAY(10);
5230                 for (j = 0; j < 16; j++) {
5231                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5232                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5233                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5234                         if (phy->gmode || phy->rev >= 2) {
5235                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5236                                     bwn_rf_2050_rfoverval(mac,
5237                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5238                         }
5239                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5240                         DELAY(10);
5241                         if (phy->gmode || phy->rev >= 2) {
5242                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5243                                     bwn_rf_2050_rfoverval(mac,
5244                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5245                         }
5246                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5247                         DELAY(10);
5248                         if (phy->gmode || phy->rev >= 2) {
5249                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5250                                     bwn_rf_2050_rfoverval(mac,
5251                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5252                         }
5253                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5254                         DELAY(10);
5255                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5256                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5257                         if (phy->gmode || phy->rev >= 2) {
5258                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5259                                     bwn_rf_2050_rfoverval(mac,
5260                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5261                         }
5262                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5263                 }
5264                 tmp2++;
5265                 tmp2 >>= 8;
5266                 if (tmp1 < tmp2)
5267                         break;
5268         }
5269
5270         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5271         BWN_RF_WRITE(mac, 0x51, radio1);
5272         BWN_RF_WRITE(mac, 0x52, radio2);
5273         BWN_RF_WRITE(mac, 0x43, radio0);
5274         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5275         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5276         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5277         BWN_WRITE_2(mac, 0x3e6, reg1);
5278         if (phy->analog != 0)
5279                 BWN_WRITE_2(mac, 0x3f4, reg2);
5280         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5281         bwn_spu_workaround(mac, phy->chan);
5282         if (phy->type == BWN_PHYTYPE_B) {
5283                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5284                 BWN_WRITE_2(mac, 0x3ec, reg0);
5285         } else if (phy->gmode) {
5286                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5287                             BWN_READ_2(mac, BWN_PHY_RADIO)
5288                             & 0x7fff);
5289                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5290                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5291                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5292                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5293                               analogoverval);
5294                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5295                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5296                 if (BWN_HAS_LOOPBACK(phy)) {
5297                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5298                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5299                 }
5300         }
5301
5302         return ((i > 15) ? radio78 : rcc);
5303 }
5304
5305 static void
5306 bwn_phy_init_b6(struct bwn_mac *mac)
5307 {
5308         struct bwn_phy *phy = &mac->mac_phy;
5309         struct bwn_phy_g *pg = &phy->phy_g;
5310         struct bwn_softc *sc = mac->mac_sc;
5311         uint16_t offset, val;
5312         uint8_t old_channel;
5313
5314         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5315             ("%s:%d: fail", __func__, __LINE__));
5316
5317         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5318         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5319         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5320                 BWN_RF_WRITE(mac, 0x51, 0x37);
5321                 BWN_RF_WRITE(mac, 0x52, 0x70);
5322                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5323                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5324                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5325                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5326                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5327                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5328                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5329                 bwn_hf_write(mac,
5330                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5331         }
5332         if (phy->rf_rev == 8) {
5333                 BWN_RF_WRITE(mac, 0x51, 0);
5334                 BWN_RF_WRITE(mac, 0x52, 0x40);
5335                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5336                 BWN_RF_WRITE(mac, 0x54, 0x98);
5337                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5338                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5339                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5340                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5341                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5342                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5343                 } else {
5344                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5345                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5346                 }
5347                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5348                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5349                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5350                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5351         }
5352         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5353                 BWN_PHY_WRITE(mac, offset, val);
5354                 val -= 0x0202;
5355         }
5356         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5357                 BWN_PHY_WRITE(mac, offset, val);
5358                 val -= 0x0202;
5359         }
5360         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5361                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5362                 val += 0x0202;
5363         }
5364         if (phy->type == BWN_PHYTYPE_G) {
5365                 BWN_RF_SET(mac, 0x007a, 0x0020);
5366                 BWN_RF_SET(mac, 0x0051, 0x0004);
5367                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5368                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5369                 BWN_PHY_WRITE(mac, 0x5b, 0);
5370                 BWN_PHY_WRITE(mac, 0x5c, 0);
5371         }
5372
5373         old_channel = phy->chan;
5374         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5375
5376         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5377         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5378         DELAY(40);
5379         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5380                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5381                 BWN_RF_WRITE(mac, 0x50, 0x20);
5382         }
5383         if (phy->rf_rev <= 2) {
5384                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5385                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5386                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5387                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5388         }
5389         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5390
5391         bwn_phy_g_switch_chan(mac, old_channel, 0);
5392
5393         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5394         if (phy->rf_rev >= 6)
5395                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5396         else
5397                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5398         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5399         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5400             pg->pg_txctl);
5401         if (phy->rf_rev <= 5)
5402                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5403         if (phy->rf_rev <= 2)
5404                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5405
5406         if (phy->analog == 4) {
5407                 BWN_WRITE_2(mac, 0x3e4, 9);
5408                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5409         } else
5410                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5411         if (phy->type == BWN_PHYTYPE_B)
5412                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5413         else if (phy->type == BWN_PHYTYPE_G)
5414                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5415 }
5416
5417 static void
5418 bwn_phy_init_a(struct bwn_mac *mac)
5419 {
5420         struct bwn_phy *phy = &mac->mac_phy;
5421         struct bwn_softc *sc = mac->mac_sc;
5422
5423         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5424             ("%s:%d: fail", __func__, __LINE__));
5425
5426         if (phy->rev >= 6) {
5427                 if (phy->type == BWN_PHYTYPE_A)
5428                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5429                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5430                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5431                 else
5432                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5433         }
5434
5435         bwn_wa_init(mac);
5436
5437         if (phy->type == BWN_PHYTYPE_G &&
5438             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5439                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5440 }
5441
5442 static void
5443 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5444 {
5445         int i;
5446
5447         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5448                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5449 }
5450
5451 static void
5452 bwn_wa_agc(struct bwn_mac *mac)
5453 {
5454         struct bwn_phy *phy = &mac->mac_phy;
5455
5456         if (phy->rev == 1) {
5457                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5458                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5460                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5461                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5462                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5463                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5464                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5465                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5466         } else {
5467                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5468                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5469                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5470                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5471         }
5472
5473         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5474             0x5700);
5475         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5476         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5477         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5478         BWN_RF_SET(mac, 0x7a, 0x0008);
5479         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5480         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5481         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5482         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5483         if (phy->rev == 1)
5484                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5485         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5486         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5487         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5488         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5491         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5492         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5493         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5494         if (phy->rev == 1) {
5495                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5496                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5497         } else {
5498                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5499                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5500                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5501                 if (phy->rev >= 6) {
5502                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5503                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5504                             (uint16_t)~0xf000, 0x3000);
5505                 }
5506         }
5507         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5508         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5509         if (phy->rev == 1) {
5510                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5511                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5512                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5513                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5514                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5515                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5516                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5517                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5518         } else {
5519                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5520                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5521                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5522                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5523         }
5524         if (phy->rev >= 6) {
5525                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5526                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5527         }
5528         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5529 }
5530
5531 static void
5532 bwn_wa_grev1(struct bwn_mac *mac)
5533 {
5534         struct bwn_phy *phy = &mac->mac_phy;
5535         int i;
5536         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5537         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5538         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5539
5540         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5541
5542         /* init CRSTHRES and ANTDWELL */
5543         if (phy->rev == 1) {
5544                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5545         } else if (phy->rev == 2) {
5546                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5547                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5548                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5549         } else {
5550                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5551                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5552                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5553                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5554         }
5555         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5556         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5557         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5558
5559         /* XXX support PHY-A??? */
5560         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5561                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5562                     bwn_tab_finefreqg[i]);
5563
5564         /* XXX support PHY-A??? */
5565         if (phy->rev == 1)
5566                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5567                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5568                             bwn_tab_noise_g1[i]);
5569         else
5570                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5571                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5572                             bwn_tab_noise_g2[i]);
5573
5574
5575         for (i = 0; i < N(bwn_tab_rotor); i++)
5576                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5577                     bwn_tab_rotor[i]);
5578
5579         /* XXX support PHY-A??? */
5580         if (phy->rev >= 6) {
5581                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5582                     BWN_PHY_ENCORE_EN)
5583                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5584                 else
5585                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5586         } else
5587                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5588
5589         for (i = 0; i < N(bwn_tab_retard); i++)
5590                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5591                     bwn_tab_retard[i]);
5592
5593         if (phy->rev == 1) {
5594                 for (i = 0; i < 16; i++)
5595                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5596                             i, 0x0020);
5597         } else {
5598                 for (i = 0; i < 32; i++)
5599                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5600         }
5601
5602         bwn_wa_agc(mac);
5603 }
5604
5605 static void
5606 bwn_wa_grev26789(struct bwn_mac *mac)
5607 {
5608         struct bwn_phy *phy = &mac->mac_phy;
5609         int i;
5610         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5611         uint16_t ofdmrev;
5612
5613         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5614
5615         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5616
5617         /* init CRSTHRES and ANTDWELL */
5618         if (phy->rev == 1)
5619                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5620         else if (phy->rev == 2) {
5621                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5622                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5623                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5624         } else {
5625                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5626                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5627                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5628                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5629         }
5630
5631         for (i = 0; i < 64; i++)
5632                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5633
5634         /* XXX support PHY-A??? */
5635         if (phy->rev == 1)
5636                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5637                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5638                             bwn_tab_noise_g1[i]);
5639         else
5640                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5641                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5642                             bwn_tab_noise_g2[i]);
5643
5644         /* XXX support PHY-A??? */
5645         if (phy->rev >= 6) {
5646                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5647                     BWN_PHY_ENCORE_EN)
5648                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5649                 else
5650                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5651         } else
5652                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5653
5654         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5655                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5656                     bwn_tab_sigmasqr2[i]);
5657
5658         if (phy->rev == 1) {
5659                 for (i = 0; i < 16; i++)
5660                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5661                             0x0020);
5662         } else {
5663                 for (i = 0; i < 32; i++)
5664                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5665         }
5666
5667         bwn_wa_agc(mac);
5668
5669         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5670         if (ofdmrev > 2) {
5671                 if (phy->type == BWN_PHYTYPE_A)
5672                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5673                 else
5674                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5675         } else {
5676                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5677                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5678                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5679         }
5680
5681         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5682         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5683 }
5684
5685 static void
5686 bwn_wa_init(struct bwn_mac *mac)
5687 {
5688         struct bwn_phy *phy = &mac->mac_phy;
5689         struct bwn_softc *sc = mac->mac_sc;
5690
5691         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5692
5693         switch (phy->rev) {
5694         case 1:
5695                 bwn_wa_grev1(mac);
5696                 break;
5697         case 2:
5698         case 6:
5699         case 7:
5700         case 8:
5701         case 9:
5702                 bwn_wa_grev26789(mac);
5703                 break;
5704         default:
5705                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5706         }
5707
5708         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5709             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5710             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5711                 if (phy->rev < 2) {
5712                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5713                             0x0002);
5714                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5715                             0x0001);
5716                 } else {
5717                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5718                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5719                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5720                              BWN_BFL_EXTLNA) &&
5721                             (phy->rev >= 7)) {
5722                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5723                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5724                                     0x0020, 0x0001);
5725                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5726                                     0x0021, 0x0001);
5727                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5728                                     0x0022, 0x0001);
5729                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5730                                     0x0023, 0x0000);
5731                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5732                                     0x0000, 0x0000);
5733                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5734                                     0x0003, 0x0002);
5735                         }
5736                 }
5737         }
5738         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5739                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5740                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5741         }
5742
5743         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5744         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5745 }
5746
5747 static void
5748 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5749     uint16_t value)
5750 {
5751         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5752         uint16_t addr;
5753
5754         addr = table + offset;
5755         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5756             (addr - 1 != pg->pg_ofdmtab_addr)) {
5757                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5758                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5759         }
5760         pg->pg_ofdmtab_addr = addr;
5761         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5762 }
5763
5764 static void
5765 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5766     uint32_t value)
5767 {
5768         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5769         uint16_t addr;
5770
5771         addr = table + offset;
5772         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5773             (addr - 1 != pg->pg_ofdmtab_addr)) {
5774                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5775                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5776         }
5777         pg->pg_ofdmtab_addr = addr;
5778
5779         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5780         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5781 }
5782
5783 static void
5784 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5785     uint16_t value)
5786 {
5787
5788         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5789         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5790 }
5791
5792 static void
5793 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5794 {
5795         struct bwn_phy *phy = &mac->mac_phy;
5796         struct bwn_softc *sc = mac->mac_sc;
5797         unsigned int i, max_loop;
5798         uint16_t value;
5799         uint32_t buffer[5] = {
5800                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5801         };
5802
5803         if (ofdm) {
5804                 max_loop = 0x1e;
5805                 buffer[0] = 0x000201cc;
5806         } else {
5807                 max_loop = 0xfa;
5808                 buffer[0] = 0x000b846e;
5809         }
5810
5811         BWN_ASSERT_LOCKED(mac->mac_sc);
5812
5813         for (i = 0; i < 5; i++)
5814                 bwn_ram_write(mac, i * 4, buffer[i]);
5815
5816         BWN_WRITE_2(mac, 0x0568, 0x0000);
5817         BWN_WRITE_2(mac, 0x07c0,
5818             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5819         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5820         BWN_WRITE_2(mac, 0x050c, value);
5821         if (phy->type == BWN_PHYTYPE_LP)
5822                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5823         BWN_WRITE_2(mac, 0x0508, 0x0000);
5824         BWN_WRITE_2(mac, 0x050a, 0x0000);
5825         BWN_WRITE_2(mac, 0x054c, 0x0000);
5826         BWN_WRITE_2(mac, 0x056a, 0x0014);
5827         BWN_WRITE_2(mac, 0x0568, 0x0826);
5828         BWN_WRITE_2(mac, 0x0500, 0x0000);
5829         if (phy->type == BWN_PHYTYPE_LP)
5830                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5831         else
5832                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5833
5834         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5835                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5836         for (i = 0x00; i < max_loop; i++) {
5837                 value = BWN_READ_2(mac, 0x050e);
5838                 if (value & 0x0080)
5839                         break;
5840                 DELAY(10);
5841         }
5842         for (i = 0x00; i < 0x0a; i++) {
5843                 value = BWN_READ_2(mac, 0x050e);
5844                 if (value & 0x0400)
5845                         break;
5846                 DELAY(10);
5847         }
5848         for (i = 0x00; i < 0x19; i++) {
5849                 value = BWN_READ_2(mac, 0x0690);
5850                 if (!(value & 0x0100))
5851                         break;
5852                 DELAY(10);
5853         }
5854         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5855                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5856 }
5857
5858 static void
5859 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5860 {
5861         uint32_t macctl;
5862
5863         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5864
5865         macctl = BWN_READ_4(mac, BWN_MACCTL);
5866         if (macctl & BWN_MACCTL_BIGENDIAN)
5867                 printf("TODO: need swap\n");
5868
5869         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5870         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5871         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5872 }
5873
5874 static void
5875 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5876 {
5877         uint16_t value;
5878
5879         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5880             ("%s:%d: fail", __func__, __LINE__));
5881
5882         value = (uint8_t) (ctl->q);
5883         value |= ((uint8_t) (ctl->i)) << 8;
5884         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5885 }
5886
5887 static uint16_t
5888 bwn_lo_calcfeed(struct bwn_mac *mac,
5889     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5890 {
5891         struct bwn_phy *phy = &mac->mac_phy;
5892         struct bwn_softc *sc = mac->mac_sc;
5893         uint16_t rfover;
5894         uint16_t feedthrough;
5895
5896         if (phy->gmode) {
5897                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5898                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5899
5900                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5901                     ("%s:%d: fail", __func__, __LINE__));
5902                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5903                     ("%s:%d: fail", __func__, __LINE__));
5904
5905                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5906
5907                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5908                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5909                     phy->rev > 6)
5910                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5911
5912                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5913                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5914                 DELAY(10);
5915                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5916                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5917                 DELAY(10);
5918                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5919                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5920                 DELAY(10);
5921                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5922         } else {
5923                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5924                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5925                 DELAY(10);
5926                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5927                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5928                 DELAY(10);
5929                 pga |= BWN_PHY_PGACTL_LPF;
5930                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5931         }
5932         DELAY(21);
5933         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5934
5935         return (feedthrough);
5936 }
5937
5938 static uint16_t
5939 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5940     uint16_t *value, uint16_t *pad_mix_gain)
5941 {
5942         struct bwn_phy *phy = &mac->mac_phy;
5943         uint16_t reg, v, padmix;
5944
5945         if (phy->type == BWN_PHYTYPE_B) {
5946                 v = 0x30;
5947                 if (phy->rf_rev <= 5) {
5948                         reg = 0x43;
5949                         padmix = 0;
5950                 } else {
5951                         reg = 0x52;
5952                         padmix = 5;
5953                 }
5954         } else {
5955                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5956                         reg = 0x43;
5957                         v = 0x10;
5958                         padmix = 2;
5959                 } else {
5960                         reg = 0x52;
5961                         v = 0x30;
5962                         padmix = 5;
5963                 }
5964         }
5965         if (value)
5966                 *value = v;
5967         if (pad_mix_gain)
5968                 *pad_mix_gain = padmix;
5969
5970         return (reg);
5971 }
5972
5973 static void
5974 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5975 {
5976         struct bwn_phy *phy = &mac->mac_phy;
5977         struct bwn_phy_g *pg = &phy->phy_g;
5978         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5979         uint16_t reg, mask;
5980         uint16_t trsw_rx, pga;
5981         uint16_t rf_pctl_reg;
5982
5983         static const uint8_t tx_bias_values[] = {
5984                 0x09, 0x08, 0x0a, 0x01, 0x00,
5985                 0x02, 0x05, 0x04, 0x06,
5986         };
5987         static const uint8_t tx_magn_values[] = {
5988                 0x70, 0x40,
5989         };
5990
5991         if (!BWN_HAS_LOOPBACK(phy)) {
5992                 rf_pctl_reg = 6;
5993                 trsw_rx = 2;
5994                 pga = 0;
5995         } else {
5996                 int lb_gain;
5997
5998                 trsw_rx = 0;
5999                 lb_gain = pg->pg_max_lb_gain / 2;
6000                 if (lb_gain > 10) {
6001                         rf_pctl_reg = 0;
6002                         pga = abs(10 - lb_gain) / 6;
6003                         pga = MIN(MAX(pga, 0), 15);
6004                 } else {
6005                         int cmp_val;
6006                         int tmp;
6007
6008                         pga = 0;
6009                         cmp_val = 0x24;
6010                         if ((phy->rev >= 2) &&
6011                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6012                                 cmp_val = 0x3c;
6013                         tmp = lb_gain;
6014                         if ((10 - lb_gain) < cmp_val)
6015                                 tmp = (10 - lb_gain);
6016                         if (tmp < 0)
6017                                 tmp += 6;
6018                         else
6019                                 tmp += 3;
6020                         cmp_val /= 4;
6021                         tmp /= 4;
6022                         if (tmp >= cmp_val)
6023                                 rf_pctl_reg = cmp_val;
6024                         else
6025                                 rf_pctl_reg = tmp;
6026                 }
6027         }
6028         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6029         bwn_phy_g_set_bbatt(mac, 2);
6030
6031         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6032         mask = ~mask;
6033         BWN_RF_MASK(mac, reg, mask);
6034
6035         if (BWN_HAS_TXMAG(phy)) {
6036                 int i, j;
6037                 int feedthrough;
6038                 int min_feedth = 0xffff;
6039                 uint8_t tx_magn, tx_bias;
6040
6041                 for (i = 0; i < N(tx_magn_values); i++) {
6042                         tx_magn = tx_magn_values[i];
6043                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6044                         for (j = 0; j < N(tx_bias_values); j++) {
6045                                 tx_bias = tx_bias_values[j];
6046                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6047                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6048                                     trsw_rx);
6049                                 if (feedthrough < min_feedth) {
6050                                         lo->tx_bias = tx_bias;
6051                                         lo->tx_magn = tx_magn;
6052                                         min_feedth = feedthrough;
6053                                 }
6054                                 if (lo->tx_bias == 0)
6055                                         break;
6056                         }
6057                         BWN_RF_WRITE(mac, 0x52,
6058                                           (BWN_RF_READ(mac, 0x52)
6059                                            & 0xff00) | lo->tx_bias | lo->
6060                                           tx_magn);
6061                 }
6062         } else {
6063                 lo->tx_magn = 0;
6064                 lo->tx_bias = 0;
6065                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6066         }
6067
6068         BWN_GETTIME(lo->txctl_measured_time);
6069 }
6070
6071 static void
6072 bwn_lo_get_powervector(struct bwn_mac *mac)
6073 {
6074         struct bwn_phy *phy = &mac->mac_phy;
6075         struct bwn_phy_g *pg = &phy->phy_g;
6076         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6077         int i;
6078         uint64_t tmp;
6079         uint64_t power_vector = 0;
6080
6081         for (i = 0; i < 8; i += 2) {
6082                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6083                 power_vector |= (tmp << (i * 8));
6084                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6085         }
6086         if (power_vector)
6087                 lo->power_vector = power_vector;
6088
6089         BWN_GETTIME(lo->pwr_vec_read_time);
6090 }
6091
6092 static void
6093 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6094     int use_trsw_rx)
6095 {
6096         struct bwn_phy *phy = &mac->mac_phy;
6097         struct bwn_phy_g *pg = &phy->phy_g;
6098         uint16_t tmp;
6099
6100         if (max_rx_gain < 0)
6101                 max_rx_gain = 0;
6102
6103         if (BWN_HAS_LOOPBACK(phy)) {
6104                 int trsw_rx = 0;
6105                 int trsw_rx_gain;
6106
6107                 if (use_trsw_rx) {
6108                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6109                         if (max_rx_gain >= trsw_rx_gain) {
6110                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6111                                 trsw_rx = 0x20;
6112                         }
6113                 } else
6114                         trsw_rx_gain = max_rx_gain;
6115                 if (trsw_rx_gain < 9) {
6116                         pg->pg_lna_lod_gain = 0;
6117                 } else {
6118                         pg->pg_lna_lod_gain = 1;
6119                         trsw_rx_gain -= 8;
6120                 }
6121                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6122                 pg->pg_pga_gain = trsw_rx_gain / 3;
6123                 if (pg->pg_pga_gain >= 5) {
6124                         pg->pg_pga_gain -= 5;
6125                         pg->pg_lna_gain = 2;
6126                 } else
6127                         pg->pg_lna_gain = 0;
6128         } else {
6129                 pg->pg_lna_gain = 0;
6130                 pg->pg_trsw_rx_gain = 0x20;
6131                 if (max_rx_gain >= 0x14) {
6132                         pg->pg_lna_lod_gain = 1;
6133                         pg->pg_pga_gain = 2;
6134                 } else if (max_rx_gain >= 0x12) {
6135                         pg->pg_lna_lod_gain = 1;
6136                         pg->pg_pga_gain = 1;
6137                 } else if (max_rx_gain >= 0xf) {
6138                         pg->pg_lna_lod_gain = 1;
6139                         pg->pg_pga_gain = 0;
6140                 } else {
6141                         pg->pg_lna_lod_gain = 0;
6142                         pg->pg_pga_gain = 0;
6143                 }
6144         }
6145
6146         tmp = BWN_RF_READ(mac, 0x7a);
6147         if (pg->pg_lna_lod_gain == 0)
6148                 tmp &= ~0x0008;
6149         else
6150                 tmp |= 0x0008;
6151         BWN_RF_WRITE(mac, 0x7a, tmp);
6152 }
6153
6154 static void
6155 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6156 {
6157         struct bwn_phy *phy = &mac->mac_phy;
6158         struct bwn_phy_g *pg = &phy->phy_g;
6159         struct bwn_softc *sc = mac->mac_sc;
6160         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6161         struct timespec ts;
6162         uint16_t tmp;
6163
6164         if (bwn_has_hwpctl(mac)) {
6165                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6166                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6167                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6168                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6169                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6170
6171                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6172                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6173                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6174                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6175         }
6176         if (phy->type == BWN_PHYTYPE_B &&
6177             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6178                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6179                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6180         }
6181         if (phy->rev >= 2) {
6182                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6183                 sav->phy_analogoverval =
6184                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6185                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6186                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6187                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6188                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6189                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6190
6191                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6192                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6193                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6194                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6195                 if (phy->type == BWN_PHYTYPE_G) {
6196                         if ((phy->rev >= 7) &&
6197                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6198                              BWN_BFL_EXTLNA)) {
6199                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6200                         } else {
6201                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6202                         }
6203                 } else {
6204                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6205                 }
6206                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6207         }
6208         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6209         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6210         sav->rf0 = BWN_RF_READ(mac, 0x43);
6211         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6212         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6213         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6214         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6215         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6216
6217         if (!BWN_HAS_TXMAG(phy)) {
6218                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6219                 sav->rf2 &= 0x00f0;
6220         }
6221         if (phy->type == BWN_PHYTYPE_B) {
6222                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6223                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6224                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6225                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6226         } else {
6227                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6228                             | 0x8000);
6229         }
6230         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6231                     & 0xf000);
6232
6233         tmp =
6234             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6235         BWN_PHY_WRITE(mac, tmp, 0x007f);
6236
6237         tmp = sav->phy_syncctl;
6238         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6239         tmp = sav->rf1;
6240         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6241
6242         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6243         if (phy->type == BWN_PHYTYPE_G ||
6244             (phy->type == BWN_PHYTYPE_B &&
6245              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6246                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6247         } else
6248                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6249         if (phy->rev >= 2)
6250                 bwn_dummy_transmission(mac, 0, 1);
6251         bwn_phy_g_switch_chan(mac, 6, 0);
6252         BWN_RF_READ(mac, 0x51);
6253         if (phy->type == BWN_PHYTYPE_G)
6254                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6255
6256         nanouptime(&ts);
6257         if (time_before(lo->txctl_measured_time,
6258             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6259                 bwn_lo_measure_txctl_values(mac);
6260
6261         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6262                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6263         else {
6264                 if (phy->type == BWN_PHYTYPE_B)
6265                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6266                 else
6267                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6268         }
6269 }
6270
6271 static void
6272 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6273 {
6274         struct bwn_phy *phy = &mac->mac_phy;
6275         struct bwn_phy_g *pg = &phy->phy_g;
6276         uint16_t tmp;
6277
6278         if (phy->rev >= 2) {
6279                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6280                 tmp = (pg->pg_pga_gain << 8);
6281                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6282                 DELAY(5);
6283                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6284                 DELAY(2);
6285                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6286         } else {
6287                 tmp = (pg->pg_pga_gain | 0xefa0);
6288                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6289         }
6290         if (phy->type == BWN_PHYTYPE_G) {
6291                 if (phy->rev >= 3)
6292                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6293                 else
6294                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6295                 if (phy->rev >= 2)
6296                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6297                 else
6298                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6299         }
6300         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6301         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6302         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6303         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6304         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6305         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6306         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6307         if (!BWN_HAS_TXMAG(phy)) {
6308                 tmp = sav->rf2;
6309                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6310         }
6311         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6312         if (phy->type == BWN_PHYTYPE_B &&
6313             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6314                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6315                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6316         }
6317         if (phy->rev >= 2) {
6318                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6319                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6320                               sav->phy_analogoverval);
6321                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6322                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6323                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6324                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6325                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6326         }
6327         if (bwn_has_hwpctl(mac)) {
6328                 tmp = (sav->phy_lomask & 0xbfff);
6329                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6330                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6331                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6332                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6333                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6334         }
6335         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6336 }
6337
6338 static int
6339 bwn_lo_probe_loctl(struct bwn_mac *mac,
6340     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6341 {
6342         struct bwn_phy *phy = &mac->mac_phy;
6343         struct bwn_phy_g *pg = &phy->phy_g;
6344         struct bwn_loctl orig, test;
6345         struct bwn_loctl prev = { -100, -100 };
6346         static const struct bwn_loctl modifiers[] = {
6347                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6348                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6349         };
6350         int begin, end, lower = 0, i;
6351         uint16_t feedth;
6352
6353         if (d->curstate == 0) {
6354                 begin = 1;
6355                 end = 8;
6356         } else if (d->curstate % 2 == 0) {
6357                 begin = d->curstate - 1;
6358                 end = d->curstate + 1;
6359         } else {
6360                 begin = d->curstate - 2;
6361                 end = d->curstate + 2;
6362         }
6363         if (begin < 1)
6364                 begin += 8;
6365         if (end > 8)
6366                 end -= 8;
6367
6368         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6369         i = begin;
6370         d->curstate = i;
6371         while (1) {
6372                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6373                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6374                 test.i += modifiers[i - 1].i * d->multipler;
6375                 test.q += modifiers[i - 1].q * d->multipler;
6376                 if ((test.i != prev.i || test.q != prev.q) &&
6377                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6378                         bwn_lo_write(mac, &test);
6379                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6380                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6381                         if (feedth < d->feedth) {
6382                                 memcpy(probe, &test,
6383                                     sizeof(struct bwn_loctl));
6384                                 lower = 1;
6385                                 d->feedth = feedth;
6386                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6387                                         break;
6388                         }
6389                 }
6390                 memcpy(&prev, &test, sizeof(prev));
6391                 if (i == end)
6392                         break;
6393                 if (i == 8)
6394                         i = 1;
6395                 else
6396                         i++;
6397                 d->curstate = i;
6398         }
6399
6400         return (lower);
6401 }
6402
6403 static void
6404 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6405 {
6406         struct bwn_phy *phy = &mac->mac_phy;
6407         struct bwn_phy_g *pg = &phy->phy_g;
6408         struct bwn_lo_g_sm d;
6409         struct bwn_loctl probe;
6410         int lower, repeat, cnt = 0;
6411         uint16_t feedth;
6412
6413         d.nmeasure = 0;
6414         d.multipler = 1;
6415         if (BWN_HAS_LOOPBACK(phy))
6416                 d.multipler = 3;
6417
6418         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6419         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6420
6421         do {
6422                 bwn_lo_write(mac, &d.loctl);
6423                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6424                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6425                 if (feedth < 0x258) {
6426                         if (feedth >= 0x12c)
6427                                 *rxgain += 6;
6428                         else
6429                                 *rxgain += 3;
6430                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6431                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6432                 }
6433                 d.feedth = feedth;
6434                 d.curstate = 0;
6435                 do {
6436                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6437                             ("%s:%d: fail", __func__, __LINE__));
6438                         memcpy(&probe, &d.loctl,
6439                                sizeof(struct bwn_loctl));
6440                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6441                         if (!lower)
6442                                 break;
6443                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6444                                 break;
6445                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6446                         d.nmeasure++;
6447                 } while (d.nmeasure < 24);
6448                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6449
6450                 if (BWN_HAS_LOOPBACK(phy)) {
6451                         if (d.feedth > 0x1194)
6452                                 *rxgain -= 6;
6453                         else if (d.feedth < 0x5dc)
6454                                 *rxgain += 3;
6455                         if (cnt == 0) {
6456                                 if (d.feedth <= 0x5dc) {
6457                                         d.multipler = 1;
6458                                         cnt++;
6459                                 } else
6460                                         d.multipler = 2;
6461                         } else if (cnt == 2)
6462                                 d.multipler = 1;
6463                 }
6464                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6465         } while (++cnt < repeat);
6466 }
6467
6468 static struct bwn_lo_calib *
6469 bwn_lo_calibset(struct bwn_mac *mac,
6470     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6471 {
6472         struct bwn_phy *phy = &mac->mac_phy;
6473         struct bwn_phy_g *pg = &phy->phy_g;
6474         struct bwn_loctl loctl = { 0, 0 };
6475         struct bwn_lo_calib *cal;
6476         struct bwn_lo_g_value sval = { 0 };
6477         int rxgain;
6478         uint16_t pad, reg, value;
6479
6480         sval.old_channel = phy->chan;
6481         bwn_mac_suspend(mac);
6482         bwn_lo_save(mac, &sval);
6483
6484         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6485         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6486         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6487
6488         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6489         if (rfatt->padmix)
6490                 rxgain -= pad;
6491         if (BWN_HAS_LOOPBACK(phy))
6492                 rxgain += pg->pg_max_lb_gain;
6493         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6494         bwn_phy_g_set_bbatt(mac, bbatt->att);
6495         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6496
6497         bwn_lo_restore(mac, &sval);
6498         bwn_mac_enable(mac);
6499
6500         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6501         if (!cal) {
6502                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6503                 return (NULL);
6504         }
6505         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6506         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6507         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6508
6509         BWN_GETTIME(cal->calib_time);
6510
6511         return (cal);
6512 }
6513
6514 static struct bwn_lo_calib *
6515 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6516     const struct bwn_rfatt *rfatt)
6517 {
6518         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6519         struct bwn_lo_calib *c;
6520
6521         TAILQ_FOREACH(c, &lo->calib_list, list) {
6522                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6523                         continue;
6524                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6525                         continue;
6526                 return (c);
6527         }
6528
6529         c = bwn_lo_calibset(mac, bbatt, rfatt);
6530         if (!c)
6531                 return (NULL);
6532         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6533
6534         return (c);
6535 }
6536
6537 static void
6538 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6539 {
6540         struct bwn_phy *phy = &mac->mac_phy;
6541         struct bwn_phy_g *pg = &phy->phy_g;
6542         struct bwn_softc *sc = mac->mac_sc;
6543         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6544         const struct bwn_rfatt *rfatt;
6545         const struct bwn_bbatt *bbatt;
6546         uint64_t pvector;
6547         int i;
6548         int rf_offset, bb_offset;
6549         uint8_t changed = 0;
6550
6551         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6552         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6553             ("%s:%d: fail", __func__, __LINE__));
6554
6555         pvector = lo->power_vector;
6556         if (!update && !pvector)
6557                 return;
6558
6559         bwn_mac_suspend(mac);
6560
6561         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6562                 struct bwn_lo_calib *cal;
6563                 int idx;
6564                 uint16_t val;
6565
6566                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6567                         continue;
6568                 bb_offset = i / lo->rfatt.len;
6569                 rf_offset = i % lo->rfatt.len;
6570                 bbatt = &(lo->bbatt.array[bb_offset]);
6571                 rfatt = &(lo->rfatt.array[rf_offset]);
6572
6573                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6574                 if (!cal) {
6575                         device_printf(sc->sc_dev, "LO: Could not "
6576                             "calibrate DC table entry\n");
6577                         continue;
6578                 }
6579                 val = (uint8_t)(cal->ctl.q);
6580                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6581                 free(cal, M_DEVBUF);
6582
6583                 idx = i / 2;
6584                 if (i % 2)
6585                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6586                             | ((val & 0x00ff) << 8);
6587                 else
6588                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6589                             | (val & 0x00ff);
6590                 changed = 1;
6591         }
6592         if (changed) {
6593                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6594                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6595         }
6596         bwn_mac_enable(mac);
6597 }
6598
6599 static void
6600 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6601 {
6602
6603         if (!rf->padmix)
6604                 return;
6605         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6606                 rf->att = 4;
6607 }
6608
6609 static void
6610 bwn_lo_g_adjust(struct bwn_mac *mac)
6611 {
6612         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6613         struct bwn_lo_calib *cal;
6614         struct bwn_rfatt rf;
6615
6616         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6617         bwn_lo_fixup_rfatt(&rf);
6618
6619         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6620         if (!cal)
6621                 return;
6622         bwn_lo_write(mac, &cal->ctl);
6623 }
6624
6625 static void
6626 bwn_lo_g_init(struct bwn_mac *mac)
6627 {
6628
6629         if (!bwn_has_hwpctl(mac))
6630                 return;
6631
6632         bwn_lo_get_powervector(mac);
6633         bwn_phy_g_dc_lookup_init(mac, 1);
6634 }
6635
6636 static void
6637 bwn_mac_suspend(struct bwn_mac *mac)
6638 {
6639         struct bwn_softc *sc = mac->mac_sc;
6640         int i;
6641         uint32_t tmp;
6642
6643         KASSERT(mac->mac_suspended >= 0,
6644             ("%s:%d: fail", __func__, __LINE__));
6645
6646         if (mac->mac_suspended == 0) {
6647                 bwn_psctl(mac, BWN_PS_AWAKE);
6648                 BWN_WRITE_4(mac, BWN_MACCTL,
6649                             BWN_READ_4(mac, BWN_MACCTL)
6650                             & ~BWN_MACCTL_ON);
6651                 BWN_READ_4(mac, BWN_MACCTL);
6652                 for (i = 35; i; i--) {
6653                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6654                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6655                                 goto out;
6656                         DELAY(10);
6657                 }
6658                 for (i = 40; i; i--) {
6659                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6660                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6661                                 goto out;
6662                         DELAY(1000);
6663                 }
6664                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6665         }
6666 out:
6667         mac->mac_suspended++;
6668 }
6669
6670 static void
6671 bwn_mac_enable(struct bwn_mac *mac)
6672 {
6673         struct bwn_softc *sc = mac->mac_sc;
6674         uint16_t state;
6675
6676         state = bwn_shm_read_2(mac, BWN_SHARED,
6677             BWN_SHARED_UCODESTAT);
6678         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6679             state != BWN_SHARED_UCODESTAT_SLEEP)
6680                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6681
6682         mac->mac_suspended--;
6683         KASSERT(mac->mac_suspended >= 0,
6684             ("%s:%d: fail", __func__, __LINE__));
6685         if (mac->mac_suspended == 0) {
6686                 BWN_WRITE_4(mac, BWN_MACCTL,
6687                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6688                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6689                 BWN_READ_4(mac, BWN_MACCTL);
6690                 BWN_READ_4(mac, BWN_INTR_REASON);
6691                 bwn_psctl(mac, 0);
6692         }
6693 }
6694
6695 static void
6696 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6697 {
6698         struct bwn_softc *sc = mac->mac_sc;
6699         int i;
6700         uint16_t ucstat;
6701
6702         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6703             ("%s:%d: fail", __func__, __LINE__));
6704         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6705             ("%s:%d: fail", __func__, __LINE__));
6706
6707         /* XXX forcibly awake and hwps-off */
6708
6709         BWN_WRITE_4(mac, BWN_MACCTL,
6710             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6711             ~BWN_MACCTL_HWPS);
6712         BWN_READ_4(mac, BWN_MACCTL);
6713         if (siba_get_revid(sc->sc_dev) >= 5) {
6714                 for (i = 0; i < 100; i++) {
6715                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6716                             BWN_SHARED_UCODESTAT);
6717                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6718                                 break;
6719                         DELAY(10);
6720                 }
6721         }
6722 }
6723
6724 static int16_t
6725 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6726 {
6727
6728         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6729         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6730 }
6731
6732 static void
6733 bwn_nrssi_threshold(struct bwn_mac *mac)
6734 {
6735         struct bwn_phy *phy = &mac->mac_phy;
6736         struct bwn_phy_g *pg = &phy->phy_g;
6737         struct bwn_softc *sc = mac->mac_sc;
6738         int32_t a, b;
6739         int16_t tmp16;
6740         uint16_t tmpu16;
6741
6742         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6743
6744         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6745                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6746                         a = 0x13;
6747                         b = 0x12;
6748                 } else {
6749                         a = 0xe;
6750                         b = 0x11;
6751                 }
6752
6753                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6754                 a += (pg->pg_nrssi[0] << 6);
6755                 a += (a < 32) ? 31 : 32;
6756                 a = a >> 6;
6757                 a = MIN(MAX(a, -31), 31);
6758
6759                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6760                 b += (pg->pg_nrssi[0] << 6);
6761                 if (b < 32)
6762                         b += 31;
6763                 else
6764                         b += 32;
6765                 b = b >> 6;
6766                 b = MIN(MAX(b, -31), 31);
6767
6768                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6769                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6770                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6771                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6772                 return;
6773         }
6774
6775         tmp16 = bwn_nrssi_read(mac, 0x20);
6776         if (tmp16 >= 0x20)
6777                 tmp16 -= 0x40;
6778         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6779 }
6780
6781 static void
6782 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6783 {
6784 #define SAVE_RF_MAX             3
6785 #define SAVE_PHY_COMM_MAX       4
6786 #define SAVE_PHY3_MAX           8
6787         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6788                 { 0x7a, 0x52, 0x43 };
6789         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6790                 { 0x15, 0x5a, 0x59, 0x58 };
6791         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6792                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6793                 0x0801, 0x0060, 0x0014, 0x0478
6794         };
6795         struct bwn_phy *phy = &mac->mac_phy;
6796         struct bwn_phy_g *pg = &phy->phy_g;
6797         int32_t i, tmp32, phy3_idx = 0;
6798         uint16_t delta, tmp;
6799         uint16_t save_rf[SAVE_RF_MAX];
6800         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6801         uint16_t save_phy3[SAVE_PHY3_MAX];
6802         uint16_t ant_div, phy0, chan_ex;
6803         int16_t nrssi0, nrssi1;
6804
6805         KASSERT(phy->type == BWN_PHYTYPE_G,
6806             ("%s:%d: fail", __func__, __LINE__));
6807
6808         if (phy->rf_rev >= 9)
6809                 return;
6810         if (phy->rf_rev == 8)
6811                 bwn_nrssi_offset(mac);
6812
6813         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6814         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6815
6816         /*
6817          * Save RF/PHY registers for later restoration
6818          */
6819         ant_div = BWN_READ_2(mac, 0x03e2);
6820         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6821         for (i = 0; i < SAVE_RF_MAX; ++i)
6822                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6823         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6824                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6825
6826         phy0 = BWN_READ_2(mac, BWN_PHY0);
6827         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6828         if (phy->rev >= 3) {
6829                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6830                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6831                 BWN_PHY_WRITE(mac, 0x002e, 0);
6832                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6833                 switch (phy->rev) {
6834                 case 4:
6835                 case 6:
6836                 case 7:
6837                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6838                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6839                         break;
6840                 case 3:
6841                 case 5:
6842                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6843                         break;
6844                 }
6845                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6846                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6847         }
6848         /*
6849          * Calculate nrssi0
6850          */
6851         BWN_RF_SET(mac, 0x007a, 0x0070);
6852         bwn_set_all_gains(mac, 0, 8, 0);
6853         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6854         if (phy->rev >= 2) {
6855                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6856                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6857         }
6858         BWN_RF_SET(mac, 0x007a, 0x0080);
6859         DELAY(20);
6860
6861         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6862         if (nrssi0 >= 0x0020)
6863                 nrssi0 -= 0x0040;
6864
6865         /*
6866          * Calculate nrssi1
6867          */
6868         BWN_RF_MASK(mac, 0x007a, 0x007f);
6869         if (phy->rev >= 2)
6870                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6871
6872         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6873             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6874         BWN_RF_SET(mac, 0x007a, 0x000f);
6875         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6876         if (phy->rev >= 2) {
6877                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6878                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6879         }
6880
6881         bwn_set_all_gains(mac, 3, 0, 1);
6882         if (phy->rf_rev == 8) {
6883                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6884         } else {
6885                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6886                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6887                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6888                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6889         }
6890         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6891         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6892         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6893         DELAY(20);
6894         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6895
6896         /*
6897          * Install calculated narrow RSSI values
6898          */
6899         if (nrssi1 >= 0x0020)
6900                 nrssi1 -= 0x0040;
6901         if (nrssi0 == nrssi1)
6902                 pg->pg_nrssi_slope = 0x00010000;
6903         else
6904                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6905         if (nrssi0 >= -4) {
6906                 pg->pg_nrssi[0] = nrssi1;
6907                 pg->pg_nrssi[1] = nrssi0;
6908         }
6909
6910         /*
6911          * Restore saved RF/PHY registers
6912          */
6913         if (phy->rev >= 3) {
6914                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6915                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6916                             save_phy3[phy3_idx]);
6917                 }
6918         }
6919         if (phy->rev >= 2) {
6920                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6921                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6922         }
6923
6924         for (i = 0; i < SAVE_RF_MAX; ++i)
6925                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6926
6927         BWN_WRITE_2(mac, 0x03e2, ant_div);
6928         BWN_WRITE_2(mac, 0x03e6, phy0);
6929         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6930
6931         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6932                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6933
6934         bwn_spu_workaround(mac, phy->chan);
6935         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6936         bwn_set_original_gains(mac);
6937         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6938         if (phy->rev >= 3) {
6939                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6940                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6941                             save_phy3[phy3_idx]);
6942                 }
6943         }
6944
6945         delta = 0x1f - pg->pg_nrssi[0];
6946         for (i = 0; i < 64; i++) {
6947                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6948                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6949                 pg->pg_nrssi_lt[i] = tmp32;
6950         }
6951
6952         bwn_nrssi_threshold(mac);
6953 #undef SAVE_RF_MAX
6954 #undef SAVE_PHY_COMM_MAX
6955 #undef SAVE_PHY3_MAX
6956 }
6957
6958 static void
6959 bwn_nrssi_offset(struct bwn_mac *mac)
6960 {
6961 #define SAVE_RF_MAX             2
6962 #define SAVE_PHY_COMM_MAX       10
6963 #define SAVE_PHY6_MAX           8
6964         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6965                 { 0x7a, 0x43 };
6966         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6967                 0x0001, 0x0811, 0x0812, 0x0814,
6968                 0x0815, 0x005a, 0x0059, 0x0058,
6969                 0x000a, 0x0003
6970         };
6971         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6972                 0x002e, 0x002f, 0x080f, 0x0810,
6973                 0x0801, 0x0060, 0x0014, 0x0478
6974         };
6975         struct bwn_phy *phy = &mac->mac_phy;
6976         int i, phy6_idx = 0;
6977         uint16_t save_rf[SAVE_RF_MAX];
6978         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6979         uint16_t save_phy6[SAVE_PHY6_MAX];
6980         int16_t nrssi;
6981         uint16_t saved = 0xffff;
6982
6983         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6984                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6985         for (i = 0; i < SAVE_RF_MAX; ++i)
6986                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6987
6988         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6989         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6990         BWN_PHY_SET(mac, 0x0811, 0x000c);
6991         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6992         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6993         if (phy->rev >= 6) {
6994                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6995                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6996
6997                 BWN_PHY_WRITE(mac, 0x002e, 0);
6998                 BWN_PHY_WRITE(mac, 0x002f, 0);
6999                 BWN_PHY_WRITE(mac, 0x080f, 0);
7000                 BWN_PHY_WRITE(mac, 0x0810, 0);
7001                 BWN_PHY_SET(mac, 0x0478, 0x0100);
7002                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7003                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7004                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7005         }
7006         BWN_RF_SET(mac, 0x007a, 0x0070);
7007         BWN_RF_SET(mac, 0x007a, 0x0080);
7008         DELAY(30);
7009
7010         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7011         if (nrssi >= 0x20)
7012                 nrssi -= 0x40;
7013         if (nrssi == 31) {
7014                 for (i = 7; i >= 4; i--) {
7015                         BWN_RF_WRITE(mac, 0x007b, i);
7016                         DELAY(20);
7017                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7018                             0x003f);
7019                         if (nrssi >= 0x20)
7020                                 nrssi -= 0x40;
7021                         if (nrssi < 31 && saved == 0xffff)
7022                                 saved = i;
7023                 }
7024                 if (saved == 0xffff)
7025                         saved = 4;
7026         } else {
7027                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7028                 if (phy->rev != 1) {
7029                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7030                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7031                 }
7032                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7033                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7034                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7035                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7036                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7037                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7038                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7039                 if (phy->rev == 0)
7040                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7041                 else
7042                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7043                 if (phy->rev != 1) {
7044                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7045                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7046                 }
7047                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7048                 BWN_RF_SET(mac, 0x007a, 0x000f);
7049                 bwn_set_all_gains(mac, 3, 0, 1);
7050                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7051                 DELAY(30);
7052                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7053                 if (nrssi >= 0x20)
7054                         nrssi -= 0x40;
7055                 if (nrssi == -32) {
7056                         for (i = 0; i < 4; i++) {
7057                                 BWN_RF_WRITE(mac, 0x007b, i);
7058                                 DELAY(20);
7059                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7060                                     0x047f) >> 8) & 0x003f);
7061                                 if (nrssi >= 0x20)
7062                                         nrssi -= 0x40;
7063                                 if (nrssi > -31 && saved == 0xffff)
7064                                         saved = i;
7065                         }
7066                         if (saved == 0xffff)
7067                                 saved = 3;
7068                 } else
7069                         saved = 0;
7070         }
7071         BWN_RF_WRITE(mac, 0x007b, saved);
7072
7073         /*
7074          * Restore saved RF/PHY registers
7075          */
7076         if (phy->rev >= 6) {
7077                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7078                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7079                             save_phy6[phy6_idx]);
7080                 }
7081         }
7082         if (phy->rev != 1) {
7083                 for (i = 3; i < 5; i++)
7084                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7085                             save_phy_comm[i]);
7086         }
7087         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7088                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7089
7090         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7091                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7092
7093         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7094         BWN_PHY_SET(mac, 0x0429, 0x8000);
7095         bwn_set_original_gains(mac);
7096         if (phy->rev >= 6) {
7097                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7098                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7099                             save_phy6[phy6_idx]);
7100                 }
7101         }
7102
7103         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7104         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7105         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7106 }
7107
7108 static void
7109 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7110     int16_t third)
7111 {
7112         struct bwn_phy *phy = &mac->mac_phy;
7113         uint16_t i;
7114         uint16_t start = 0x08, end = 0x18;
7115         uint16_t tmp;
7116         uint16_t table;
7117
7118         if (phy->rev <= 1) {
7119                 start = 0x10;
7120                 end = 0x20;
7121         }
7122
7123         table = BWN_OFDMTAB_GAINX;
7124         if (phy->rev <= 1)
7125                 table = BWN_OFDMTAB_GAINX_R1;
7126         for (i = 0; i < 4; i++)
7127                 bwn_ofdmtab_write_2(mac, table, i, first);
7128
7129         for (i = start; i < end; i++)
7130                 bwn_ofdmtab_write_2(mac, table, i, second);
7131
7132         if (third != -1) {
7133                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7134                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7135                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7136                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7137         }
7138         bwn_dummy_transmission(mac, 0, 1);
7139 }
7140
7141 static void
7142 bwn_set_original_gains(struct bwn_mac *mac)
7143 {
7144         struct bwn_phy *phy = &mac->mac_phy;
7145         uint16_t i, tmp;
7146         uint16_t table;
7147         uint16_t start = 0x0008, end = 0x0018;
7148
7149         if (phy->rev <= 1) {
7150                 start = 0x0010;
7151                 end = 0x0020;
7152         }
7153
7154         table = BWN_OFDMTAB_GAINX;
7155         if (phy->rev <= 1)
7156                 table = BWN_OFDMTAB_GAINX_R1;
7157         for (i = 0; i < 4; i++) {
7158                 tmp = (i & 0xfffc);
7159                 tmp |= (i & 0x0001) << 1;
7160                 tmp |= (i & 0x0002) >> 1;
7161
7162                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7163         }
7164
7165         for (i = start; i < end; i++)
7166                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7167
7168         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7169         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7170         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7171         bwn_dummy_transmission(mac, 0, 1);
7172 }
7173
7174 static void
7175 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7176 {
7177         struct bwn_phy *phy = &mac->mac_phy;
7178         struct bwn_phy_g *pg = &phy->phy_g;
7179         struct bwn_rfatt old_rfatt, rfatt;
7180         struct bwn_bbatt old_bbatt, bbatt;
7181         struct bwn_softc *sc = mac->mac_sc;
7182         uint8_t old_txctl = 0;
7183
7184         KASSERT(phy->type == BWN_PHYTYPE_G,
7185             ("%s:%d: fail", __func__, __LINE__));
7186
7187         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7188             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7189                 return;
7190
7191         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7192
7193         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7194
7195         if (!phy->gmode)
7196                 return;
7197         bwn_hwpctl_early_init(mac);
7198         if (pg->pg_curtssi == 0) {
7199                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7200                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7201                 } else {
7202                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7203                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7204                         old_txctl = pg->pg_txctl;
7205
7206                         bbatt.att = 11;
7207                         if (phy->rf_rev == 8) {
7208                                 rfatt.att = 15;
7209                                 rfatt.padmix = 1;
7210                         } else {
7211                                 rfatt.att = 9;
7212                                 rfatt.padmix = 0;
7213                         }
7214                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7215                 }
7216                 bwn_dummy_transmission(mac, 0, 1);
7217                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7218                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7219                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7220                 else
7221                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7222                             &old_rfatt, old_txctl);
7223         }
7224         bwn_hwpctl_init_gphy(mac);
7225
7226         /* clear TSSI */
7227         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7228         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7229         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7230         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7231 }
7232
7233 static void
7234 bwn_hwpctl_early_init(struct bwn_mac *mac)
7235 {
7236         struct bwn_phy *phy = &mac->mac_phy;
7237
7238         if (!bwn_has_hwpctl(mac)) {
7239                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7240                 return;
7241         }
7242
7243         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7244         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7245         BWN_PHY_SET(mac, 0x047c, 0x0002);
7246         BWN_PHY_SET(mac, 0x047a, 0xf000);
7247         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7248                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7249                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7250                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7251                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7252                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7253         } else {
7254                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7255                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7256                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7257                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7258                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7259                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7260                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7261         }
7262 }
7263
7264 static void
7265 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7266 {
7267         struct bwn_phy *phy = &mac->mac_phy;
7268         struct bwn_phy_g *pg = &phy->phy_g;
7269         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7270         int i;
7271         uint16_t nr_written = 0, tmp, value;
7272         uint8_t rf, bb;
7273
7274         if (!bwn_has_hwpctl(mac)) {
7275                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7276                 return;
7277         }
7278
7279         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7280             (pg->pg_idletssi - pg->pg_curtssi));
7281         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7282             (pg->pg_idletssi - pg->pg_curtssi));
7283
7284         for (i = 0; i < 32; i++)
7285                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7286         for (i = 32; i < 64; i++)
7287                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7288         for (i = 0; i < 64; i += 2) {
7289                 value = (uint16_t) pg->pg_tssi2dbm[i];
7290                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7291                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7292         }
7293
7294         for (rf = 0; rf < lo->rfatt.len; rf++) {
7295                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7296                         if (nr_written >= 0x40)
7297                                 return;
7298                         tmp = lo->bbatt.array[bb].att;
7299                         tmp <<= 8;
7300                         if (phy->rf_rev == 8)
7301                                 tmp |= 0x50;
7302                         else
7303                                 tmp |= 0x40;
7304                         tmp |= lo->rfatt.array[rf].att;
7305                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7306                         nr_written++;
7307                 }
7308         }
7309
7310         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7311         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7312
7313         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7314         BWN_PHY_SET(mac, 0x0478, 0x0800);
7315         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7316         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7317
7318         bwn_phy_g_dc_lookup_init(mac, 1);
7319         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7320 }
7321
7322 static void
7323 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7324 {
7325         struct bwn_softc *sc = mac->mac_sc;
7326
7327         if (spu != 0)
7328                 bwn_spu_workaround(mac, channel);
7329
7330         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7331
7332         if (channel == 14) {
7333                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7334                         bwn_hf_write(mac,
7335                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7336                 else
7337                         bwn_hf_write(mac,
7338                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7339                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7340                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7341                 return;
7342         }
7343
7344         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7345             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7346 }
7347
7348 static uint16_t
7349 bwn_phy_g_chan2freq(uint8_t channel)
7350 {
7351         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7352
7353         KASSERT(channel >= 1 && channel <= 14,
7354             ("%s:%d: fail", __func__, __LINE__));
7355
7356         return (bwn_phy_g_rf_channels[channel - 1]);
7357 }
7358
7359 static void
7360 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7361     const struct bwn_rfatt *rfatt, uint8_t txctl)
7362 {
7363         struct bwn_phy *phy = &mac->mac_phy;
7364         struct bwn_phy_g *pg = &phy->phy_g;
7365         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7366         uint16_t bb, rf;
7367         uint16_t tx_bias, tx_magn;
7368
7369         bb = bbatt->att;
7370         rf = rfatt->att;
7371         tx_bias = lo->tx_bias;
7372         tx_magn = lo->tx_magn;
7373         if (tx_bias == 0xff)
7374                 tx_bias = 0;
7375
7376         pg->pg_txctl = txctl;
7377         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7378         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7379         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7380         bwn_phy_g_set_bbatt(mac, bb);
7381         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7382         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7383                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7384         else {
7385                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7386                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7387         }
7388         if (BWN_HAS_TXMAG(phy))
7389                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7390         else
7391                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7392         bwn_lo_g_adjust(mac);
7393 }
7394
7395 static void
7396 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7397     uint16_t bbatt)
7398 {
7399         struct bwn_phy *phy = &mac->mac_phy;
7400
7401         if (phy->analog == 0) {
7402                 BWN_WRITE_2(mac, BWN_PHY0,
7403                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7404                 return;
7405         }
7406         if (phy->analog > 1) {
7407                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7408                 return;
7409         }
7410         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7411 }
7412
7413 static uint16_t
7414 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7415 {
7416         struct bwn_phy *phy = &mac->mac_phy;
7417         struct bwn_phy_g *pg = &phy->phy_g;
7418         struct bwn_softc *sc = mac->mac_sc;
7419         int max_lb_gain;
7420         uint16_t extlna;
7421         uint16_t i;
7422
7423         if (phy->gmode == 0)
7424                 return (0);
7425
7426         if (BWN_HAS_LOOPBACK(phy)) {
7427                 max_lb_gain = pg->pg_max_lb_gain;
7428                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7429                 if (max_lb_gain >= 0x46) {
7430                         extlna = 0x3000;
7431                         max_lb_gain -= 0x46;
7432                 } else if (max_lb_gain >= 0x3a) {
7433                         extlna = 0x1000;
7434                         max_lb_gain -= 0x3a;
7435                 } else if (max_lb_gain >= 0x2e) {
7436                         extlna = 0x2000;
7437                         max_lb_gain -= 0x2e;
7438                 } else {
7439                         extlna = 0;
7440                         max_lb_gain -= 0x10;
7441                 }
7442
7443                 for (i = 0; i < 16; i++) {
7444                         max_lb_gain -= (i * 6);
7445                         if (max_lb_gain < 6)
7446                                 break;
7447                 }
7448
7449                 if ((phy->rev < 7) ||
7450                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7451                         if (reg == BWN_PHY_RFOVER) {
7452                                 return (0x1b3);
7453                         } else if (reg == BWN_PHY_RFOVERVAL) {
7454                                 extlna |= (i << 8);
7455                                 switch (lpd) {
7456                                 case BWN_LPD(0, 1, 1):
7457                                         return (0x0f92);
7458                                 case BWN_LPD(0, 0, 1):
7459                                 case BWN_LPD(1, 0, 1):
7460                                         return (0x0092 | extlna);
7461                                 case BWN_LPD(1, 0, 0):
7462                                         return (0x0093 | extlna);
7463                                 }
7464                                 KASSERT(0 == 1,
7465                                     ("%s:%d: fail", __func__, __LINE__));
7466                         }
7467                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7468                 } else {
7469                         if (reg == BWN_PHY_RFOVER)
7470                                 return (0x9b3);
7471                         if (reg == BWN_PHY_RFOVERVAL) {
7472                                 if (extlna)
7473                                         extlna |= 0x8000;
7474                                 extlna |= (i << 8);
7475                                 switch (lpd) {
7476                                 case BWN_LPD(0, 1, 1):
7477                                         return (0x8f92);
7478                                 case BWN_LPD(0, 0, 1):
7479                                         return (0x8092 | extlna);
7480                                 case BWN_LPD(1, 0, 1):
7481                                         return (0x2092 | extlna);
7482                                 case BWN_LPD(1, 0, 0):
7483                                         return (0x2093 | extlna);
7484                                 }
7485                                 KASSERT(0 == 1,
7486                                     ("%s:%d: fail", __func__, __LINE__));
7487                         }
7488                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7489                 }
7490                 return (0);
7491         }
7492
7493         if ((phy->rev < 7) ||
7494             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7495                 if (reg == BWN_PHY_RFOVER) {
7496                         return (0x1b3);
7497                 } else if (reg == BWN_PHY_RFOVERVAL) {
7498                         switch (lpd) {
7499                         case BWN_LPD(0, 1, 1):
7500                                 return (0x0fb2);
7501                         case BWN_LPD(0, 0, 1):
7502                                 return (0x00b2);
7503                         case BWN_LPD(1, 0, 1):
7504                                 return (0x30b2);
7505                         case BWN_LPD(1, 0, 0):
7506                                 return (0x30b3);
7507                         }
7508                         KASSERT(0 == 1,
7509                             ("%s:%d: fail", __func__, __LINE__));
7510                 }
7511                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7512         } else {
7513                 if (reg == BWN_PHY_RFOVER) {
7514                         return (0x9b3);
7515                 } else if (reg == BWN_PHY_RFOVERVAL) {
7516                         switch (lpd) {
7517                         case BWN_LPD(0, 1, 1):
7518                                 return (0x8fb2);
7519                         case BWN_LPD(0, 0, 1):
7520                                 return (0x80b2);
7521                         case BWN_LPD(1, 0, 1):
7522                                 return (0x20b2);
7523                         case BWN_LPD(1, 0, 0):
7524                                 return (0x20b3);
7525                         }
7526                         KASSERT(0 == 1,
7527                             ("%s:%d: fail", __func__, __LINE__));
7528                 }
7529                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7530         }
7531         return (0);
7532 }
7533
7534 static void
7535 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7536 {
7537
7538         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7539                 return;
7540         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7541             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7542         DELAY(1000);
7543         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7544 }
7545
7546 static int
7547 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7548 {
7549         struct bwn_softc *sc = mac->mac_sc;
7550         struct bwn_fw *fw = &mac->mac_fw;
7551         const uint8_t rev = siba_get_revid(sc->sc_dev);
7552         const char *filename;
7553         uint32_t high;
7554         int error;
7555
7556         /* microcode */
7557         if (rev >= 5 && rev <= 10)
7558                 filename = "ucode5";
7559         else if (rev >= 11 && rev <= 12)
7560                 filename = "ucode11";
7561         else if (rev == 13)
7562                 filename = "ucode13";
7563         else if (rev == 14)
7564                 filename = "ucode14";
7565         else if (rev >= 15)
7566                 filename = "ucode15";
7567         else {
7568                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7569                 bwn_release_firmware(mac);
7570                 return (EOPNOTSUPP);
7571         }
7572         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7573         if (error) {
7574                 bwn_release_firmware(mac);
7575                 return (error);
7576         }
7577
7578         /* PCM */
7579         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7580         if (rev >= 5 && rev <= 10) {
7581                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7582                 if (error == ENOENT)
7583                         fw->no_pcmfile = 1;
7584                 else if (error) {
7585                         bwn_release_firmware(mac);
7586                         return (error);
7587                 }
7588         } else if (rev < 11) {
7589                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7590                 return (EOPNOTSUPP);
7591         }
7592
7593         /* initvals */
7594         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7595         switch (mac->mac_phy.type) {
7596         case BWN_PHYTYPE_A:
7597                 if (rev < 5 || rev > 10)
7598                         goto fail1;
7599                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7600                         filename = "a0g1initvals5";
7601                 else
7602                         filename = "a0g0initvals5";
7603                 break;
7604         case BWN_PHYTYPE_G:
7605                 if (rev >= 5 && rev <= 10)
7606                         filename = "b0g0initvals5";
7607                 else if (rev >= 13)
7608                         filename = "b0g0initvals13";
7609                 else
7610                         goto fail1;
7611                 break;
7612         case BWN_PHYTYPE_LP:
7613                 if (rev == 13)
7614                         filename = "lp0initvals13";
7615                 else if (rev == 14)
7616                         filename = "lp0initvals14";
7617                 else if (rev >= 15)
7618                         filename = "lp0initvals15";
7619                 else
7620                         goto fail1;
7621                 break;
7622         case BWN_PHYTYPE_N:
7623                 if (rev >= 11 && rev <= 12)
7624                         filename = "n0initvals11";
7625                 else
7626                         goto fail1;
7627                 break;
7628         default:
7629                 goto fail1;
7630         }
7631         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7632         if (error) {
7633                 bwn_release_firmware(mac);
7634                 return (error);
7635         }
7636
7637         /* bandswitch initvals */
7638         switch (mac->mac_phy.type) {
7639         case BWN_PHYTYPE_A:
7640                 if (rev >= 5 && rev <= 10) {
7641                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7642                                 filename = "a0g1bsinitvals5";
7643                         else
7644                                 filename = "a0g0bsinitvals5";
7645                 } else if (rev >= 11)
7646                         filename = NULL;
7647                 else
7648                         goto fail1;
7649                 break;
7650         case BWN_PHYTYPE_G:
7651                 if (rev >= 5 && rev <= 10)
7652                         filename = "b0g0bsinitvals5";
7653                 else if (rev >= 11)
7654                         filename = NULL;
7655                 else
7656                         goto fail1;
7657                 break;
7658         case BWN_PHYTYPE_LP:
7659                 if (rev == 13)
7660                         filename = "lp0bsinitvals13";
7661                 else if (rev == 14)
7662                         filename = "lp0bsinitvals14";
7663                 else if (rev >= 15)
7664                         filename = "lp0bsinitvals15";
7665                 else
7666                         goto fail1;
7667                 break;
7668         case BWN_PHYTYPE_N:
7669                 if (rev >= 11 && rev <= 12)
7670                         filename = "n0bsinitvals11";
7671                 else
7672                         goto fail1;
7673                 break;
7674         default:
7675                 goto fail1;
7676         }
7677         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7678         if (error) {
7679                 bwn_release_firmware(mac);
7680                 return (error);
7681         }
7682         return (0);
7683 fail1:
7684         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7685         bwn_release_firmware(mac);
7686         return (EOPNOTSUPP);
7687 }
7688
7689 static int
7690 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7691     const char *name, struct bwn_fwfile *bfw)
7692 {
7693         const struct bwn_fwhdr *hdr;
7694         struct bwn_softc *sc = mac->mac_sc;
7695         const struct firmware *fw;
7696         char namebuf[64];
7697
7698         if (name == NULL) {
7699                 bwn_do_release_fw(bfw);
7700                 return (0);
7701         }
7702         if (bfw->filename != NULL) {
7703                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7704                         return (0);
7705                 bwn_do_release_fw(bfw);
7706         }
7707
7708         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7709             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7710             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7711         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7712         fw = firmware_get(namebuf);
7713         if (fw == NULL) {
7714                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7715                     namebuf);
7716                 return (ENOENT);
7717         }
7718         if (fw->datasize < sizeof(struct bwn_fwhdr))
7719                 goto fail;
7720         hdr = (const struct bwn_fwhdr *)(fw->data);
7721         switch (hdr->type) {
7722         case BWN_FWTYPE_UCODE:
7723         case BWN_FWTYPE_PCM:
7724                 if (be32toh(hdr->size) !=
7725                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7726                         goto fail;
7727                 /* FALLTHROUGH */
7728         case BWN_FWTYPE_IV:
7729                 if (hdr->ver != 1)
7730                         goto fail;
7731                 break;
7732         default:
7733                 goto fail;
7734         }
7735         bfw->filename = name;
7736         bfw->fw = fw;
7737         bfw->type = type;
7738         return (0);
7739 fail:
7740         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7741         if (fw != NULL)
7742                 firmware_put(fw, FIRMWARE_UNLOAD);
7743         return (EPROTO);
7744 }
7745
7746 static void
7747 bwn_release_firmware(struct bwn_mac *mac)
7748 {
7749
7750         bwn_do_release_fw(&mac->mac_fw.ucode);
7751         bwn_do_release_fw(&mac->mac_fw.pcm);
7752         bwn_do_release_fw(&mac->mac_fw.initvals);
7753         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7754 }
7755
7756 static void
7757 bwn_do_release_fw(struct bwn_fwfile *bfw)
7758 {
7759
7760         if (bfw->fw != NULL)
7761                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7762         bfw->fw = NULL;
7763         bfw->filename = NULL;
7764 }
7765
7766 static int
7767 bwn_fw_loaducode(struct bwn_mac *mac)
7768 {
7769 #define GETFWOFFSET(fwp, offset)        \
7770         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7771 #define GETFWSIZE(fwp, offset)  \
7772         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7773         struct bwn_softc *sc = mac->mac_sc;
7774         const uint32_t *data;
7775         unsigned int i;
7776         uint32_t ctl;
7777         uint16_t date, fwcaps, time;
7778         int error = 0;
7779
7780         ctl = BWN_READ_4(mac, BWN_MACCTL);
7781         ctl |= BWN_MACCTL_MCODE_JMP0;
7782         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7783             __LINE__));
7784         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7785         for (i = 0; i < 64; i++)
7786                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7787         for (i = 0; i < 4096; i += 2)
7788                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7789
7790         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7791         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7792         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7793              i++) {
7794                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7795                 DELAY(10);
7796         }
7797
7798         if (mac->mac_fw.pcm.fw) {
7799                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7800                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7801                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7802                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7803                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7804                     sizeof(struct bwn_fwhdr)); i++) {
7805                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7806                         DELAY(10);
7807                 }
7808         }
7809
7810         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7811         BWN_WRITE_4(mac, BWN_MACCTL,
7812             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7813             BWN_MACCTL_MCODE_RUN);
7814
7815         for (i = 0; i < 21; i++) {
7816                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7817                         break;
7818                 if (i >= 20) {
7819                         device_printf(sc->sc_dev, "ucode timeout\n");
7820                         error = ENXIO;
7821                         goto error;
7822                 }
7823                 DELAY(50000);
7824         }
7825         BWN_READ_4(mac, BWN_INTR_REASON);
7826
7827         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7828         if (mac->mac_fw.rev <= 0x128) {
7829                 device_printf(sc->sc_dev, "the firmware is too old\n");
7830                 error = EOPNOTSUPP;
7831                 goto error;
7832         }
7833         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7834             BWN_SHARED_UCODE_PATCH);
7835         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7836         mac->mac_fw.opensource = (date == 0xffff);
7837         if (bwn_wme != 0)
7838                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7839         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7840
7841         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7842         if (mac->mac_fw.opensource == 0) {
7843                 device_printf(sc->sc_dev,
7844                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7845                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7846                 if (mac->mac_fw.no_pcmfile)
7847                         device_printf(sc->sc_dev,
7848                             "no HW crypto acceleration due to pcm5\n");
7849         } else {
7850                 mac->mac_fw.patch = time;
7851                 fwcaps = bwn_fwcaps_read(mac);
7852                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7853                         device_printf(sc->sc_dev,
7854                             "disabling HW crypto acceleration\n");
7855                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7856                 }
7857                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7858                         device_printf(sc->sc_dev, "disabling WME support\n");
7859                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7860                 }
7861         }
7862
7863         if (BWN_ISOLDFMT(mac))
7864                 device_printf(sc->sc_dev, "using old firmware image\n");
7865
7866         return (0);
7867
7868 error:
7869         BWN_WRITE_4(mac, BWN_MACCTL,
7870             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7871             BWN_MACCTL_MCODE_JMP0);
7872
7873         return (error);
7874 #undef GETFWSIZE
7875 #undef GETFWOFFSET
7876 }
7877
7878 /* OpenFirmware only */
7879 static uint16_t
7880 bwn_fwcaps_read(struct bwn_mac *mac)
7881 {
7882
7883         KASSERT(mac->mac_fw.opensource == 1,
7884             ("%s:%d: fail", __func__, __LINE__));
7885         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7886 }
7887
7888 static int
7889 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7890     size_t count, size_t array_size)
7891 {
7892 #define GET_NEXTIV16(iv)                                                \
7893         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7894             sizeof(uint16_t) + sizeof(uint16_t)))
7895 #define GET_NEXTIV32(iv)                                                \
7896         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7897             sizeof(uint16_t) + sizeof(uint32_t)))
7898         struct bwn_softc *sc = mac->mac_sc;
7899         const struct bwn_fwinitvals *iv;
7900         uint16_t offset;
7901         size_t i;
7902         uint8_t bit32;
7903
7904         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7905             ("%s:%d: fail", __func__, __LINE__));
7906         iv = ivals;
7907         for (i = 0; i < count; i++) {
7908                 if (array_size < sizeof(iv->offset_size))
7909                         goto fail;
7910                 array_size -= sizeof(iv->offset_size);
7911                 offset = be16toh(iv->offset_size);
7912                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7913                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7914                 if (offset >= 0x1000)
7915                         goto fail;
7916                 if (bit32) {
7917                         if (array_size < sizeof(iv->data.d32))
7918                                 goto fail;
7919                         array_size -= sizeof(iv->data.d32);
7920                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7921                         iv = GET_NEXTIV32(iv);
7922                 } else {
7923
7924                         if (array_size < sizeof(iv->data.d16))
7925                                 goto fail;
7926                         array_size -= sizeof(iv->data.d16);
7927                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7928
7929                         iv = GET_NEXTIV16(iv);
7930                 }
7931         }
7932         if (array_size != 0)
7933                 goto fail;
7934         return (0);
7935 fail:
7936         device_printf(sc->sc_dev, "initvals: invalid format\n");
7937         return (EPROTO);
7938 #undef GET_NEXTIV16
7939 #undef GET_NEXTIV32
7940 }
7941
7942 static int
7943 bwn_switch_channel(struct bwn_mac *mac, int chan)
7944 {
7945         struct bwn_phy *phy = &(mac->mac_phy);
7946         struct bwn_softc *sc = mac->mac_sc;
7947         struct ifnet *ifp = sc->sc_ifp;
7948         struct ieee80211com *ic = ifp->if_l2com;
7949         uint16_t channelcookie, savedcookie;
7950         int error;
7951
7952         if (chan == 0xffff)
7953                 chan = phy->get_default_chan(mac);
7954
7955         channelcookie = chan;
7956         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7957                 channelcookie |= 0x100;
7958         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7959         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7960         error = phy->switch_channel(mac, chan);
7961         if (error)
7962                 goto fail;
7963
7964         mac->mac_phy.chan = chan;
7965         DELAY(8000);
7966         return (0);
7967 fail:
7968         device_printf(sc->sc_dev, "failed to switch channel\n");
7969         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7970         return (error);
7971 }
7972
7973 static uint16_t
7974 bwn_ant2phy(int antenna)
7975 {
7976
7977         switch (antenna) {
7978         case BWN_ANT0:
7979                 return (BWN_TX_PHY_ANT0);
7980         case BWN_ANT1:
7981                 return (BWN_TX_PHY_ANT1);
7982         case BWN_ANT2:
7983                 return (BWN_TX_PHY_ANT2);
7984         case BWN_ANT3:
7985                 return (BWN_TX_PHY_ANT3);
7986         case BWN_ANTAUTO:
7987                 return (BWN_TX_PHY_ANT01AUTO);
7988         }
7989         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7990         return (0);
7991 }
7992
7993 static void
7994 bwn_wme_load(struct bwn_mac *mac)
7995 {
7996         struct bwn_softc *sc = mac->mac_sc;
7997         int i;
7998
7999         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8000             ("%s:%d: fail", __func__, __LINE__));
8001
8002         bwn_mac_suspend(mac);
8003         for (i = 0; i < N(sc->sc_wmeParams); i++)
8004                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8005                     bwn_wme_shm_offsets[i]);
8006         bwn_mac_enable(mac);
8007 }
8008
8009 static void
8010 bwn_wme_loadparams(struct bwn_mac *mac,
8011     const struct wmeParams *p, uint16_t shm_offset)
8012 {
8013 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8014         struct bwn_softc *sc = mac->mac_sc;
8015         uint16_t params[BWN_NR_WMEPARAMS];
8016         int slot, tmp;
8017         unsigned int i;
8018
8019         slot = BWN_READ_2(mac, BWN_RNG) &
8020             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8021
8022         memset(&params, 0, sizeof(params));
8023
8024         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8025             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8026             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8027
8028         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8029         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8030         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8031         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8032         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8033         params[BWN_WMEPARAM_BSLOTS] = slot;
8034         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8035
8036         for (i = 0; i < N(params); i++) {
8037                 if (i == BWN_WMEPARAM_STATUS) {
8038                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8039                             shm_offset + (i * 2));
8040                         tmp |= 0x100;
8041                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8042                             tmp);
8043                 } else {
8044                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8045                             params[i]);
8046                 }
8047         }
8048 }
8049
8050 static void
8051 bwn_mac_write_bssid(struct bwn_mac *mac)
8052 {
8053         struct bwn_softc *sc = mac->mac_sc;
8054         uint32_t tmp;
8055         int i;
8056         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8057
8058         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8059         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8060         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8061             IEEE80211_ADDR_LEN);
8062
8063         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8064                 tmp = (uint32_t) (mac_bssid[i + 0]);
8065                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8066                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8067                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8068                 bwn_ram_write(mac, 0x20 + i, tmp);
8069         }
8070 }
8071
8072 static void
8073 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8074     const uint8_t *macaddr)
8075 {
8076         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8077         uint16_t data;
8078
8079         if (!mac)
8080                 macaddr = zero;
8081
8082         offset |= 0x0020;
8083         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8084
8085         data = macaddr[0];
8086         data |= macaddr[1] << 8;
8087         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8088         data = macaddr[2];
8089         data |= macaddr[3] << 8;
8090         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8091         data = macaddr[4];
8092         data |= macaddr[5] << 8;
8093         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8094 }
8095
8096 static void
8097 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8098     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8099 {
8100         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8101         uint8_t per_sta_keys_start = 8;
8102
8103         if (BWN_SEC_NEWAPI(mac))
8104                 per_sta_keys_start = 4;
8105
8106         KASSERT(index < mac->mac_max_nr_keys,
8107             ("%s:%d: fail", __func__, __LINE__));
8108         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8109             ("%s:%d: fail", __func__, __LINE__));
8110
8111         if (index >= per_sta_keys_start)
8112                 bwn_key_macwrite(mac, index, NULL);
8113         if (key)
8114                 memcpy(buf, key, key_len);
8115         bwn_key_write(mac, index, algorithm, buf);
8116         if (index >= per_sta_keys_start)
8117                 bwn_key_macwrite(mac, index, mac_addr);
8118
8119         mac->mac_key[index].algorithm = algorithm;
8120 }
8121
8122 static void
8123 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8124 {
8125         struct bwn_softc *sc = mac->mac_sc;
8126         uint32_t addrtmp[2] = { 0, 0 };
8127         uint8_t start = 8;
8128
8129         if (BWN_SEC_NEWAPI(mac))
8130                 start = 4;
8131
8132         KASSERT(index >= start,
8133             ("%s:%d: fail", __func__, __LINE__));
8134         index -= start;
8135
8136         if (addr) {
8137                 addrtmp[0] = addr[0];
8138                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8139                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8140                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8141                 addrtmp[1] = addr[4];
8142                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8143         }
8144
8145         if (siba_get_revid(sc->sc_dev) >= 5) {
8146                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8147                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8148         } else {
8149                 if (index >= 8) {
8150                         bwn_shm_write_4(mac, BWN_SHARED,
8151                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8152                         bwn_shm_write_2(mac, BWN_SHARED,
8153                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8154                 }
8155         }
8156 }
8157
8158 static void
8159 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8160     const uint8_t *key)
8161 {
8162         unsigned int i;
8163         uint32_t offset;
8164         uint16_t kidx, value;
8165
8166         kidx = BWN_SEC_KEY2FW(mac, index);
8167         bwn_shm_write_2(mac, BWN_SHARED,
8168             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8169
8170         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8171         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8172                 value = key[i];
8173                 value |= (uint16_t)(key[i + 1]) << 8;
8174                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8175         }
8176 }
8177
8178 static void
8179 bwn_phy_exit(struct bwn_mac *mac)
8180 {
8181
8182         mac->mac_phy.rf_onoff(mac, 0);
8183         if (mac->mac_phy.exit != NULL)
8184                 mac->mac_phy.exit(mac);
8185 }
8186
8187 static void
8188 bwn_dma_free(struct bwn_mac *mac)
8189 {
8190         struct bwn_dma *dma;
8191
8192         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8193                 return;
8194         dma = &mac->mac_method.dma;
8195
8196         bwn_dma_ringfree(&dma->rx);
8197         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8198         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8199         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8200         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8201         bwn_dma_ringfree(&dma->mcast);
8202 }
8203
8204 static void
8205 bwn_core_stop(struct bwn_mac *mac)
8206 {
8207         struct bwn_softc *sc = mac->mac_sc;
8208
8209         BWN_ASSERT_LOCKED(sc);
8210
8211         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8212                 return;
8213
8214         callout_stop(&sc->sc_rfswitch_ch);
8215         callout_stop(&sc->sc_task_ch);
8216         callout_stop(&sc->sc_watchdog_ch);
8217         sc->sc_watchdog_timer = 0;
8218         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8219         BWN_READ_4(mac, BWN_INTR_MASK);
8220         bwn_mac_suspend(mac);
8221
8222         mac->mac_status = BWN_MAC_STATUS_INITED;
8223 }
8224
8225 static int
8226 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8227 {
8228         struct bwn_mac *up_dev = NULL;
8229         struct bwn_mac *down_dev;
8230         struct bwn_mac *mac;
8231         int err, status;
8232         uint8_t gmode;
8233
8234         BWN_ASSERT_LOCKED(sc);
8235
8236         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8237                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8238                     mac->mac_phy.supports_2ghz) {
8239                         up_dev = mac;
8240                         gmode = 1;
8241                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8242                     mac->mac_phy.supports_5ghz) {
8243                         up_dev = mac;
8244                         gmode = 0;
8245                 } else {
8246                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8247                         return (EINVAL);
8248                 }
8249                 if (up_dev != NULL)
8250                         break;
8251         }
8252         if (up_dev == NULL) {
8253                 device_printf(sc->sc_dev, "Could not find a device\n");
8254                 return (ENODEV);
8255         }
8256         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8257                 return (0);
8258
8259         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8260             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8261
8262         down_dev = sc->sc_curmac;
8263         status = down_dev->mac_status;
8264         if (status >= BWN_MAC_STATUS_STARTED)
8265                 bwn_core_stop(down_dev);
8266         if (status >= BWN_MAC_STATUS_INITED)
8267                 bwn_core_exit(down_dev);
8268
8269         if (down_dev != up_dev)
8270                 bwn_phy_reset(down_dev);
8271
8272         up_dev->mac_phy.gmode = gmode;
8273         if (status >= BWN_MAC_STATUS_INITED) {
8274                 err = bwn_core_init(up_dev);
8275                 if (err) {
8276                         device_printf(sc->sc_dev,
8277                             "fatal: failed to initialize for %s-GHz\n",
8278                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8279                         goto fail;
8280                 }
8281         }
8282         if (status >= BWN_MAC_STATUS_STARTED)
8283                 bwn_core_start(up_dev);
8284         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8285         sc->sc_curmac = up_dev;
8286
8287         return (0);
8288 fail:
8289         sc->sc_curmac = NULL;
8290         return (err);
8291 }
8292
8293 static void
8294 bwn_rf_turnon(struct bwn_mac *mac)
8295 {
8296
8297         bwn_mac_suspend(mac);
8298         mac->mac_phy.rf_onoff(mac, 1);
8299         mac->mac_phy.rf_on = 1;
8300         bwn_mac_enable(mac);
8301 }
8302
8303 static void
8304 bwn_rf_turnoff(struct bwn_mac *mac)
8305 {
8306
8307         bwn_mac_suspend(mac);
8308         mac->mac_phy.rf_onoff(mac, 0);
8309         mac->mac_phy.rf_on = 0;
8310         bwn_mac_enable(mac);
8311 }
8312
8313 static void
8314 bwn_phy_reset(struct bwn_mac *mac)
8315 {
8316         struct bwn_softc *sc = mac->mac_sc;
8317
8318         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8319             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8320              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8321         DELAY(1000);
8322         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8323             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8324             BWN_TGSLOW_PHYRESET);
8325         DELAY(1000);
8326 }
8327
8328 static int
8329 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8330 {
8331         struct bwn_vap *bvp = BWN_VAP(vap);
8332         struct ieee80211com *ic= vap->iv_ic;
8333         struct ifnet *ifp = ic->ic_ifp;
8334         enum ieee80211_state ostate = vap->iv_state;
8335         struct bwn_softc *sc = ifp->if_softc;
8336         struct bwn_mac *mac = sc->sc_curmac;
8337         int error;
8338
8339         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8340             ieee80211_state_name[vap->iv_state],
8341             ieee80211_state_name[nstate]);
8342
8343         error = bvp->bv_newstate(vap, nstate, arg);
8344         if (error != 0)
8345                 return (error);
8346
8347         BWN_LOCK(sc);
8348
8349         bwn_led_newstate(mac, nstate);
8350
8351         /*
8352          * Clear the BSSID when we stop a STA
8353          */
8354         if (vap->iv_opmode == IEEE80211_M_STA) {
8355                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8356                         /*
8357                          * Clear out the BSSID.  If we reassociate to
8358                          * the same AP, this will reinialize things
8359                          * correctly...
8360                          */
8361                         if (ic->ic_opmode == IEEE80211_M_STA &&
8362                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8363                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8364                                 bwn_set_macaddr(mac);
8365                         }
8366                 }
8367         }
8368
8369         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8370             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8371                 /* XXX nothing to do? */
8372         } else if (nstate == IEEE80211_S_RUN) {
8373                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8374                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8375                 bwn_set_opmode(mac);
8376                 bwn_set_pretbtt(mac);
8377                 bwn_spu_setdelay(mac, 0);
8378                 bwn_set_macaddr(mac);
8379         }
8380
8381         BWN_UNLOCK(sc);
8382
8383         return (error);
8384 }
8385
8386 static void
8387 bwn_set_pretbtt(struct bwn_mac *mac)
8388 {
8389         struct bwn_softc *sc = mac->mac_sc;
8390         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8391         uint16_t pretbtt;
8392
8393         if (ic->ic_opmode == IEEE80211_M_IBSS)
8394                 pretbtt = 2;
8395         else
8396                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8397         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8398         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8399 }
8400
8401 static int
8402 bwn_intr(void *arg)
8403 {
8404         struct bwn_mac *mac = arg;
8405         struct bwn_softc *sc = mac->mac_sc;
8406         uint32_t reason;
8407
8408         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8409             (sc->sc_flags & BWN_FLAG_INVALID))
8410                 return (FILTER_STRAY);
8411
8412         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8413         if (reason == 0xffffffff)       /* shared IRQ */
8414                 return (FILTER_STRAY);
8415         reason &= mac->mac_intr_mask;
8416         if (reason == 0)
8417                 return (FILTER_HANDLED);
8418
8419         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8420         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8421         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8422         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8423         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8424         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8425         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8426         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8427         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8428         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8429         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8430
8431         /* Disable interrupts. */
8432         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8433
8434         mac->mac_reason_intr = reason;
8435
8436         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8437         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8438
8439         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8440         return (FILTER_HANDLED);
8441 }
8442
8443 static void
8444 bwn_intrtask(void *arg, int npending)
8445 {
8446         struct bwn_mac *mac = arg;
8447         struct bwn_softc *sc = mac->mac_sc;
8448         struct ifnet *ifp = sc->sc_ifp;
8449         uint32_t merged = 0;
8450         int i, tx = 0, rx = 0;
8451
8452         BWN_LOCK(sc);
8453         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8454             (sc->sc_flags & BWN_FLAG_INVALID)) {
8455                 BWN_UNLOCK(sc);
8456                 return;
8457         }
8458
8459         for (i = 0; i < N(mac->mac_reason); i++)
8460                 merged |= mac->mac_reason[i];
8461
8462         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8463                 device_printf(sc->sc_dev, "MAC trans error\n");
8464
8465         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8466                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8467                 mac->mac_phy.txerrors--;
8468                 if (mac->mac_phy.txerrors == 0) {
8469                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8470                         bwn_restart(mac, "PHY TX errors");
8471                 }
8472         }
8473
8474         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8475                 if (merged & BWN_DMAINTR_FATALMASK) {
8476                         device_printf(sc->sc_dev,
8477                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8478                             mac->mac_reason[0], mac->mac_reason[1],
8479                             mac->mac_reason[2], mac->mac_reason[3],
8480                             mac->mac_reason[4], mac->mac_reason[5]);
8481                         bwn_restart(mac, "DMA error");
8482                         BWN_UNLOCK(sc);
8483                         return;
8484                 }
8485                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8486                         device_printf(sc->sc_dev,
8487                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8488                             mac->mac_reason[0], mac->mac_reason[1],
8489                             mac->mac_reason[2], mac->mac_reason[3],
8490                             mac->mac_reason[4], mac->mac_reason[5]);
8491                 }
8492         }
8493
8494         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8495                 bwn_intr_ucode_debug(mac);
8496         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8497                 bwn_intr_tbtt_indication(mac);
8498         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8499                 bwn_intr_atim_end(mac);
8500         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8501                 bwn_intr_beacon(mac);
8502         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8503                 bwn_intr_pmq(mac);
8504         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8505                 bwn_intr_noise(mac);
8506
8507         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8508                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8509                         bwn_dma_rx(mac->mac_method.dma.rx);
8510                         rx = 1;
8511                 }
8512         } else
8513                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8514
8515         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8519         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8520
8521         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8522                 bwn_intr_txeof(mac);
8523                 tx = 1;
8524         }
8525
8526         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8527
8528         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8529                 int evt = BWN_LED_EVENT_NONE;
8530
8531                 if (tx && rx) {
8532                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8533                                 evt = BWN_LED_EVENT_RX;
8534                         else
8535                                 evt = BWN_LED_EVENT_TX;
8536                 } else if (tx) {
8537                         evt = BWN_LED_EVENT_TX;
8538                 } else if (rx) {
8539                         evt = BWN_LED_EVENT_RX;
8540                 } else if (rx == 0) {
8541                         evt = BWN_LED_EVENT_POLL;
8542                 }
8543
8544                 if (evt != BWN_LED_EVENT_NONE)
8545                         bwn_led_event(mac, evt);
8546        }
8547
8548         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8549                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8550                         bwn_start_locked(ifp);
8551         }
8552
8553         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8554         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8555
8556         BWN_UNLOCK(sc);
8557 }
8558
8559 static void
8560 bwn_restart(struct bwn_mac *mac, const char *msg)
8561 {
8562         struct bwn_softc *sc = mac->mac_sc;
8563         struct ifnet *ifp = sc->sc_ifp;
8564         struct ieee80211com *ic = ifp->if_l2com;
8565
8566         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8567                 return;
8568
8569         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8570         ieee80211_runtask(ic, &mac->mac_hwreset);
8571 }
8572
8573 static void
8574 bwn_intr_ucode_debug(struct bwn_mac *mac)
8575 {
8576         struct bwn_softc *sc = mac->mac_sc;
8577         uint16_t reason;
8578
8579         if (mac->mac_fw.opensource == 0)
8580                 return;
8581
8582         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8583         switch (reason) {
8584         case BWN_DEBUGINTR_PANIC:
8585                 bwn_handle_fwpanic(mac);
8586                 break;
8587         case BWN_DEBUGINTR_DUMP_SHM:
8588                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8589                 break;
8590         case BWN_DEBUGINTR_DUMP_REGS:
8591                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8592                 break;
8593         case BWN_DEBUGINTR_MARKER:
8594                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8595                 break;
8596         default:
8597                 device_printf(sc->sc_dev,
8598                     "ucode debug unknown reason: %#x\n", reason);
8599         }
8600
8601         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8602             BWN_DEBUGINTR_ACK);
8603 }
8604
8605 static void
8606 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8607 {
8608         struct bwn_softc *sc = mac->mac_sc;
8609         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8610
8611         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8612                 bwn_psctl(mac, 0);
8613         if (ic->ic_opmode == IEEE80211_M_IBSS)
8614                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8615 }
8616
8617 static void
8618 bwn_intr_atim_end(struct bwn_mac *mac)
8619 {
8620
8621         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8622                 BWN_WRITE_4(mac, BWN_MACCMD,
8623                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8624                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8625         }
8626 }
8627
8628 static void
8629 bwn_intr_beacon(struct bwn_mac *mac)
8630 {
8631         struct bwn_softc *sc = mac->mac_sc;
8632         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8633         uint32_t cmd, beacon0, beacon1;
8634
8635         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8636             ic->ic_opmode == IEEE80211_M_MBSS)
8637                 return;
8638
8639         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8640
8641         cmd = BWN_READ_4(mac, BWN_MACCMD);
8642         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8643         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8644
8645         if (beacon0 && beacon1) {
8646                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8647                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8648                 return;
8649         }
8650
8651         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8652                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8653                 bwn_load_beacon0(mac);
8654                 bwn_load_beacon1(mac);
8655                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8656                 cmd |= BWN_MACCMD_BEACON0_VALID;
8657                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8658         } else {
8659                 if (!beacon0) {
8660                         bwn_load_beacon0(mac);
8661                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8662                         cmd |= BWN_MACCMD_BEACON0_VALID;
8663                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8664                 } else if (!beacon1) {
8665                         bwn_load_beacon1(mac);
8666                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8667                         cmd |= BWN_MACCMD_BEACON1_VALID;
8668                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8669                 }
8670         }
8671 }
8672
8673 static void
8674 bwn_intr_pmq(struct bwn_mac *mac)
8675 {
8676         uint32_t tmp;
8677
8678         while (1) {
8679                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8680                 if (!(tmp & 0x00000008))
8681                         break;
8682         }
8683         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8684 }
8685
8686 static void
8687 bwn_intr_noise(struct bwn_mac *mac)
8688 {
8689         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8690         uint16_t tmp;
8691         uint8_t noise[4];
8692         uint8_t i, j;
8693         int32_t average;
8694
8695         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8696                 return;
8697
8698         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8699         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8700         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8701             noise[3] == 0x7f)
8702                 goto new;
8703
8704         KASSERT(mac->mac_noise.noi_nsamples < 8,
8705             ("%s:%d: fail", __func__, __LINE__));
8706         i = mac->mac_noise.noi_nsamples;
8707         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8708         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8709         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8710         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8711         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8712         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8713         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8714         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8715         mac->mac_noise.noi_nsamples++;
8716         if (mac->mac_noise.noi_nsamples == 8) {
8717                 average = 0;
8718                 for (i = 0; i < 8; i++) {
8719                         for (j = 0; j < 4; j++)
8720                                 average += mac->mac_noise.noi_samples[i][j];
8721                 }
8722                 average = (((average / 32) * 125) + 64) / 128;
8723                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8724                 if (tmp >= 8)
8725                         average += 2;
8726                 else
8727                         average -= 25;
8728                 average -= (tmp == 8) ? 72 : 48;
8729
8730                 mac->mac_stats.link_noise = average;
8731                 mac->mac_noise.noi_running = 0;
8732                 return;
8733         }
8734 new:
8735         bwn_noise_gensample(mac);
8736 }
8737
8738 static int
8739 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8740 {
8741         struct bwn_mac *mac = prq->prq_mac;
8742         struct bwn_softc *sc = mac->mac_sc;
8743         unsigned int i;
8744
8745         BWN_ASSERT_LOCKED(sc);
8746
8747         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8748                 return (0);
8749
8750         for (i = 0; i < 5000; i++) {
8751                 if (bwn_pio_rxeof(prq) == 0)
8752                         break;
8753         }
8754         if (i >= 5000)
8755                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8756         return ((i > 0) ? 1 : 0);
8757 }
8758
8759 static void
8760 bwn_dma_rx(struct bwn_dma_ring *dr)
8761 {
8762         int slot, curslot;
8763
8764         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8765         curslot = dr->get_curslot(dr);
8766         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8767             ("%s:%d: fail", __func__, __LINE__));
8768
8769         slot = dr->dr_curslot;
8770         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8771                 bwn_dma_rxeof(dr, &slot);
8772
8773         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8774             BUS_DMASYNC_PREWRITE);
8775
8776         dr->set_curslot(dr, slot);
8777         dr->dr_curslot = slot;
8778 }
8779
8780 static void
8781 bwn_intr_txeof(struct bwn_mac *mac)
8782 {
8783         struct bwn_txstatus stat;
8784         uint32_t stat0, stat1;
8785         uint16_t tmp;
8786
8787         BWN_ASSERT_LOCKED(mac->mac_sc);
8788
8789         while (1) {
8790                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8791                 if (!(stat0 & 0x00000001))
8792                         break;
8793                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8794
8795                 stat.cookie = (stat0 >> 16);
8796                 stat.seq = (stat1 & 0x0000ffff);
8797                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8798                 tmp = (stat0 & 0x0000ffff);
8799                 stat.framecnt = ((tmp & 0xf000) >> 12);
8800                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8801                 stat.sreason = ((tmp & 0x001c) >> 2);
8802                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8803                 stat.im = (tmp & 0x0040) ? 1 : 0;
8804                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8805                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8806
8807                 bwn_handle_txeof(mac, &stat);
8808         }
8809 }
8810
8811 static void
8812 bwn_hwreset(void *arg, int npending)
8813 {
8814         struct bwn_mac *mac = arg;
8815         struct bwn_softc *sc = mac->mac_sc;
8816         int error = 0;
8817         int prev_status;
8818
8819         BWN_LOCK(sc);
8820
8821         prev_status = mac->mac_status;
8822         if (prev_status >= BWN_MAC_STATUS_STARTED)
8823                 bwn_core_stop(mac);
8824         if (prev_status >= BWN_MAC_STATUS_INITED)
8825                 bwn_core_exit(mac);
8826
8827         if (prev_status >= BWN_MAC_STATUS_INITED) {
8828                 error = bwn_core_init(mac);
8829                 if (error)
8830                         goto out;
8831         }
8832         if (prev_status >= BWN_MAC_STATUS_STARTED)
8833                 bwn_core_start(mac);
8834 out:
8835         if (error) {
8836                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8837                 sc->sc_curmac = NULL;
8838         }
8839         BWN_UNLOCK(sc);
8840 }
8841
8842 static void
8843 bwn_handle_fwpanic(struct bwn_mac *mac)
8844 {
8845         struct bwn_softc *sc = mac->mac_sc;
8846         uint16_t reason;
8847
8848         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8849         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8850
8851         if (reason == BWN_FWPANIC_RESTART)
8852                 bwn_restart(mac, "ucode panic");
8853 }
8854
8855 static void
8856 bwn_load_beacon0(struct bwn_mac *mac)
8857 {
8858
8859         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8860 }
8861
8862 static void
8863 bwn_load_beacon1(struct bwn_mac *mac)
8864 {
8865
8866         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8867 }
8868
8869 static uint32_t
8870 bwn_jssi_read(struct bwn_mac *mac)
8871 {
8872         uint32_t val = 0;
8873
8874         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8875         val <<= 16;
8876         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8877
8878         return (val);
8879 }
8880
8881 static void
8882 bwn_noise_gensample(struct bwn_mac *mac)
8883 {
8884         uint32_t jssi = 0x7f7f7f7f;
8885
8886         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8887         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8888         BWN_WRITE_4(mac, BWN_MACCMD,
8889             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8890 }
8891
8892 static int
8893 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8894 {
8895         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8896
8897         return (dr->dr_numslots - dr->dr_usedslot);
8898 }
8899
8900 static int
8901 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8902 {
8903         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8904
8905         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8906             ("%s:%d: fail", __func__, __LINE__));
8907         if (slot == dr->dr_numslots - 1)
8908                 return (0);
8909         return (slot + 1);
8910 }
8911
8912 static void
8913 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8914 {
8915         struct bwn_mac *mac = dr->dr_mac;
8916         struct bwn_softc *sc = mac->mac_sc;
8917         struct bwn_dma *dma = &mac->mac_method.dma;
8918         struct bwn_dmadesc_generic *desc;
8919         struct bwn_dmadesc_meta *meta;
8920         struct bwn_rxhdr4 *rxhdr;
8921         struct ifnet *ifp = sc->sc_ifp;
8922         struct mbuf *m;
8923         uint32_t macstat;
8924         int32_t tmp;
8925         int cnt = 0;
8926         uint16_t len;
8927
8928         dr->getdesc(dr, *slot, &desc, &meta);
8929
8930         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8931         m = meta->mt_m;
8932
8933         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8934                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8935                 return;
8936         }
8937
8938         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8939         len = le16toh(rxhdr->frame_len);
8940         if (len <= 0) {
8941                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8942                 return;
8943         }
8944         if (bwn_dma_check_redzone(dr, m)) {
8945                 device_printf(sc->sc_dev, "redzone error.\n");
8946                 bwn_dma_set_redzone(dr, m);
8947                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8948                     BUS_DMASYNC_PREWRITE);
8949                 return;
8950         }
8951         if (len > dr->dr_rx_bufsize) {
8952                 tmp = len;
8953                 while (1) {
8954                         dr->getdesc(dr, *slot, &desc, &meta);
8955                         bwn_dma_set_redzone(dr, meta->mt_m);
8956                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8957                             BUS_DMASYNC_PREWRITE);
8958                         *slot = bwn_dma_nextslot(dr, *slot);
8959                         cnt++;
8960                         tmp -= dr->dr_rx_bufsize;
8961                         if (tmp <= 0)
8962                                 break;
8963                 }
8964                 device_printf(sc->sc_dev, "too small buffer "
8965                        "(len %u buffer %u dropped %d)\n",
8966                        len, dr->dr_rx_bufsize, cnt);
8967                 return;
8968         }
8969         macstat = le32toh(rxhdr->mac_status);
8970         if (macstat & BWN_RX_MAC_FCSERR) {
8971                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8972                         device_printf(sc->sc_dev, "RX drop\n");
8973                         return;
8974                 }
8975         }
8976
8977         m->m_pkthdr.rcvif = ifp;
8978         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8979         m_adj(m, dr->dr_frameoffset);
8980
8981         bwn_rxeof(dr->dr_mac, m, rxhdr);
8982 }
8983
8984 static void
8985 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8986 {
8987         struct bwn_dma_ring *dr;
8988         struct bwn_dmadesc_generic *desc;
8989         struct bwn_dmadesc_meta *meta;
8990         struct bwn_pio_txqueue *tq;
8991         struct bwn_pio_txpkt *tp = NULL;
8992         struct bwn_softc *sc = mac->mac_sc;
8993         struct bwn_stats *stats = &mac->mac_stats;
8994         struct ieee80211_node *ni;
8995         struct ieee80211vap *vap;
8996         int retrycnt = 0, slot;
8997
8998         BWN_ASSERT_LOCKED(mac->mac_sc);
8999
9000         if (status->im)
9001                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9002         if (status->ampdu)
9003                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9004         if (status->rtscnt) {
9005                 if (status->rtscnt == 0xf)
9006                         stats->rtsfail++;
9007                 else
9008                         stats->rts++;
9009         }
9010
9011         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9012                 if (status->ack) {
9013                         dr = bwn_dma_parse_cookie(mac, status,
9014                             status->cookie, &slot);
9015                         if (dr == NULL) {
9016                                 device_printf(sc->sc_dev,
9017                                     "failed to parse cookie\n");
9018                                 return;
9019                         }
9020                         while (1) {
9021                                 dr->getdesc(dr, slot, &desc, &meta);
9022                                 if (meta->mt_islast) {
9023                                         ni = meta->mt_ni;
9024                                         vap = ni->ni_vap;
9025                                         ieee80211_ratectl_tx_complete(vap, ni,
9026                                             status->ack ?
9027                                               IEEE80211_RATECTL_TX_SUCCESS :
9028                                               IEEE80211_RATECTL_TX_FAILURE,
9029                                             &retrycnt, 0);
9030                                         break;
9031                                 }
9032                                 slot = bwn_dma_nextslot(dr, slot);
9033                         }
9034                 }
9035                 bwn_dma_handle_txeof(mac, status);
9036         } else {
9037                 if (status->ack) {
9038                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9039                         if (tq == NULL) {
9040                                 device_printf(sc->sc_dev,
9041                                     "failed to parse cookie\n");
9042                                 return;
9043                         }
9044                         ni = tp->tp_ni;
9045                         vap = ni->ni_vap;
9046                         ieee80211_ratectl_tx_complete(vap, ni,
9047                             status->ack ?
9048                               IEEE80211_RATECTL_TX_SUCCESS :
9049                               IEEE80211_RATECTL_TX_FAILURE,
9050                             &retrycnt, 0);
9051                 }
9052                 bwn_pio_handle_txeof(mac, status);
9053         }
9054
9055         bwn_phy_txpower_check(mac, 0);
9056 }
9057
9058 static uint8_t
9059 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9060 {
9061         struct bwn_mac *mac = prq->prq_mac;
9062         struct bwn_softc *sc = mac->mac_sc;
9063         struct bwn_rxhdr4 rxhdr;
9064         struct ifnet *ifp = sc->sc_ifp;
9065         struct mbuf *m;
9066         uint32_t ctl32, macstat, v32;
9067         unsigned int i, padding;
9068         uint16_t ctl16, len, totlen, v16;
9069         unsigned char *mp;
9070         char *data;
9071
9072         memset(&rxhdr, 0, sizeof(rxhdr));
9073
9074         if (prq->prq_rev >= 8) {
9075                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9076                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9077                         return (0);
9078                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9079                     BWN_PIO8_RXCTL_FRAMEREADY);
9080                 for (i = 0; i < 10; i++) {
9081                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9082                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9083                                 goto ready;
9084                         DELAY(10);
9085                 }
9086         } else {
9087                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9088                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9089                         return (0);
9090                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9091                     BWN_PIO_RXCTL_FRAMEREADY);
9092                 for (i = 0; i < 10; i++) {
9093                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9094                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9095                                 goto ready;
9096                         DELAY(10);
9097                 }
9098         }
9099         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9100         return (1);
9101 ready:
9102         if (prq->prq_rev >= 8)
9103                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9104                     prq->prq_base + BWN_PIO8_RXDATA);
9105         else
9106                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9107                     prq->prq_base + BWN_PIO_RXDATA);
9108         len = le16toh(rxhdr.frame_len);
9109         if (len > 0x700) {
9110                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9111                 goto error;
9112         }
9113         if (len == 0) {
9114                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9115                 goto error;
9116         }
9117
9118         macstat = le32toh(rxhdr.mac_status);
9119         if (macstat & BWN_RX_MAC_FCSERR) {
9120                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9121                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9122                         goto error;
9123                 }
9124         }
9125
9126         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9127         totlen = len + padding;
9128         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9129         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9130         if (m == NULL) {
9131                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9132                 goto error;
9133         }
9134         mp = mtod(m, unsigned char *);
9135         if (prq->prq_rev >= 8) {
9136                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9137                     prq->prq_base + BWN_PIO8_RXDATA);
9138                 if (totlen & 3) {
9139                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9140                         data = &(mp[totlen - 1]);
9141                         switch (totlen & 3) {
9142                         case 3:
9143                                 *data = (v32 >> 16);
9144                                 data--;
9145                         case 2:
9146                                 *data = (v32 >> 8);
9147                                 data--;
9148                         case 1:
9149                                 *data = v32;
9150                         }
9151                 }
9152         } else {
9153                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9154                     prq->prq_base + BWN_PIO_RXDATA);
9155                 if (totlen & 1) {
9156                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9157                         mp[totlen - 1] = v16;
9158                 }
9159         }
9160
9161         m->m_pkthdr.rcvif = ifp;
9162         m->m_len = m->m_pkthdr.len = totlen;
9163
9164         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9165
9166         return (1);
9167 error:
9168         if (prq->prq_rev >= 8)
9169                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9170                     BWN_PIO8_RXCTL_DATAREADY);
9171         else
9172                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9173         return (1);
9174 }
9175
9176 static int
9177 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9178     struct bwn_dmadesc_meta *meta, int init)
9179 {
9180         struct bwn_mac *mac = dr->dr_mac;
9181         struct bwn_dma *dma = &mac->mac_method.dma;
9182         struct bwn_rxhdr4 *hdr;
9183         bus_dmamap_t map;
9184         bus_addr_t paddr;
9185         struct mbuf *m;
9186         int error;
9187
9188         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9189         if (m == NULL) {
9190                 error = ENOBUFS;
9191
9192                 /*
9193                  * If the NIC is up and running, we need to:
9194                  * - Clear RX buffer's header.
9195                  * - Restore RX descriptor settings.
9196                  */
9197                 if (init)
9198                         return (error);
9199                 else
9200                         goto back;
9201         }
9202         m->m_len = m->m_pkthdr.len = MCLBYTES;
9203
9204         bwn_dma_set_redzone(dr, m);
9205
9206         /*
9207          * Try to load RX buf into temporary DMA map
9208          */
9209         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9210             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9211         if (error) {
9212                 m_freem(m);
9213
9214                 /*
9215                  * See the comment above
9216                  */
9217                 if (init)
9218                         return (error);
9219                 else
9220                         goto back;
9221         }
9222
9223         if (!init)
9224                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9225         meta->mt_m = m;
9226         meta->mt_paddr = paddr;
9227
9228         /*
9229          * Swap RX buf's DMA map with the loaded temporary one
9230          */
9231         map = meta->mt_dmap;
9232         meta->mt_dmap = dr->dr_spare_dmap;
9233         dr->dr_spare_dmap = map;
9234
9235 back:
9236         /*
9237          * Clear RX buf header
9238          */
9239         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9240         bzero(hdr, sizeof(*hdr));
9241         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9242             BUS_DMASYNC_PREWRITE);
9243
9244         /*
9245          * Setup RX buf descriptor
9246          */
9247         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9248             sizeof(*hdr), 0, 0, 0);
9249         return (error);
9250 }
9251
9252 static void
9253 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9254                  bus_size_t mapsz __unused, int error)
9255 {
9256
9257         if (!error) {
9258                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9259                 *((bus_addr_t *)arg) = seg->ds_addr;
9260         }
9261 }
9262
9263 static int
9264 bwn_hwrate2ieeerate(int rate)
9265 {
9266
9267         switch (rate) {
9268         case BWN_CCK_RATE_1MB:
9269                 return (2);
9270         case BWN_CCK_RATE_2MB:
9271                 return (4);
9272         case BWN_CCK_RATE_5MB:
9273                 return (11);
9274         case BWN_CCK_RATE_11MB:
9275                 return (22);
9276         case BWN_OFDM_RATE_6MB:
9277                 return (12);
9278         case BWN_OFDM_RATE_9MB:
9279                 return (18);
9280         case BWN_OFDM_RATE_12MB:
9281                 return (24);
9282         case BWN_OFDM_RATE_18MB:
9283                 return (36);
9284         case BWN_OFDM_RATE_24MB:
9285                 return (48);
9286         case BWN_OFDM_RATE_36MB:
9287                 return (72);
9288         case BWN_OFDM_RATE_48MB:
9289                 return (96);
9290         case BWN_OFDM_RATE_54MB:
9291                 return (108);
9292         default:
9293                 printf("Ooops\n");
9294                 return (0);
9295         }
9296 }
9297
9298 static void
9299 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9300 {
9301         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9302         struct bwn_plcp6 *plcp;
9303         struct bwn_softc *sc = mac->mac_sc;
9304         struct ieee80211_frame_min *wh;
9305         struct ieee80211_node *ni;
9306         struct ifnet *ifp = sc->sc_ifp;
9307         struct ieee80211com *ic = ifp->if_l2com;
9308         uint32_t macstat;
9309         int padding, rate, rssi = 0, noise = 0, type;
9310         uint16_t phytype, phystat0, phystat3, chanstat;
9311         unsigned char *mp = mtod(m, unsigned char *);
9312         static int rx_mac_dec_rpt = 0;
9313
9314         BWN_ASSERT_LOCKED(sc);
9315
9316         phystat0 = le16toh(rxhdr->phy_status0);
9317         phystat3 = le16toh(rxhdr->phy_status3);
9318         macstat = le32toh(rxhdr->mac_status);
9319         chanstat = le16toh(rxhdr->channel);
9320         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9321
9322         if (macstat & BWN_RX_MAC_FCSERR)
9323                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9324         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9325                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9326         if (macstat & BWN_RX_MAC_DECERR)
9327                 goto drop;
9328
9329         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9330         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9331                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9332                     m->m_pkthdr.len);
9333                 goto drop;
9334         }
9335         plcp = (struct bwn_plcp6 *)(mp + padding);
9336         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9337         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9338                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9339                     m->m_pkthdr.len);
9340                 goto drop;
9341         }
9342         wh = mtod(m, struct ieee80211_frame_min *);
9343
9344         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9345                 device_printf(sc->sc_dev,
9346                     "RX decryption attempted (old %d keyidx %#x)\n",
9347                     BWN_ISOLDFMT(mac),
9348                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9349
9350         /* XXX calculating RSSI & noise & antenna */
9351
9352         if (phystat0 & BWN_RX_PHYST0_OFDM)
9353                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9354                     phytype == BWN_PHYTYPE_A);
9355         else
9356                 rate = bwn_plcp_get_cckrate(mac, plcp);
9357         if (rate == -1) {
9358                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9359                         goto drop;
9360         }
9361         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9362
9363         /* RX radio tap */
9364         if (ieee80211_radiotap_active(ic))
9365                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9366         m_adj(m, -IEEE80211_CRC_LEN);
9367
9368         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9369         noise = mac->mac_stats.link_noise;
9370
9371         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
9372
9373         BWN_UNLOCK(sc);
9374
9375         ni = ieee80211_find_rxnode(ic, wh);
9376         if (ni != NULL) {
9377                 type = ieee80211_input(ni, m, rssi, noise);
9378                 ieee80211_free_node(ni);
9379         } else
9380                 type = ieee80211_input_all(ic, m, rssi, noise);
9381
9382         BWN_LOCK(sc);
9383         return;
9384 drop:
9385         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9386 }
9387
9388 static void
9389 bwn_dma_handle_txeof(struct bwn_mac *mac,
9390     const struct bwn_txstatus *status)
9391 {
9392         struct bwn_dma *dma = &mac->mac_method.dma;
9393         struct bwn_dma_ring *dr;
9394         struct bwn_dmadesc_generic *desc;
9395         struct bwn_dmadesc_meta *meta;
9396         struct bwn_softc *sc = mac->mac_sc;
9397         struct ieee80211_node *ni;
9398         struct ifnet *ifp = sc->sc_ifp;
9399         struct mbuf *m;
9400         int slot;
9401
9402         BWN_ASSERT_LOCKED(sc);
9403
9404         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9405         if (dr == NULL) {
9406                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9407                 return;
9408         }
9409         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9410
9411         while (1) {
9412                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9413                     ("%s:%d: fail", __func__, __LINE__));
9414                 dr->getdesc(dr, slot, &desc, &meta);
9415
9416                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9417                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9418                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9419                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9420
9421                 if (meta->mt_islast) {
9422                         KASSERT(meta->mt_m != NULL,
9423                             ("%s:%d: fail", __func__, __LINE__));
9424
9425                         ni = meta->mt_ni;
9426                         m = meta->mt_m;
9427                         if (ni != NULL) {
9428                                 /*
9429                                  * Do any tx complete callback. Note this must
9430                                  * be done before releasing the node reference.
9431                                  */
9432                                 if (m->m_flags & M_TXCB)
9433                                         ieee80211_process_callback(ni, m, 0);
9434                                 ieee80211_free_node(ni);
9435                                 meta->mt_ni = NULL;
9436                         }
9437                         m_freem(m);
9438                         meta->mt_m = NULL;
9439                 } else {
9440                         KASSERT(meta->mt_m == NULL,
9441                             ("%s:%d: fail", __func__, __LINE__));
9442                 }
9443
9444                 dr->dr_usedslot--;
9445                 if (meta->mt_islast) {
9446                         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9447                         break;
9448                 }
9449                 slot = bwn_dma_nextslot(dr, slot);
9450         }
9451         sc->sc_watchdog_timer = 0;
9452         if (dr->dr_stop) {
9453                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9454                     ("%s:%d: fail", __func__, __LINE__));
9455                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9456                 dr->dr_stop = 0;
9457         }
9458 }
9459
9460 static void
9461 bwn_pio_handle_txeof(struct bwn_mac *mac,
9462     const struct bwn_txstatus *status)
9463 {
9464         struct bwn_pio_txqueue *tq;
9465         struct bwn_pio_txpkt *tp = NULL;
9466         struct bwn_softc *sc = mac->mac_sc;
9467         struct ifnet *ifp = sc->sc_ifp;
9468
9469         BWN_ASSERT_LOCKED(sc);
9470
9471         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9472         if (tq == NULL)
9473                 return;
9474
9475         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9476         tq->tq_free++;
9477
9478         if (tp->tp_ni != NULL) {
9479                 /*
9480                  * Do any tx complete callback.  Note this must
9481                  * be done before releasing the node reference.
9482                  */
9483                 if (tp->tp_m->m_flags & M_TXCB)
9484                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9485                 ieee80211_free_node(tp->tp_ni);
9486                 tp->tp_ni = NULL;
9487         }
9488         m_freem(tp->tp_m);
9489         tp->tp_m = NULL;
9490         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9491
9492         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9493
9494         sc->sc_watchdog_timer = 0;
9495         if (tq->tq_stop) {
9496                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9497                 tq->tq_stop = 0;
9498         }
9499 }
9500
9501 static void
9502 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9503 {
9504         struct bwn_softc *sc = mac->mac_sc;
9505         struct bwn_phy *phy = &mac->mac_phy;
9506         struct ifnet *ifp = sc->sc_ifp;
9507         struct ieee80211com *ic = ifp->if_l2com;
9508         unsigned long now;
9509         int result;
9510
9511         BWN_GETTIME(now);
9512
9513         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9514                 return;
9515         phy->nexttime = now + 2 * 1000;
9516
9517         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9518             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9519                 return;
9520
9521         if (phy->recalc_txpwr != NULL) {
9522                 result = phy->recalc_txpwr(mac,
9523                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9524                 if (result == BWN_TXPWR_RES_DONE)
9525                         return;
9526                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9527                     ("%s: fail", __func__));
9528                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9529
9530                 ieee80211_runtask(ic, &mac->mac_txpower);
9531         }
9532 }
9533
9534 static uint16_t
9535 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9536 {
9537
9538         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9539 }
9540
9541 static uint32_t
9542 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9543 {
9544
9545         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9546 }
9547
9548 static void
9549 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9550 {
9551
9552         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9553 }
9554
9555 static void
9556 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9557 {
9558
9559         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9560 }
9561
9562 static int
9563 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9564 {
9565
9566         switch (rate) {
9567         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9568         case 12:
9569                 return (BWN_OFDM_RATE_6MB);
9570         case 18:
9571                 return (BWN_OFDM_RATE_9MB);
9572         case 24:
9573                 return (BWN_OFDM_RATE_12MB);
9574         case 36:
9575                 return (BWN_OFDM_RATE_18MB);
9576         case 48:
9577                 return (BWN_OFDM_RATE_24MB);
9578         case 72:
9579                 return (BWN_OFDM_RATE_36MB);
9580         case 96:
9581                 return (BWN_OFDM_RATE_48MB);
9582         case 108:
9583                 return (BWN_OFDM_RATE_54MB);
9584         /* CCK rates (NB: not IEEE std, device-specific) */
9585         case 2:
9586                 return (BWN_CCK_RATE_1MB);
9587         case 4:
9588                 return (BWN_CCK_RATE_2MB);
9589         case 11:
9590                 return (BWN_CCK_RATE_5MB);
9591         case 22:
9592                 return (BWN_CCK_RATE_11MB);
9593         }
9594
9595         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9596         return (BWN_CCK_RATE_1MB);
9597 }
9598
9599 static int
9600 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9601     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9602 {
9603         const struct bwn_phy *phy = &mac->mac_phy;
9604         struct bwn_softc *sc = mac->mac_sc;
9605         struct ieee80211_frame *wh;
9606         struct ieee80211_frame *protwh;
9607         struct ieee80211_frame_cts *cts;
9608         struct ieee80211_frame_rts *rts;
9609         const struct ieee80211_txparam *tp;
9610         struct ieee80211vap *vap = ni->ni_vap;
9611         struct ifnet *ifp = sc->sc_ifp;
9612         struct ieee80211com *ic = ifp->if_l2com;
9613         struct mbuf *mprot;
9614         unsigned int len;
9615         uint32_t macctl = 0;
9616         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9617         uint16_t phyctl = 0;
9618         uint8_t rate, rate_fb;
9619
9620         wh = mtod(m, struct ieee80211_frame *);
9621         memset(txhdr, 0, sizeof(*txhdr));
9622
9623         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9624         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9625         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9626
9627         /*
9628          * Find TX rate
9629          */
9630         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9631         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9632                 rate = rate_fb = tp->mgmtrate;
9633         else if (ismcast)
9634                 rate = rate_fb = tp->mcastrate;
9635         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9636                 rate = rate_fb = tp->ucastrate;
9637         else {
9638                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9639                 rate = ni->ni_txrate;
9640
9641                 if (rix > 0)
9642                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9643                             IEEE80211_RATE_VAL;
9644                 else
9645                         rate_fb = rate;
9646         }
9647
9648         sc->sc_tx_rate = rate;
9649
9650         rate = bwn_ieeerate2hwrate(sc, rate);
9651         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9652
9653         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9654             bwn_plcp_getcck(rate);
9655         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9656         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9657
9658         if ((rate_fb == rate) ||
9659             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9660             (*(u_int16_t *)wh->i_dur == htole16(0)))
9661                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9662         else
9663                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9664                     m->m_pkthdr.len, rate, isshort);
9665
9666         /* XXX TX encryption */
9667         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9668             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9669             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9670             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9671         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9672             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9673
9674         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9675             BWN_TX_EFT_FB_CCK;
9676         txhdr->chan = phy->chan;
9677         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9678             BWN_TX_PHY_ENC_CCK;
9679         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9680              rate == BWN_CCK_RATE_11MB))
9681                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9682
9683         /* XXX TX antenna selection */
9684
9685         switch (bwn_antenna_sanitize(mac, 0)) {
9686         case 0:
9687                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9688                 break;
9689         case 1:
9690                 phyctl |= BWN_TX_PHY_ANT0;
9691                 break;
9692         case 2:
9693                 phyctl |= BWN_TX_PHY_ANT1;
9694                 break;
9695         case 3:
9696                 phyctl |= BWN_TX_PHY_ANT2;
9697                 break;
9698         case 4:
9699                 phyctl |= BWN_TX_PHY_ANT3;
9700                 break;
9701         default:
9702                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9703         }
9704
9705         if (!ismcast)
9706                 macctl |= BWN_TX_MAC_ACK;
9707
9708         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9709         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9710             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9711                 macctl |= BWN_TX_MAC_LONGFRAME;
9712
9713         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9714                 /* XXX RTS rate is always 1MB??? */
9715                 rts_rate = BWN_CCK_RATE_1MB;
9716                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9717
9718                 protdur = ieee80211_compute_duration(ic->ic_rt,
9719                     m->m_pkthdr.len, rate, isshort) +
9720                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9721
9722                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9723                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9724                             (txhdr->body.old.rts_frame) :
9725                             (txhdr->body.new.rts_frame));
9726                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9727                             protdur);
9728                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9729                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9730                             mprot->m_pkthdr.len);
9731                         m_freem(mprot);
9732                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9733                         len = sizeof(struct ieee80211_frame_cts);
9734                 } else {
9735                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9736                             (txhdr->body.old.rts_frame) :
9737                             (txhdr->body.new.rts_frame));
9738                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9739                             isshort);
9740                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9741                             wh->i_addr2, protdur);
9742                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9743                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9744                             mprot->m_pkthdr.len);
9745                         m_freem(mprot);
9746                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9747                         len = sizeof(struct ieee80211_frame_rts);
9748                 }
9749                 len += IEEE80211_CRC_LEN;
9750                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9751                     &txhdr->body.old.rts_plcp :
9752                     &txhdr->body.new.rts_plcp), len, rts_rate);
9753                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9754                     rts_rate_fb);
9755
9756                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9757                     (&txhdr->body.old.rts_frame) :
9758                     (&txhdr->body.new.rts_frame));
9759                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9760
9761                 if (BWN_ISOFDMRATE(rts_rate)) {
9762                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9763                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9764                 } else {
9765                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9766                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9767                 }
9768                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9769                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9770         }
9771
9772         if (BWN_ISOLDFMT(mac))
9773                 txhdr->body.old.cookie = htole16(cookie);
9774         else
9775                 txhdr->body.new.cookie = htole16(cookie);
9776
9777         txhdr->macctl = htole32(macctl);
9778         txhdr->phyctl = htole16(phyctl);
9779
9780         /*
9781          * TX radio tap
9782          */
9783         if (ieee80211_radiotap_active_vap(vap)) {
9784                 sc->sc_tx_th.wt_flags = 0;
9785                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9786                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9787                 if (isshort &&
9788                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9789                      rate == BWN_CCK_RATE_11MB))
9790                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9791                 sc->sc_tx_th.wt_rate = rate;
9792
9793                 ieee80211_radiotap_tx(vap, m);
9794         }
9795
9796         return (0);
9797 }
9798
9799 static void
9800 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9801     const uint8_t rate)
9802 {
9803         uint32_t d, plen;
9804         uint8_t *raw = plcp->o.raw;
9805
9806         if (BWN_ISOFDMRATE(rate)) {
9807                 d = bwn_plcp_getofdm(rate);
9808                 KASSERT(!(octets & 0xf000),
9809                     ("%s:%d: fail", __func__, __LINE__));
9810                 d |= (octets << 5);
9811                 plcp->o.data = htole32(d);
9812         } else {
9813                 plen = octets * 16 / rate;
9814                 if ((octets * 16 % rate) > 0) {
9815                         plen++;
9816                         if ((rate == BWN_CCK_RATE_11MB)
9817                             && ((octets * 8 % 11) < 4)) {
9818                                 raw[1] = 0x84;
9819                         } else
9820                                 raw[1] = 0x04;
9821                 } else
9822                         raw[1] = 0x04;
9823                 plcp->o.data |= htole32(plen << 16);
9824                 raw[0] = bwn_plcp_getcck(rate);
9825         }
9826 }
9827
9828 static uint8_t
9829 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9830 {
9831         struct bwn_softc *sc = mac->mac_sc;
9832         uint8_t mask;
9833
9834         if (n == 0)
9835                 return (0);
9836         if (mac->mac_phy.gmode)
9837                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9838         else
9839                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9840         if (!(mask & (1 << (n - 1))))
9841                 return (0);
9842         return (n);
9843 }
9844
9845 static uint8_t
9846 bwn_get_fbrate(uint8_t bitrate)
9847 {
9848         switch (bitrate) {
9849         case BWN_CCK_RATE_1MB:
9850                 return (BWN_CCK_RATE_1MB);
9851         case BWN_CCK_RATE_2MB:
9852                 return (BWN_CCK_RATE_1MB);
9853         case BWN_CCK_RATE_5MB:
9854                 return (BWN_CCK_RATE_2MB);
9855         case BWN_CCK_RATE_11MB:
9856                 return (BWN_CCK_RATE_5MB);
9857         case BWN_OFDM_RATE_6MB:
9858                 return (BWN_CCK_RATE_5MB);
9859         case BWN_OFDM_RATE_9MB:
9860                 return (BWN_OFDM_RATE_6MB);
9861         case BWN_OFDM_RATE_12MB:
9862                 return (BWN_OFDM_RATE_9MB);
9863         case BWN_OFDM_RATE_18MB:
9864                 return (BWN_OFDM_RATE_12MB);
9865         case BWN_OFDM_RATE_24MB:
9866                 return (BWN_OFDM_RATE_18MB);
9867         case BWN_OFDM_RATE_36MB:
9868                 return (BWN_OFDM_RATE_24MB);
9869         case BWN_OFDM_RATE_48MB:
9870                 return (BWN_OFDM_RATE_36MB);
9871         case BWN_OFDM_RATE_54MB:
9872                 return (BWN_OFDM_RATE_48MB);
9873         }
9874         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9875         return (0);
9876 }
9877
9878 static uint32_t
9879 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9880     uint32_t ctl, const void *_data, int len)
9881 {
9882         struct bwn_softc *sc = mac->mac_sc;
9883         uint32_t value = 0;
9884         const uint8_t *data = _data;
9885
9886         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9887             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9888         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9889
9890         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9891             tq->tq_base + BWN_PIO8_TXDATA);
9892         if (len & 3) {
9893                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9894                     BWN_PIO8_TXCTL_24_31);
9895                 data = &(data[len - 1]);
9896                 switch (len & 3) {
9897                 case 3:
9898                         ctl |= BWN_PIO8_TXCTL_16_23;
9899                         value |= (uint32_t)(*data) << 16;
9900                         data--;
9901                 case 2:
9902                         ctl |= BWN_PIO8_TXCTL_8_15;
9903                         value |= (uint32_t)(*data) << 8;
9904                         data--;
9905                 case 1:
9906                         value |= (uint32_t)(*data);
9907                 }
9908                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9909                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9910         }
9911
9912         return (ctl);
9913 }
9914
9915 static void
9916 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9917     uint16_t offset, uint32_t value)
9918 {
9919
9920         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9921 }
9922
9923 static uint16_t
9924 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9925     uint16_t ctl, const void *_data, int len)
9926 {
9927         struct bwn_softc *sc = mac->mac_sc;
9928         const uint8_t *data = _data;
9929
9930         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9931         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9932
9933         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9934             tq->tq_base + BWN_PIO_TXDATA);
9935         if (len & 1) {
9936                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9937                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9938                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9939         }
9940
9941         return (ctl);
9942 }
9943
9944 static uint16_t
9945 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9946     uint16_t ctl, struct mbuf *m0)
9947 {
9948         int i, j = 0;
9949         uint16_t data = 0;
9950         const uint8_t *buf;
9951         struct mbuf *m = m0;
9952
9953         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9954         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9955
9956         for (; m != NULL; m = m->m_next) {
9957                 buf = mtod(m, const uint8_t *);
9958                 for (i = 0; i < m->m_len; i++) {
9959                         if (!((j++) % 2))
9960                                 data |= buf[i];
9961                         else {
9962                                 data |= (buf[i] << 8);
9963                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9964                                 data = 0;
9965                         }
9966                 }
9967         }
9968         if (m0->m_pkthdr.len % 2) {
9969                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9970                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9971                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9972         }
9973
9974         return (ctl);
9975 }
9976
9977 static void
9978 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9979 {
9980
9981         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9982                 return;
9983         BWN_WRITE_2(mac, 0x684, 510 + time);
9984         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9985 }
9986
9987 static struct bwn_dma_ring *
9988 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9989 {
9990
9991         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9992                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9993
9994         switch (prio) {
9995         case 3:
9996                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9997         case 2:
9998                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9999         case 0:
10000                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10001         case 1:
10002                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10003         }
10004         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10005         return (NULL);
10006 }
10007
10008 static int
10009 bwn_dma_getslot(struct bwn_dma_ring *dr)
10010 {
10011         int slot;
10012
10013         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10014
10015         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10016         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10017         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10018
10019         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10020         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10021         dr->dr_curslot = slot;
10022         dr->dr_usedslot++;
10023
10024         return (slot);
10025 }
10026
10027 static int
10028 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10029 {
10030         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10031         unsigned int a, b, c, d;
10032         unsigned int avg;
10033         uint32_t tmp;
10034
10035         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10036         a = tmp & 0xff;
10037         b = (tmp >> 8) & 0xff;
10038         c = (tmp >> 16) & 0xff;
10039         d = (tmp >> 24) & 0xff;
10040         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10041             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10042                 return (ENOENT);
10043         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10044             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10045             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10046
10047         if (ofdm) {
10048                 a = (a + 32) & 0x3f;
10049                 b = (b + 32) & 0x3f;
10050                 c = (c + 32) & 0x3f;
10051                 d = (d + 32) & 0x3f;
10052         }
10053
10054         avg = (a + b + c + d + 2) / 4;
10055         if (ofdm) {
10056                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10057                     & BWN_HF_4DB_CCK_POWERBOOST)
10058                         avg = (avg >= 13) ? (avg - 13) : 0;
10059         }
10060         return (avg);
10061 }
10062
10063 static void
10064 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10065 {
10066         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10067         int rfatt = *rfattp;
10068         int bbatt = *bbattp;
10069
10070         while (1) {
10071                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10072                         break;
10073                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10074                         break;
10075                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10076                         break;
10077                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10078                         break;
10079                 if (bbatt > lo->bbatt.max) {
10080                         bbatt -= 4;
10081                         rfatt += 1;
10082                         continue;
10083                 }
10084                 if (bbatt < lo->bbatt.min) {
10085                         bbatt += 4;
10086                         rfatt -= 1;
10087                         continue;
10088                 }
10089                 if (rfatt > lo->rfatt.max) {
10090                         rfatt -= 1;
10091                         bbatt += 4;
10092                         continue;
10093                 }
10094                 if (rfatt < lo->rfatt.min) {
10095                         rfatt += 1;
10096                         bbatt -= 4;
10097                         continue;
10098                 }
10099                 break;
10100         }
10101
10102         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10103         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10104 }
10105
10106 static void
10107 bwn_phy_lock(struct bwn_mac *mac)
10108 {
10109         struct bwn_softc *sc = mac->mac_sc;
10110         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10111
10112         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10113             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10114
10115         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10116                 bwn_psctl(mac, BWN_PS_AWAKE);
10117 }
10118
10119 static void
10120 bwn_phy_unlock(struct bwn_mac *mac)
10121 {
10122         struct bwn_softc *sc = mac->mac_sc;
10123         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10124
10125         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10126             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10127
10128         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10129                 bwn_psctl(mac, 0);
10130 }
10131
10132 static void
10133 bwn_rf_lock(struct bwn_mac *mac)
10134 {
10135
10136         BWN_WRITE_4(mac, BWN_MACCTL,
10137             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10138         BWN_READ_4(mac, BWN_MACCTL);
10139         DELAY(10);
10140 }
10141
10142 static void
10143 bwn_rf_unlock(struct bwn_mac *mac)
10144 {
10145
10146         BWN_READ_2(mac, BWN_PHYVER);
10147         BWN_WRITE_4(mac, BWN_MACCTL,
10148             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10149 }
10150
10151 static struct bwn_pio_txqueue *
10152 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10153     struct bwn_pio_txpkt **pack)
10154 {
10155         struct bwn_pio *pio = &mac->mac_method.pio;
10156         struct bwn_pio_txqueue *tq = NULL;
10157         unsigned int index;
10158
10159         switch (cookie & 0xf000) {
10160         case 0x1000:
10161                 tq = &pio->wme[WME_AC_BK];
10162                 break;
10163         case 0x2000:
10164                 tq = &pio->wme[WME_AC_BE];
10165                 break;
10166         case 0x3000:
10167                 tq = &pio->wme[WME_AC_VI];
10168                 break;
10169         case 0x4000:
10170                 tq = &pio->wme[WME_AC_VO];
10171                 break;
10172         case 0x5000:
10173                 tq = &pio->mcast;
10174                 break;
10175         }
10176         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10177         if (tq == NULL)
10178                 return (NULL);
10179         index = (cookie & 0x0fff);
10180         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10181         if (index >= N(tq->tq_pkts))
10182                 return (NULL);
10183         *pack = &tq->tq_pkts[index];
10184         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10185         return (tq);
10186 }
10187
10188 static void
10189 bwn_txpwr(void *arg, int npending)
10190 {
10191         struct bwn_mac *mac = arg;
10192         struct bwn_softc *sc = mac->mac_sc;
10193
10194         BWN_LOCK(sc);
10195         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10196             mac->mac_phy.set_txpwr != NULL)
10197                 mac->mac_phy.set_txpwr(mac);
10198         BWN_UNLOCK(sc);
10199 }
10200
10201 static void
10202 bwn_task_15s(struct bwn_mac *mac)
10203 {
10204         uint16_t reg;
10205
10206         if (mac->mac_fw.opensource) {
10207                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10208                 if (reg) {
10209                         bwn_restart(mac, "fw watchdog");
10210                         return;
10211                 }
10212                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10213         }
10214         if (mac->mac_phy.task_15s)
10215                 mac->mac_phy.task_15s(mac);
10216
10217         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10218 }
10219
10220 static void
10221 bwn_task_30s(struct bwn_mac *mac)
10222 {
10223
10224         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10225                 return;
10226         mac->mac_noise.noi_running = 1;
10227         mac->mac_noise.noi_nsamples = 0;
10228
10229         bwn_noise_gensample(mac);
10230 }
10231
10232 static void
10233 bwn_task_60s(struct bwn_mac *mac)
10234 {
10235
10236         if (mac->mac_phy.task_60s)
10237                 mac->mac_phy.task_60s(mac);
10238         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10239 }
10240
10241 static void
10242 bwn_tasks(void *arg)
10243 {
10244         struct bwn_mac *mac = arg;
10245         struct bwn_softc *sc = mac->mac_sc;
10246
10247         BWN_ASSERT_LOCKED(sc);
10248         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10249                 return;
10250
10251         if (mac->mac_task_state % 4 == 0)
10252                 bwn_task_60s(mac);
10253         if (mac->mac_task_state % 2 == 0)
10254                 bwn_task_30s(mac);
10255         bwn_task_15s(mac);
10256
10257         mac->mac_task_state++;
10258         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10259 }
10260
10261 static int
10262 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10263 {
10264         struct bwn_softc *sc = mac->mac_sc;
10265
10266         KASSERT(a == 0, ("not support APHY\n"));
10267
10268         switch (plcp->o.raw[0] & 0xf) {
10269         case 0xb:
10270                 return (BWN_OFDM_RATE_6MB);
10271         case 0xf:
10272                 return (BWN_OFDM_RATE_9MB);
10273         case 0xa:
10274                 return (BWN_OFDM_RATE_12MB);
10275         case 0xe:
10276                 return (BWN_OFDM_RATE_18MB);
10277         case 0x9:
10278                 return (BWN_OFDM_RATE_24MB);
10279         case 0xd:
10280                 return (BWN_OFDM_RATE_36MB);
10281         case 0x8:
10282                 return (BWN_OFDM_RATE_48MB);
10283         case 0xc:
10284                 return (BWN_OFDM_RATE_54MB);
10285         }
10286         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10287             plcp->o.raw[0] & 0xf);
10288         return (-1);
10289 }
10290
10291 static int
10292 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10293 {
10294         struct bwn_softc *sc = mac->mac_sc;
10295
10296         switch (plcp->o.raw[0]) {
10297         case 0x0a:
10298                 return (BWN_CCK_RATE_1MB);
10299         case 0x14:
10300                 return (BWN_CCK_RATE_2MB);
10301         case 0x37:
10302                 return (BWN_CCK_RATE_5MB);
10303         case 0x6e:
10304                 return (BWN_CCK_RATE_11MB);
10305         }
10306         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10307         return (-1);
10308 }
10309
10310 static void
10311 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10312     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10313     int rssi, int noise)
10314 {
10315         struct bwn_softc *sc = mac->mac_sc;
10316         const struct ieee80211_frame_min *wh;
10317         uint64_t tsf;
10318         uint16_t low_mactime_now;
10319
10320         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10321                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10322
10323         wh = mtod(m, const struct ieee80211_frame_min *);
10324         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10325                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10326
10327         bwn_tsf_read(mac, &tsf);
10328         low_mactime_now = tsf;
10329         tsf = tsf & ~0xffffULL;
10330         tsf += le16toh(rxhdr->mac_time);
10331         if (low_mactime_now < le16toh(rxhdr->mac_time))
10332                 tsf -= 0x10000;
10333
10334         sc->sc_rx_th.wr_tsf = tsf;
10335         sc->sc_rx_th.wr_rate = rate;
10336         sc->sc_rx_th.wr_antsignal = rssi;
10337         sc->sc_rx_th.wr_antnoise = noise;
10338 }
10339
10340 static void
10341 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10342 {
10343         uint32_t low, high;
10344
10345         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10346             ("%s:%d: fail", __func__, __LINE__));
10347
10348         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10349         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10350         *tsf = high;
10351         *tsf <<= 32;
10352         *tsf |= low;
10353 }
10354
10355 static int
10356 bwn_dma_attach(struct bwn_mac *mac)
10357 {
10358         struct bwn_dma *dma = &mac->mac_method.dma;
10359         struct bwn_softc *sc = mac->mac_sc;
10360         bus_addr_t lowaddr = 0;
10361         int error;
10362
10363         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10364                 return (0);
10365
10366         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10367
10368         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10369
10370         dma->dmatype = bwn_dma_gettype(mac);
10371         if (dma->dmatype == BWN_DMA_30BIT)
10372                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10373         else if (dma->dmatype == BWN_DMA_32BIT)
10374                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10375         else
10376                 lowaddr = BUS_SPACE_MAXADDR;
10377
10378         /*
10379          * Create top level DMA tag
10380          */
10381         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10382                                BWN_ALIGN, 0,            /* alignment, bounds */
10383                                lowaddr,                 /* lowaddr */
10384                                BUS_SPACE_MAXADDR,       /* highaddr */
10385                                NULL, NULL,              /* filter, filterarg */
10386                                BUS_SPACE_MAXSIZE,       /* maxsize */
10387                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10388                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10389                                0,                       /* flags */
10390                                NULL, NULL,              /* lockfunc, lockarg */
10391                                &dma->parent_dtag);
10392         if (error) {
10393                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10394                 return (error);
10395         }
10396
10397         /*
10398          * Create TX/RX mbuf DMA tag
10399          */
10400         error = bus_dma_tag_create(dma->parent_dtag,
10401                                 1,
10402                                 0,
10403                                 BUS_SPACE_MAXADDR,
10404                                 BUS_SPACE_MAXADDR,
10405                                 NULL, NULL,
10406                                 MCLBYTES,
10407                                 1,
10408                                 BUS_SPACE_MAXSIZE_32BIT,
10409                                 0,
10410                                 NULL, NULL,
10411                                 &dma->rxbuf_dtag);
10412         if (error) {
10413                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10414                 goto fail0;
10415         }
10416         error = bus_dma_tag_create(dma->parent_dtag,
10417                                 1,
10418                                 0,
10419                                 BUS_SPACE_MAXADDR,
10420                                 BUS_SPACE_MAXADDR,
10421                                 NULL, NULL,
10422                                 MCLBYTES,
10423                                 1,
10424                                 BUS_SPACE_MAXSIZE_32BIT,
10425                                 0,
10426                                 NULL, NULL,
10427                                 &dma->txbuf_dtag);
10428         if (error) {
10429                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10430                 goto fail1;
10431         }
10432
10433         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10434         if (!dma->wme[WME_AC_BK])
10435                 goto fail2;
10436
10437         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10438         if (!dma->wme[WME_AC_BE])
10439                 goto fail3;
10440
10441         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10442         if (!dma->wme[WME_AC_VI])
10443                 goto fail4;
10444
10445         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10446         if (!dma->wme[WME_AC_VO])
10447                 goto fail5;
10448
10449         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10450         if (!dma->mcast)
10451                 goto fail6;
10452         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10453         if (!dma->rx)
10454                 goto fail7;
10455
10456         return (error);
10457
10458 fail7:  bwn_dma_ringfree(&dma->mcast);
10459 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10460 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10461 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10462 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10463 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10464 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10465 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10466         return (error);
10467 }
10468
10469 static struct bwn_dma_ring *
10470 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10471     uint16_t cookie, int *slot)
10472 {
10473         struct bwn_dma *dma = &mac->mac_method.dma;
10474         struct bwn_dma_ring *dr;
10475         struct bwn_softc *sc = mac->mac_sc;
10476
10477         BWN_ASSERT_LOCKED(mac->mac_sc);
10478
10479         switch (cookie & 0xf000) {
10480         case 0x1000:
10481                 dr = dma->wme[WME_AC_BK];
10482                 break;
10483         case 0x2000:
10484                 dr = dma->wme[WME_AC_BE];
10485                 break;
10486         case 0x3000:
10487                 dr = dma->wme[WME_AC_VI];
10488                 break;
10489         case 0x4000:
10490                 dr = dma->wme[WME_AC_VO];
10491                 break;
10492         case 0x5000:
10493                 dr = dma->mcast;
10494                 break;
10495         default:
10496                 dr = NULL;
10497                 KASSERT(0 == 1,
10498                     ("invalid cookie value %d", cookie & 0xf000));
10499         }
10500         *slot = (cookie & 0x0fff);
10501         if (*slot < 0 || *slot >= dr->dr_numslots) {
10502                 /*
10503                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10504                  * that it occurs events which have same H/W sequence numbers.
10505                  * When it's occurred just prints a WARNING msgs and ignores.
10506                  */
10507                 KASSERT(status->seq == dma->lastseq,
10508                     ("%s:%d: fail", __func__, __LINE__));
10509                 device_printf(sc->sc_dev,
10510                     "out of slot ranges (0 < %d < %d)\n", *slot,
10511                     dr->dr_numslots);
10512                 return (NULL);
10513         }
10514         dma->lastseq = status->seq;
10515         return (dr);
10516 }
10517
10518 static void
10519 bwn_dma_stop(struct bwn_mac *mac)
10520 {
10521         struct bwn_dma *dma;
10522
10523         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10524                 return;
10525         dma = &mac->mac_method.dma;
10526
10527         bwn_dma_ringstop(&dma->rx);
10528         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10529         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10530         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10531         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10532         bwn_dma_ringstop(&dma->mcast);
10533 }
10534
10535 static void
10536 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10537 {
10538
10539         if (dr == NULL)
10540                 return;
10541
10542         bwn_dma_cleanup(*dr);
10543 }
10544
10545 static void
10546 bwn_pio_stop(struct bwn_mac *mac)
10547 {
10548         struct bwn_pio *pio;
10549
10550         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10551                 return;
10552         pio = &mac->mac_method.pio;
10553
10554         bwn_destroy_queue_tx(&pio->mcast);
10555         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10556         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10557         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10558         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10559 }
10560
10561 static void
10562 bwn_led_attach(struct bwn_mac *mac)
10563 {
10564         struct bwn_softc *sc = mac->mac_sc;
10565         const uint8_t *led_act = NULL;
10566         uint16_t val[BWN_LED_MAX];
10567         int i;
10568
10569         sc->sc_led_idle = (2350 * hz) / 1000;
10570         sc->sc_led_blink = 1;
10571
10572         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10573                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10574                     bwn_vendor_led_act[i].vid) {
10575                         led_act = bwn_vendor_led_act[i].led_act;
10576                         break;
10577                 }
10578         }
10579         if (led_act == NULL)
10580                 led_act = bwn_default_led_act;
10581
10582         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10583         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10584         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10585         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10586
10587         for (i = 0; i < BWN_LED_MAX; ++i) {
10588                 struct bwn_led *led = &sc->sc_leds[i];
10589
10590                 if (val[i] == 0xff) {
10591                         led->led_act = led_act[i];
10592                 } else {
10593                         if (val[i] & BWN_LED_ACT_LOW)
10594                                 led->led_flags |= BWN_LED_F_ACTLOW;
10595                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10596                 }
10597                 led->led_mask = (1 << i);
10598
10599                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10600                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10601                     led->led_act == BWN_LED_ACT_BLINK) {
10602                         led->led_flags |= BWN_LED_F_BLINK;
10603                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10604                                 led->led_flags |= BWN_LED_F_POLLABLE;
10605                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10606                                 led->led_flags |= BWN_LED_F_SLOW;
10607
10608                         if (sc->sc_blink_led == NULL) {
10609                                 sc->sc_blink_led = led;
10610                                 if (led->led_flags & BWN_LED_F_SLOW)
10611                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10612                         }
10613                 }
10614
10615                 DPRINTF(sc, BWN_DEBUG_LED,
10616                     "%dth led, act %d, lowact %d\n", i,
10617                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10618         }
10619         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10620 }
10621
10622 static __inline uint16_t
10623 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10624 {
10625
10626         if (led->led_flags & BWN_LED_F_ACTLOW)
10627                 on = !on;
10628         if (on)
10629                 val |= led->led_mask;
10630         else
10631                 val &= ~led->led_mask;
10632         return val;
10633 }
10634
10635 static void
10636 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10637 {
10638         struct bwn_softc *sc = mac->mac_sc;
10639         struct ifnet *ifp = sc->sc_ifp;
10640         struct ieee80211com *ic = ifp->if_l2com;
10641         uint16_t val;
10642         int i;
10643
10644         if (nstate == IEEE80211_S_INIT) {
10645                 callout_stop(&sc->sc_led_blink_ch);
10646                 sc->sc_led_blinking = 0;
10647         }
10648
10649         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10650                 return;
10651
10652         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10653         for (i = 0; i < BWN_LED_MAX; ++i) {
10654                 struct bwn_led *led = &sc->sc_leds[i];
10655                 int on;
10656
10657                 if (led->led_act == BWN_LED_ACT_UNKN ||
10658                     led->led_act == BWN_LED_ACT_NULL)
10659                         continue;
10660
10661                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10662                     nstate != IEEE80211_S_INIT)
10663                         continue;
10664
10665                 switch (led->led_act) {
10666                 case BWN_LED_ACT_ON:    /* Always on */
10667                         on = 1;
10668                         break;
10669                 case BWN_LED_ACT_OFF:   /* Always off */
10670                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10671                         on = 0;
10672                         break;
10673                 default:
10674                         on = 1;
10675                         switch (nstate) {
10676                         case IEEE80211_S_INIT:
10677                                 on = 0;
10678                                 break;
10679                         case IEEE80211_S_RUN:
10680                                 if (led->led_act == BWN_LED_ACT_11G &&
10681                                     ic->ic_curmode != IEEE80211_MODE_11G)
10682                                         on = 0;
10683                                 break;
10684                         default:
10685                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10686                                         on = 0;
10687                                 break;
10688                         }
10689                         break;
10690                 }
10691
10692                 val = bwn_led_onoff(led, val, on);
10693         }
10694         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10695 }
10696
10697 static void
10698 bwn_led_event(struct bwn_mac *mac, int event)
10699 {
10700         struct bwn_softc *sc = mac->mac_sc;
10701         struct bwn_led *led = sc->sc_blink_led;
10702         int rate;
10703
10704         if (event == BWN_LED_EVENT_POLL) {
10705                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10706                         return;
10707                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10708                         return;
10709         }
10710
10711         sc->sc_led_ticks = ticks;
10712         if (sc->sc_led_blinking)
10713                 return;
10714
10715         switch (event) {
10716         case BWN_LED_EVENT_RX:
10717                 rate = sc->sc_rx_rate;
10718                 break;
10719         case BWN_LED_EVENT_TX:
10720                 rate = sc->sc_tx_rate;
10721                 break;
10722         case BWN_LED_EVENT_POLL:
10723                 rate = 0;
10724                 break;
10725         default:
10726                 panic("unknown LED event %d\n", event);
10727                 break;
10728         }
10729         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10730             bwn_led_duration[rate].off_dur);
10731 }
10732
10733 static void
10734 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10735 {
10736         struct bwn_softc *sc = mac->mac_sc;
10737         struct bwn_led *led = sc->sc_blink_led;
10738         uint16_t val;
10739
10740         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10741         val = bwn_led_onoff(led, val, 1);
10742         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10743
10744         if (led->led_flags & BWN_LED_F_SLOW) {
10745                 BWN_LED_SLOWDOWN(on_dur);
10746                 BWN_LED_SLOWDOWN(off_dur);
10747         }
10748
10749         sc->sc_led_blinking = 1;
10750         sc->sc_led_blink_offdur = off_dur;
10751
10752         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10753 }
10754
10755 static void
10756 bwn_led_blink_next(void *arg)
10757 {
10758         struct bwn_mac *mac = arg;
10759         struct bwn_softc *sc = mac->mac_sc;
10760         uint16_t val;
10761
10762         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10763         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10764         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10765
10766         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10767             bwn_led_blink_end, mac);
10768 }
10769
10770 static void
10771 bwn_led_blink_end(void *arg)
10772 {
10773         struct bwn_mac *mac = arg;
10774         struct bwn_softc *sc = mac->mac_sc;
10775
10776         sc->sc_led_blinking = 0;
10777 }
10778
10779 static int
10780 bwn_suspend(device_t dev)
10781 {
10782         struct bwn_softc *sc = device_get_softc(dev);
10783
10784         bwn_stop(sc, 1);
10785         return (0);
10786 }
10787
10788 static int
10789 bwn_resume(device_t dev)
10790 {
10791         struct bwn_softc *sc = device_get_softc(dev);
10792         struct ifnet *ifp = sc->sc_ifp;
10793
10794         if (ifp->if_flags & IFF_UP)
10795                 bwn_init(sc);
10796         return (0);
10797 }
10798
10799 static void
10800 bwn_rfswitch(void *arg)
10801 {
10802         struct bwn_softc *sc = arg;
10803         struct bwn_mac *mac = sc->sc_curmac;
10804         int cur = 0, prev = 0;
10805
10806         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10807             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10808
10809         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10810                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10811                         & BWN_RF_HWENABLED_HI_MASK))
10812                         cur = 1;
10813         } else {
10814                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10815                     & BWN_RF_HWENABLED_LO_MASK)
10816                         cur = 1;
10817         }
10818
10819         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10820                 prev = 1;
10821
10822         if (cur != prev) {
10823                 if (cur)
10824                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10825                 else
10826                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10827
10828                 device_printf(sc->sc_dev,
10829                     "status of RF switch is changed to %s\n",
10830                     cur ? "ON" : "OFF");
10831                 if (cur != mac->mac_phy.rf_on) {
10832                         if (cur)
10833                                 bwn_rf_turnon(mac);
10834                         else
10835                                 bwn_rf_turnoff(mac);
10836                 }
10837         }
10838
10839         callout_schedule(&sc->sc_rfswitch_ch, hz);
10840 }
10841
10842 static void
10843 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10844 {
10845         struct bwn_phy *phy = &mac->mac_phy;
10846         struct bwn_phy_lp *plp = &phy->phy_lp;
10847
10848         plp->plp_antenna = BWN_ANT_DEFAULT;
10849 }
10850
10851 static int
10852 bwn_phy_lp_init(struct bwn_mac *mac)
10853 {
10854         static const struct bwn_stxtable tables[] = {
10855                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10856                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10857                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10858                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10859                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10860                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10861                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10862                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10863                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10864                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10865                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10866                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10867                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10868                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10869                 { 2, 11, 0x40, 0, 0x0f }
10870         };
10871         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10872         struct bwn_softc *sc = mac->mac_sc;
10873         const struct bwn_stxtable *st;
10874         struct ifnet *ifp = sc->sc_ifp;
10875         struct ieee80211com *ic = ifp->if_l2com;
10876         int i, error;
10877         uint16_t tmp;
10878
10879         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10880         bwn_phy_lp_bbinit(mac);
10881
10882         /* initialize RF */
10883         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10884         DELAY(1);
10885         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10886         DELAY(1);
10887
10888         if (mac->mac_phy.rf_ver == 0x2062)
10889                 bwn_phy_lp_b2062_init(mac);
10890         else {
10891                 bwn_phy_lp_b2063_init(mac);
10892
10893                 /* synchronize stx table. */
10894                 for (i = 0; i < N(tables); i++) {
10895                         st = &tables[i];
10896                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10897                         tmp >>= st->st_rfshift;
10898                         tmp <<= st->st_physhift;
10899                         BWN_PHY_SETMASK(mac,
10900                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10901                             ~(st->st_mask << st->st_physhift), tmp);
10902                 }
10903
10904                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10905                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10906         }
10907
10908         /* calibrate RC */
10909         if (mac->mac_phy.rev >= 2)
10910                 bwn_phy_lp_rxcal_r2(mac);
10911         else if (!plp->plp_rccap) {
10912                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10913                         bwn_phy_lp_rccal_r12(mac);
10914         } else
10915                 bwn_phy_lp_set_rccap(mac);
10916
10917         error = bwn_phy_lp_switch_channel(mac, 7);
10918         if (error)
10919                 device_printf(sc->sc_dev,
10920                     "failed to change channel 7 (%d)\n", error);
10921         bwn_phy_lp_txpctl_init(mac);
10922         bwn_phy_lp_calib(mac);
10923         return (0);
10924 }
10925
10926 static uint16_t
10927 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10928 {
10929
10930         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10931         return (BWN_READ_2(mac, BWN_PHYDATA));
10932 }
10933
10934 static void
10935 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10936 {
10937
10938         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10939         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10940 }
10941
10942 static void
10943 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10944     uint16_t set)
10945 {
10946
10947         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10948         BWN_WRITE_2(mac, BWN_PHYDATA,
10949             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10950 }
10951
10952 static uint16_t
10953 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10954 {
10955
10956         KASSERT(reg != 1, ("unaccessible register %d", reg));
10957         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10958                 reg |= 0x100;
10959         if (mac->mac_phy.rev >= 2)
10960                 reg |= 0x200;
10961         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10962         return BWN_READ_2(mac, BWN_RFDATALO);
10963 }
10964
10965 static void
10966 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10967 {
10968
10969         KASSERT(reg != 1, ("unaccessible register %d", reg));
10970         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10971         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10972 }
10973
10974 static void
10975 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10976 {
10977
10978         if (on) {
10979                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10980                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10981                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10982                 return;
10983         }
10984
10985         if (mac->mac_phy.rev >= 2) {
10986                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10987                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10988                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10989                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10990                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10991                 return;
10992         }
10993
10994         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10995         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10996         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10997         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10998 }
10999
11000 static int
11001 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11002 {
11003         struct bwn_phy *phy = &mac->mac_phy;
11004         struct bwn_phy_lp *plp = &phy->phy_lp;
11005         int error;
11006
11007         if (phy->rf_ver == 0x2063) {
11008                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11009                 if (error)
11010                         return (error);
11011         } else {
11012                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11013                 if (error)
11014                         return (error);
11015                 bwn_phy_lp_set_anafilter(mac, chan);
11016                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11017         }
11018
11019         plp->plp_chan = chan;
11020         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11021         return (0);
11022 }
11023
11024 static uint32_t
11025 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11026 {
11027         struct bwn_softc *sc = mac->mac_sc;
11028         struct ifnet *ifp = sc->sc_ifp;
11029         struct ieee80211com *ic = ifp->if_l2com;
11030
11031         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11032 }
11033
11034 static void
11035 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11036 {
11037         struct bwn_phy *phy = &mac->mac_phy;
11038         struct bwn_phy_lp *plp = &phy->phy_lp;
11039
11040         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11041                 return;
11042
11043         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11044         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11045         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11046         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11047         plp->plp_antenna = antenna;
11048 }
11049
11050 static void
11051 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11052 {
11053
11054         bwn_phy_lp_calib(mac);
11055 }
11056
11057 static void
11058 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11059 {
11060         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11061         struct bwn_softc *sc = mac->mac_sc;
11062         struct ifnet *ifp = sc->sc_ifp;
11063         struct ieee80211com *ic = ifp->if_l2com;
11064
11065         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11066                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11067                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11068                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11069                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11070                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11071                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11072                 return;
11073         }
11074
11075         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11076         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11077         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11078         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11079         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11080         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11081         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11082         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11083 }
11084
11085 static void
11086 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11087 {
11088
11089         bwn_phy_lp_tblinit(mac);
11090         if (mac->mac_phy.rev >= 2)
11091                 bwn_phy_lp_bbinit_r2(mac);
11092         else
11093                 bwn_phy_lp_bbinit_r01(mac);
11094 }
11095
11096 static void
11097 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11098 {
11099         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11100         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11101         struct bwn_softc *sc = mac->mac_sc;
11102         struct ifnet *ifp = sc->sc_ifp;
11103         struct ieee80211com *ic = ifp->if_l2com;
11104
11105         bwn_phy_lp_set_txgain(mac,
11106             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11107         bwn_phy_lp_set_bbmult(mac, 150);
11108 }
11109
11110 static void
11111 bwn_phy_lp_calib(struct bwn_mac *mac)
11112 {
11113         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11114         struct bwn_softc *sc = mac->mac_sc;
11115         struct ifnet *ifp = sc->sc_ifp;
11116         struct ieee80211com *ic = ifp->if_l2com;
11117         const struct bwn_rxcompco *rc = NULL;
11118         struct bwn_txgain ogain;
11119         int i, omode, oafeovr, orf, obbmult;
11120         uint8_t mode, fc = 0;
11121
11122         if (plp->plp_chanfullcal != plp->plp_chan) {
11123                 plp->plp_chanfullcal = plp->plp_chan;
11124                 fc = 1;
11125         }
11126
11127         bwn_mac_suspend(mac);
11128
11129         /* BlueTooth Coexistance Override */
11130         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11131         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11132
11133         if (mac->mac_phy.rev >= 2)
11134                 bwn_phy_lp_digflt_save(mac);
11135         bwn_phy_lp_get_txpctlmode(mac);
11136         mode = plp->plp_txpctlmode;
11137         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11138         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11139                 bwn_phy_lp_bugfix(mac);
11140         if (mac->mac_phy.rev >= 2 && fc == 1) {
11141                 bwn_phy_lp_get_txpctlmode(mac);
11142                 omode = plp->plp_txpctlmode;
11143                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11144                 if (oafeovr)
11145                         ogain = bwn_phy_lp_get_txgain(mac);
11146                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11147                 obbmult = bwn_phy_lp_get_bbmult(mac);
11148                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11149                 if (oafeovr)
11150                         bwn_phy_lp_set_txgain(mac, &ogain);
11151                 bwn_phy_lp_set_bbmult(mac, obbmult);
11152                 bwn_phy_lp_set_txpctlmode(mac, omode);
11153                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11154         }
11155         bwn_phy_lp_set_txpctlmode(mac, mode);
11156         if (mac->mac_phy.rev >= 2)
11157                 bwn_phy_lp_digflt_restore(mac);
11158
11159         /* do RX IQ Calculation; assumes that noise is true. */
11160         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11161                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11162                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11163                                 rc = &bwn_rxcompco_5354[i];
11164                 }
11165         } else if (mac->mac_phy.rev >= 2)
11166                 rc = &bwn_rxcompco_r2;
11167         else {
11168                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11169                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11170                                 rc = &bwn_rxcompco_r12[i];
11171                 }
11172         }
11173         if (rc == NULL)
11174                 goto fail;
11175
11176         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11177         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11178
11179         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11180
11181         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11182                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11183                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11184         } else {
11185                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11186                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11187         }
11188
11189         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11190         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11191         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11192         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11193         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11194         bwn_phy_lp_set_deaf(mac, 0);
11195         /* XXX no checking return value? */
11196         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11197         bwn_phy_lp_clear_deaf(mac, 0);
11198         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11199         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11200         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11201
11202         /* disable RX GAIN override. */
11203         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11204         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11205         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11206         if (mac->mac_phy.rev >= 2) {
11207                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11208                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11209                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11210                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11211                 }
11212         } else {
11213                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11214         }
11215
11216         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11217         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11218 fail:
11219         bwn_mac_enable(mac);
11220 }
11221
11222 static void
11223 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11224 {
11225
11226         if (on) {
11227                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11228                 return;
11229         }
11230
11231         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11232         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11233 }
11234
11235 static int
11236 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11237 {
11238         static const struct bwn_b206x_chan *bc = NULL;
11239         struct bwn_softc *sc = mac->mac_sc;
11240         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11241             tmp[6];
11242         uint16_t old, scale, tmp16;
11243         int i, div;
11244
11245         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11246                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11247                         bc = &bwn_b2063_chantable[i];
11248                         break;
11249                 }
11250         }
11251         if (bc == NULL)
11252                 return (EINVAL);
11253
11254         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11255         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11256         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11257         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11258         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11259         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11260         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11261         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11262         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11263         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11264         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11265         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11266
11267         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11268         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11269
11270         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11271         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11272         freqref = freqxtal * 3;
11273         div = (freqxtal <= 26000000 ? 1 : 2);
11274         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11275         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11276                 999999) / 1000000) + 1;
11277
11278         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11279         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11280             0xfff8, timeout >> 2);
11281         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11282             0xff9f,timeout << 5);
11283         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11284
11285         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11286         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11287         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11288
11289         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11290             (timeoutref + 1)) - 1;
11291         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11292             0xf0, count >> 8);
11293         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11294
11295         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11296         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11297         while (tmp[1] >= freqref) {
11298                 tmp[0]++;
11299                 tmp[1] -= freqref;
11300         }
11301         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11302         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11303         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11304         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11305         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11306
11307         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11308         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11309         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11310         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11311
11312         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11313         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11314
11315         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11316                 scale = 1;
11317                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11318         } else {
11319                 scale = 0;
11320                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11321         }
11322         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11323         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11324
11325         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11326             (scale + 1);
11327         if (tmp[5] > 150)
11328                 tmp[5] = 0;
11329
11330         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11331         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11332
11333         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11334         if (freqxtal > 26000000)
11335                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11336         else
11337                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11338
11339         if (val[0] == 45)
11340                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11341         else
11342                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11343
11344         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11345         DELAY(1);
11346         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11347
11348         /* VCO Calibration */
11349         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11350         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11351         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11352         DELAY(1);
11353         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11354         DELAY(1);
11355         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11356         DELAY(1);
11357         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11358         DELAY(300);
11359         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11360
11361         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11362         return (0);
11363 }
11364
11365 static int
11366 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11367 {
11368         struct bwn_softc *sc = mac->mac_sc;
11369         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11370         const struct bwn_b206x_chan *bc = NULL;
11371         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11372         uint32_t tmp[9];
11373         int i;
11374
11375         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11376                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11377                         bc = &bwn_b2062_chantable[i];
11378                         break;
11379                 }
11380         }
11381
11382         if (bc == NULL)
11383                 return (EINVAL);
11384
11385         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11386         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11387         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11388         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11389         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11390         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11391         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11392         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11393         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11394         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11395
11396         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11397         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11398         bwn_phy_lp_b2062_reset_pllbias(mac);
11399         tmp[0] = freqxtal / 1000;
11400         tmp[1] = plp->plp_div * 1000;
11401         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11402         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11403                 tmp[2] *= 2;
11404         tmp[3] = 48 * tmp[0];
11405         tmp[5] = tmp[2] / tmp[3];
11406         tmp[6] = tmp[2] % tmp[3];
11407         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11408         tmp[4] = tmp[6] * 0x100;
11409         tmp[5] = tmp[4] / tmp[3];
11410         tmp[6] = tmp[4] % tmp[3];
11411         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11412         tmp[4] = tmp[6] * 0x100;
11413         tmp[5] = tmp[4] / tmp[3];
11414         tmp[6] = tmp[4] % tmp[3];
11415         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11416         tmp[4] = tmp[6] * 0x100;
11417         tmp[5] = tmp[4] / tmp[3];
11418         tmp[6] = tmp[4] % tmp[3];
11419         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11420             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11421         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11422         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11423         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11424         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11425
11426         bwn_phy_lp_b2062_vco_calib(mac);
11427         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11428                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11429                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11430                 bwn_phy_lp_b2062_reset_pllbias(mac);
11431                 bwn_phy_lp_b2062_vco_calib(mac);
11432                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11433                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11434                         return (EIO);
11435                 }
11436         }
11437         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11438         return (0);
11439 }
11440
11441 static void
11442 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11443 {
11444         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11445         uint16_t tmp = (channel == 14);
11446
11447         if (mac->mac_phy.rev < 2) {
11448                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11449                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11450                         bwn_phy_lp_set_rccap(mac);
11451                 return;
11452         }
11453
11454         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11455 }
11456
11457 static void
11458 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11459 {
11460         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11461         struct bwn_softc *sc = mac->mac_sc;
11462         struct ifnet *ifp = sc->sc_ifp;
11463         struct ieee80211com *ic = ifp->if_l2com;
11464         uint16_t iso, tmp[3];
11465
11466         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11467
11468         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11469                 iso = plp->plp_txisoband_m;
11470         else if (freq <= 5320)
11471                 iso = plp->plp_txisoband_l;
11472         else if (freq <= 5700)
11473                 iso = plp->plp_txisoband_m;
11474         else
11475                 iso = plp->plp_txisoband_h;
11476
11477         tmp[0] = ((iso - 26) / 12) << 12;
11478         tmp[1] = tmp[0] + 0x1000;
11479         tmp[2] = tmp[0] + 0x2000;
11480
11481         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11482         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11483 }
11484
11485 static void
11486 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11487 {
11488         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11489         int i;
11490         static const uint16_t addr[] = {
11491                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11492                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11493                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11494                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11495                 BWN_PHY_OFDM(0xcf),
11496         };
11497         static const uint16_t val[] = {
11498                 0xde5e, 0xe832, 0xe331, 0x4d26,
11499                 0x0026, 0x1420, 0x0020, 0xfe08,
11500                 0x0008,
11501         };
11502
11503         for (i = 0; i < N(addr); i++) {
11504                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11505                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11506         }
11507 }
11508
11509 static void
11510 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11511 {
11512         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11513         struct bwn_softc *sc = mac->mac_sc;
11514         uint16_t ctl;
11515
11516         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11517         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11518         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11519                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11520                 break;
11521         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11522                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11523                 break;
11524         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11525                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11526                 break;
11527         default:
11528                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11529                 device_printf(sc->sc_dev, "unknown command mode\n");
11530                 break;
11531         }
11532 }
11533
11534 static void
11535 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11536 {
11537         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11538         uint16_t ctl;
11539         uint8_t old;
11540
11541         bwn_phy_lp_get_txpctlmode(mac);
11542         old = plp->plp_txpctlmode;
11543         if (old == mode)
11544                 return;
11545         plp->plp_txpctlmode = mode;
11546
11547         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11548                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11549                     plp->plp_tssiidx);
11550                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11551                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11552
11553                 /* disable TX GAIN override */
11554                 if (mac->mac_phy.rev < 2)
11555                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11556                 else {
11557                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11558                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11559                 }
11560                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11561
11562                 plp->plp_txpwridx = -1;
11563         }
11564         if (mac->mac_phy.rev >= 2) {
11565                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11566                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11567                 else
11568                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11569         }
11570
11571         /* writes TX Power Control mode */
11572         switch (plp->plp_txpctlmode) {
11573         case BWN_PHYLP_TXPCTL_OFF:
11574                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11575                 break;
11576         case BWN_PHYLP_TXPCTL_ON_HW:
11577                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11578                 break;
11579         case BWN_PHYLP_TXPCTL_ON_SW:
11580                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11581                 break;
11582         default:
11583                 ctl = 0;
11584                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11585         }
11586         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11587             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11588 }
11589
11590 static void
11591 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11592 {
11593         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11594         struct bwn_softc *sc = mac->mac_sc;
11595         const unsigned int size = 256;
11596         struct bwn_txgain tg;
11597         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11598         uint16_t tssinpt, tssiidx, value[2];
11599         uint8_t mode;
11600         int8_t txpwridx;
11601
11602         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11603             M_NOWAIT | M_ZERO);
11604         if (tabs == NULL) {
11605                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11606                 return;
11607         }
11608
11609         bwn_phy_lp_get_txpctlmode(mac);
11610         mode = plp->plp_txpctlmode;
11611         txpwridx = plp->plp_txpwridx;
11612         tssinpt = plp->plp_tssinpt;
11613         tssiidx = plp->plp_tssiidx;
11614
11615         bwn_tab_read_multi(mac,
11616             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11617             BWN_TAB_4(7, 0x140), size, tabs);
11618
11619         bwn_phy_lp_tblinit(mac);
11620         bwn_phy_lp_bbinit(mac);
11621         bwn_phy_lp_txpctl_init(mac);
11622         bwn_phy_lp_rf_onoff(mac, 1);
11623         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11624
11625         bwn_tab_write_multi(mac,
11626             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11627             BWN_TAB_4(7, 0x140), size, tabs);
11628
11629         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11630         plp->plp_tssinpt = tssinpt;
11631         plp->plp_tssiidx = tssiidx;
11632         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11633         if (txpwridx != -1) {
11634                 /* set TX power by index */
11635                 plp->plp_txpwridx = txpwridx;
11636                 bwn_phy_lp_get_txpctlmode(mac);
11637                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11638                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11639                 if (mac->mac_phy.rev >= 2) {
11640                         rxcomp = bwn_tab_read(mac,
11641                             BWN_TAB_4(7, txpwridx + 320));
11642                         txgain = bwn_tab_read(mac,
11643                             BWN_TAB_4(7, txpwridx + 192));
11644                         tg.tg_pad = (txgain >> 16) & 0xff;
11645                         tg.tg_gm = txgain & 0xff;
11646                         tg.tg_pga = (txgain >> 8) & 0xff;
11647                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11648                         bwn_phy_lp_set_txgain(mac, &tg);
11649                 } else {
11650                         rxcomp = bwn_tab_read(mac,
11651                             BWN_TAB_4(10, txpwridx + 320));
11652                         txgain = bwn_tab_read(mac,
11653                             BWN_TAB_4(10, txpwridx + 192));
11654                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11655                             0xf800, (txgain >> 4) & 0x7fff);
11656                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11657                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11658                 }
11659                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11660
11661                 /* set TX IQCC */
11662                 value[0] = (rxcomp >> 10) & 0x3ff;
11663                 value[1] = rxcomp & 0x3ff;
11664                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11665
11666                 coeff = bwn_tab_read(mac,
11667                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11668                     BWN_TAB_4(10, txpwridx + 448));
11669                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11670                 if (mac->mac_phy.rev >= 2) {
11671                         rfpwr = bwn_tab_read(mac,
11672                             BWN_TAB_4(7, txpwridx + 576));
11673                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11674                             rfpwr & 0xffff);
11675                 }
11676                 bwn_phy_lp_set_txgain_override(mac);
11677         }
11678         if (plp->plp_rccap)
11679                 bwn_phy_lp_set_rccap(mac);
11680         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11681         bwn_phy_lp_set_txpctlmode(mac, mode);
11682         free(tabs, M_DEVBUF);
11683 }
11684
11685 static void
11686 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11687 {
11688         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11689         int i;
11690         static const uint16_t addr[] = {
11691                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11692                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11693                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11694                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11695                 BWN_PHY_OFDM(0xcf),
11696         };
11697
11698         for (i = 0; i < N(addr); i++)
11699                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11700 }
11701
11702 static void
11703 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11704 {
11705         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11706
11707         if (mac->mac_phy.rev < 2) {
11708                 bwn_phy_lp_tblinit_r01(mac);
11709                 bwn_phy_lp_tblinit_txgain(mac);
11710                 bwn_phy_lp_set_gaintbl(mac, freq);
11711                 return;
11712         }
11713
11714         bwn_phy_lp_tblinit_r2(mac);
11715         bwn_phy_lp_tblinit_txgain(mac);
11716 }
11717
11718 struct bwn_wpair {
11719         uint16_t                reg;
11720         uint16_t                value;
11721 };
11722
11723 struct bwn_smpair {
11724         uint16_t                offset;
11725         uint16_t                mask;
11726         uint16_t                set;
11727 };
11728
11729 static void
11730 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11731 {
11732         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11733         struct bwn_softc *sc = mac->mac_sc;
11734         struct ifnet *ifp = sc->sc_ifp;
11735         struct ieee80211com *ic = ifp->if_l2com;
11736         static const struct bwn_wpair v1[] = {
11737                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11738                 { BWN_PHY_AFE_CTL, 0x8800 },
11739                 { BWN_PHY_AFE_CTL_OVR, 0 },
11740                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11741                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11742                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11743                 { BWN_PHY_OFDM(0xf9), 0 },
11744                 { BWN_PHY_TR_LOOKUP_1, 0 }
11745         };
11746         static const struct bwn_smpair v2[] = {
11747                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11748                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11749                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11750                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11751                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11752         };
11753         static const struct bwn_smpair v3[] = {
11754                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11755                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11756                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11757                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11758                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11759                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11760                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11761                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11762                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11763                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11764
11765         };
11766         int i;
11767
11768         for (i = 0; i < N(v1); i++)
11769                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11770         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11771         for (i = 0; i < N(v2); i++)
11772                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11773
11774         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11775         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11776         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11777         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11778                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11779                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11780         } else {
11781                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11782         }
11783         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11784         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11785         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11786         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11787         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11788         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11789         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11790         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11791         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11792         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11793         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11794         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11795             (siba_get_chiprev(sc->sc_dev) == 0)) {
11796                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11797                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11798         } else {
11799                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11800                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11801         }
11802         for (i = 0; i < N(v3); i++)
11803                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11804         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11805             (siba_get_chiprev(sc->sc_dev) == 0)) {
11806                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11807                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11808         }
11809
11810         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11811                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11812                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11813                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11814                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11815                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11816                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11817         } else
11818                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11819
11820         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11821         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11822         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11823         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11824         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11825         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11826         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11827             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11828             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11829
11830         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11831             (siba_get_chiprev(sc->sc_dev) == 0)) {
11832                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11833                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11834                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11835         }
11836
11837         bwn_phy_lp_digflt_save(mac);
11838 }
11839
11840 static void
11841 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11842 {
11843         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11844         struct bwn_softc *sc = mac->mac_sc;
11845         struct ifnet *ifp = sc->sc_ifp;
11846         struct ieee80211com *ic = ifp->if_l2com;
11847         static const struct bwn_smpair v1[] = {
11848                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11849                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11850                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11851                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11852                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11853                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11854                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11855         };
11856         static const struct bwn_smpair v2[] = {
11857                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11858                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11859                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11860                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11861                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11862                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11863                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11864                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11865                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11866                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11867                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11868                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11869                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11870                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11871                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11872                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11873         };
11874         static const struct bwn_smpair v3[] = {
11875                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11876                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11877                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11878                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11879                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11880                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11881                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11882                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11883         };
11884         static const struct bwn_smpair v4[] = {
11885                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11886                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11887                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11888                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11889                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11890                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11891                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11892                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11893         };
11894         static const struct bwn_smpair v5[] = {
11895                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11896                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11897                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11898                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11899                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11900                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11901                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11902                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11903         };
11904         int i;
11905         uint16_t tmp, tmp2;
11906
11907         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11908         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11909         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11910         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11911         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11912         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11913         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11914         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11915         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11916         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11917         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11918         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11919         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11920         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11921         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11922         for (i = 0; i < N(v1); i++)
11923                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11924         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11925             0xff00, plp->plp_rxpwroffset);
11926         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11927             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11928            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11929                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11930                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11931                 if (mac->mac_phy.rev == 0)
11932                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11933                             0xffcf, 0x0010);
11934                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11935         } else {
11936                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11937                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11938                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11939         }
11940         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11941         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11942         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11943                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11944         else
11945                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11946         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11947         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11948             0xfff9, (plp->plp_bxarch << 1));
11949         if (mac->mac_phy.rev == 1 &&
11950             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11951                 for (i = 0; i < N(v2); i++)
11952                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11953                             v2[i].set);
11954         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11955             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11956             ((mac->mac_phy.rev == 0) &&
11957              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11958                 for (i = 0; i < N(v3); i++)
11959                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11960                             v3[i].set);
11961         } else if (mac->mac_phy.rev == 1 ||
11962                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11963                 for (i = 0; i < N(v4); i++)
11964                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11965                             v4[i].set);
11966         } else {
11967                 for (i = 0; i < N(v5); i++)
11968                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11969                             v5[i].set);
11970         }
11971         if (mac->mac_phy.rev == 1 &&
11972             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11973                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11974                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11975                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11976                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11977         }
11978         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11979             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11980             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11981                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11982                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11983                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11984                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11985         }
11986         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11987                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11988                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11989                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11990                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11991                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11992                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11993                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11994                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11995         } else {
11996                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11997                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11998         }
11999         if (mac->mac_phy.rev == 1) {
12000                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12001                 tmp2 = (tmp & 0x03e0) >> 5;
12002                 tmp2 |= tmp2 << 5;
12003                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12004                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12005                 tmp2 = (tmp & 0x1f00) >> 8;
12006                 tmp2 |= tmp2 << 5;
12007                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12008                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12009                 tmp2 = tmp & 0x00ff;
12010                 tmp2 |= tmp << 8;
12011                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12012         }
12013 }
12014
12015 struct bwn_b2062_freq {
12016         uint16_t                freq;
12017         uint8_t                 value[6];
12018 };
12019
12020 static void
12021 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12022 {
12023 #define CALC_CTL7(freq, div)                                            \
12024         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12025 #define CALC_CTL18(freq, div)                                           \
12026         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12027 #define CALC_CTL19(freq, div)                                           \
12028         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12029         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12030         struct bwn_softc *sc = mac->mac_sc;
12031         struct ifnet *ifp = sc->sc_ifp;
12032         struct ieee80211com *ic = ifp->if_l2com;
12033         static const struct bwn_b2062_freq freqdata_tab[] = {
12034                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12035                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12036                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12037                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12038                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12039                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12040         };
12041         static const struct bwn_wpair v1[] = {
12042                 { BWN_B2062_N_TXCTL3, 0 },
12043                 { BWN_B2062_N_TXCTL4, 0 },
12044                 { BWN_B2062_N_TXCTL5, 0 },
12045                 { BWN_B2062_N_TXCTL6, 0 },
12046                 { BWN_B2062_N_PDNCTL0, 0x40 },
12047                 { BWN_B2062_N_PDNCTL0, 0 },
12048                 { BWN_B2062_N_CALIB_TS, 0x10 },
12049                 { BWN_B2062_N_CALIB_TS, 0 }
12050         };
12051         const struct bwn_b2062_freq *f = NULL;
12052         uint32_t xtalfreq, ref;
12053         unsigned int i;
12054
12055         bwn_phy_lp_b2062_tblinit(mac);
12056
12057         for (i = 0; i < N(v1); i++)
12058                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12059         if (mac->mac_phy.rev > 0)
12060                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12061                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12062         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12063                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12064         else
12065                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12066
12067         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12068             ("%s:%d: fail", __func__, __LINE__));
12069         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12070         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12071
12072         if (xtalfreq <= 30000000) {
12073                 plp->plp_div = 1;
12074                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12075         } else {
12076                 plp->plp_div = 2;
12077                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12078         }
12079
12080         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12081             CALC_CTL7(xtalfreq, plp->plp_div));
12082         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12083             CALC_CTL18(xtalfreq, plp->plp_div));
12084         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12085             CALC_CTL19(xtalfreq, plp->plp_div));
12086
12087         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12088         ref &= 0xffff;
12089         for (i = 0; i < N(freqdata_tab); i++) {
12090                 if (ref < freqdata_tab[i].freq) {
12091                         f = &freqdata_tab[i];
12092                         break;
12093                 }
12094         }
12095         if (f == NULL)
12096                 f = &freqdata_tab[N(freqdata_tab) - 1];
12097         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12098             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12099         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12100             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12101         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12102         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12103 #undef CALC_CTL7
12104 #undef CALC_CTL18
12105 #undef CALC_CTL19
12106 }
12107
12108 static void
12109 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12110 {
12111
12112         bwn_phy_lp_b2063_tblinit(mac);
12113         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12114         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12115         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12116         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12117         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12118         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12119         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12120         if (mac->mac_phy.rev == 2) {
12121                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12122                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12123                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12124         } else {
12125                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12126                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12127         }
12128 }
12129
12130 static void
12131 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12132 {
12133         struct bwn_softc *sc = mac->mac_sc;
12134         static const struct bwn_wpair v1[] = {
12135                 { BWN_B2063_RX_BB_SP8, 0x0 },
12136                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12137                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12138                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12139                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12140                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12141                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12142                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12143         };
12144         static const struct bwn_wpair v2[] = {
12145                 { BWN_B2063_TX_BB_SP3, 0x0 },
12146                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12147                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12148                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12149                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12150         };
12151         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12152         int i;
12153         uint8_t tmp;
12154
12155         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12156
12157         for (i = 0; i < 2; i++)
12158                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12159         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12160         for (i = 2; i < N(v1); i++)
12161                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12162         for (i = 0; i < 10000; i++) {
12163                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12164                         break;
12165                 DELAY(1000);
12166         }
12167
12168         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12169                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12170
12171         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12172
12173         for (i = 0; i < N(v2); i++)
12174                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12175         if (freqxtal == 24000000) {
12176                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12177                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12178         } else {
12179                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12180                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12181         }
12182         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12183         for (i = 0; i < 10000; i++) {
12184                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12185                         break;
12186                 DELAY(1000);
12187         }
12188         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12189                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12190         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12191 }
12192
12193 static void
12194 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12195 {
12196         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12197         struct bwn_softc *sc = mac->mac_sc;
12198         struct bwn_phy_lp_iq_est ie;
12199         struct bwn_txgain tx_gains;
12200         static const uint32_t pwrtbl[21] = {
12201                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12202                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12203                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12204                 0x0004c, 0x0002c, 0x0001a,
12205         };
12206         uint32_t npwr, ipwr, sqpwr, tmp;
12207         int loopback, i, j, sum, error;
12208         uint16_t save[7];
12209         uint8_t txo, bbmult, txpctlmode;
12210
12211         error = bwn_phy_lp_switch_channel(mac, 7);
12212         if (error)
12213                 device_printf(sc->sc_dev,
12214                     "failed to change channel to 7 (%d)\n", error);
12215         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12216         bbmult = bwn_phy_lp_get_bbmult(mac);
12217         if (txo)
12218                 tx_gains = bwn_phy_lp_get_txgain(mac);
12219
12220         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12221         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12222         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12223         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12224         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12225         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12226         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12227
12228         bwn_phy_lp_get_txpctlmode(mac);
12229         txpctlmode = plp->plp_txpctlmode;
12230         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12231
12232         /* disable CRS */
12233         bwn_phy_lp_set_deaf(mac, 1);
12234         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12235         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12236         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12237         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12238         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12239         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12240         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12241         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12242         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12243         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12244         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12245         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12246         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12247         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12248         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12249         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12250         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12251         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12252         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12253         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12254         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12255         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12256         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12257         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12258
12259         loopback = bwn_phy_lp_loopback(mac);
12260         if (loopback == -1)
12261                 goto done;
12262         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12263         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12264         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12265         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12266         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12267
12268         tmp = 0;
12269         memset(&ie, 0, sizeof(ie));
12270         for (i = 128; i <= 159; i++) {
12271                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12272                 sum = 0;
12273                 for (j = 5; j <= 25; j++) {
12274                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12275                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12276                                 goto done;
12277                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12278                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12279                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12280                             12);
12281                         sum += ((ipwr - npwr) * (ipwr - npwr));
12282                         if ((i == 128) || (sum < tmp)) {
12283                                 plp->plp_rccap = i;
12284                                 tmp = sum;
12285                         }
12286                 }
12287         }
12288         bwn_phy_lp_ddfs_turnoff(mac);
12289 done:
12290         /* restore CRS */
12291         bwn_phy_lp_clear_deaf(mac, 1);
12292         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12293         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12294
12295         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12296         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12297         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12298         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12299         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12300         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12301         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12302
12303         bwn_phy_lp_set_bbmult(mac, bbmult);
12304         if (txo)
12305                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12306         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12307         if (plp->plp_rccap)
12308                 bwn_phy_lp_set_rccap(mac);
12309 }
12310
12311 static void
12312 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12313 {
12314         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12315         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12316
12317         if (mac->mac_phy.rev == 1)
12318                 rc_cap = MIN(rc_cap + 5, 15);
12319
12320         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12321             MAX(plp->plp_rccap - 4, 0x80));
12322         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12323         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12324             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12325 }
12326
12327 static uint32_t
12328 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12329 {
12330         uint32_t i, q, r;
12331
12332         if (div == 0)
12333                 return (0);
12334
12335         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12336                 q <<= 1;
12337                 if (r << 1 >= div) {
12338                         q++;
12339                         r = (r << 1) - div;
12340                 }
12341         }
12342         if (r << 1 >= div)
12343                 q++;
12344         return (q);
12345 }
12346
12347 static void
12348 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12349 {
12350         struct bwn_softc *sc = mac->mac_sc;
12351
12352         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12353         DELAY(20);
12354         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12355                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12356                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12357         } else {
12358                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12359         }
12360         DELAY(5);
12361 }
12362
12363 static void
12364 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12365 {
12366
12367         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12368         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12369         DELAY(200);
12370 }
12371
12372 static void
12373 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12374 {
12375 #define FLAG_A  0x01
12376 #define FLAG_G  0x02
12377         struct bwn_softc *sc = mac->mac_sc;
12378         struct ifnet *ifp = sc->sc_ifp;
12379         struct ieee80211com *ic = ifp->if_l2com;
12380         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12381                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12382                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12383                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12384                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12385                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12386                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12387                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12388                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12389                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12390                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12391                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12392                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12393                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12394                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12395                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12396                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12397                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12398                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12399                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12400                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12401                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12402                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12403                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12404                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12405                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12406                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12407                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12408                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12409                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12410                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12411                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12412                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12413                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12414                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12415                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12416                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12417                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12418                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12419                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12420                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12421                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12422                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12424                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12426                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12427                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12428         };
12429         const struct bwn_b206x_rfinit_entry *br;
12430         unsigned int i;
12431
12432         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12433                 br = &bwn_b2062_init_tab[i];
12434                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12435                         if (br->br_flags & FLAG_G)
12436                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12437                 } else {
12438                         if (br->br_flags & FLAG_A)
12439                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12440                 }
12441         }
12442 #undef FLAG_A
12443 #undef FLAG_B
12444 }
12445
12446 static void
12447 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12448 {
12449 #define FLAG_A  0x01
12450 #define FLAG_G  0x02
12451         struct bwn_softc *sc = mac->mac_sc;
12452         struct ifnet *ifp = sc->sc_ifp;
12453         struct ieee80211com *ic = ifp->if_l2com;
12454         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12455                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12456                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12457                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12458                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12459                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12460                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12461                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12462                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12463                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12464                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12465                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12466                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12467                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12468                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12469                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12470                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12471                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12472                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12473                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12474                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12475                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12476                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12477                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12478                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12479                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12480                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12481                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12482                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12483                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12484                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12485                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12486                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12487                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12488                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12489                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12490                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12491                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12492                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12493                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12494                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12495                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12496                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12497         };
12498         const struct bwn_b206x_rfinit_entry *br;
12499         unsigned int i;
12500
12501         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12502                 br = &bwn_b2063_init_tab[i];
12503                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12504                         if (br->br_flags & FLAG_G)
12505                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12506                 } else {
12507                         if (br->br_flags & FLAG_A)
12508                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12509                 }
12510         }
12511 #undef FLAG_A
12512 #undef FLAG_B
12513 }
12514
12515 static void
12516 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12517     int count, void *_data)
12518 {
12519         unsigned int i;
12520         uint32_t offset, type;
12521         uint8_t *data = _data;
12522
12523         type = BWN_TAB_GETTYPE(typenoffset);
12524         offset = BWN_TAB_GETOFFSET(typenoffset);
12525         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12526
12527         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12528
12529         for (i = 0; i < count; i++) {
12530                 switch (type) {
12531                 case BWN_TAB_8BIT:
12532                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12533                         data++;
12534                         break;
12535                 case BWN_TAB_16BIT:
12536                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12537                             BWN_PHY_TABLEDATALO);
12538                         data += 2;
12539                         break;
12540                 case BWN_TAB_32BIT:
12541                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12542                             BWN_PHY_TABLEDATAHI);
12543                         *((uint32_t *)data) <<= 16;
12544                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12545                             BWN_PHY_TABLEDATALO);
12546                         data += 4;
12547                         break;
12548                 default:
12549                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12550                 }
12551         }
12552 }
12553
12554 static void
12555 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12556     int count, const void *_data)
12557 {
12558         uint32_t offset, type, value;
12559         const uint8_t *data = _data;
12560         unsigned int i;
12561
12562         type = BWN_TAB_GETTYPE(typenoffset);
12563         offset = BWN_TAB_GETOFFSET(typenoffset);
12564         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12565
12566         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12567
12568         for (i = 0; i < count; i++) {
12569                 switch (type) {
12570                 case BWN_TAB_8BIT:
12571                         value = *data;
12572                         data++;
12573                         KASSERT(!(value & ~0xff),
12574                             ("%s:%d: fail", __func__, __LINE__));
12575                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12576                         break;
12577                 case BWN_TAB_16BIT:
12578                         value = *((const uint16_t *)data);
12579                         data += 2;
12580                         KASSERT(!(value & ~0xffff),
12581                             ("%s:%d: fail", __func__, __LINE__));
12582                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12583                         break;
12584                 case BWN_TAB_32BIT:
12585                         value = *((const uint32_t *)data);
12586                         data += 4;
12587                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12588                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12589                         break;
12590                 default:
12591                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12592                 }
12593         }
12594 }
12595
12596 static struct bwn_txgain
12597 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12598 {
12599         struct bwn_txgain tg;
12600         uint16_t tmp;
12601
12602         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12603         if (mac->mac_phy.rev < 2) {
12604                 tmp = BWN_PHY_READ(mac,
12605                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12606                 tg.tg_gm = tmp & 0x0007;
12607                 tg.tg_pga = (tmp & 0x0078) >> 3;
12608                 tg.tg_pad = (tmp & 0x780) >> 7;
12609                 return (tg);
12610         }
12611
12612         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12613         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12614         tg.tg_gm = tmp & 0xff;
12615         tg.tg_pga = (tmp >> 8) & 0xff;
12616         return (tg);
12617 }
12618
12619 static uint8_t
12620 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12621 {
12622
12623         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12624 }
12625
12626 static void
12627 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12628 {
12629         uint16_t pa;
12630
12631         if (mac->mac_phy.rev < 2) {
12632                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12633                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12634                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12635                 bwn_phy_lp_set_txgain_override(mac);
12636                 return;
12637         }
12638
12639         pa = bwn_phy_lp_get_pa_gain(mac);
12640         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12641             (tg->tg_pga << 8) | tg->tg_gm);
12642         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12643             tg->tg_pad | (pa << 6));
12644         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12645         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12646             tg->tg_pad | (pa << 8));
12647         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12648         bwn_phy_lp_set_txgain_override(mac);
12649 }
12650
12651 static void
12652 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12653 {
12654
12655         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12656 }
12657
12658 static void
12659 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12660 {
12661         uint16_t trsw = (tx << 1) | rx;
12662
12663         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12664         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12665 }
12666
12667 static void
12668 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12669 {
12670         struct bwn_softc *sc = mac->mac_sc;
12671         struct ifnet *ifp = sc->sc_ifp;
12672         struct ieee80211com *ic = ifp->if_l2com;
12673         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12674
12675         if (mac->mac_phy.rev < 2) {
12676                 trsw = gain & 0x1;
12677                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12678                 ext_lna = (gain & 2) >> 1;
12679
12680                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12681                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12682                     0xfbff, ext_lna << 10);
12683                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12684                     0xf7ff, ext_lna << 11);
12685                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12686         } else {
12687                 low_gain = gain & 0xffff;
12688                 high_gain = (gain >> 16) & 0xf;
12689                 ext_lna = (gain >> 21) & 0x1;
12690                 trsw = ~(gain >> 20) & 0x1;
12691
12692                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12693                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12694                     0xfdff, ext_lna << 9);
12695                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12696                     0xfbff, ext_lna << 10);
12697                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12698                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12699                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12700                         tmp = (gain >> 2) & 0x3;
12701                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12702                             0xe7ff, tmp<<11);
12703                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12704                             tmp << 3);
12705                 }
12706         }
12707
12708         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12709         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12710         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12711         if (mac->mac_phy.rev >= 2) {
12712                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12713                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12714                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12715                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12716                 }
12717                 return;
12718         }
12719         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12720 }
12721
12722 static void
12723 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12724 {
12725         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12726
12727         if (user)
12728                 plp->plp_crsusr_off = 1;
12729         else
12730                 plp->plp_crssys_off = 1;
12731
12732         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12733 }
12734
12735 static void
12736 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12737 {
12738         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12739         struct bwn_softc *sc = mac->mac_sc;
12740         struct ifnet *ifp = sc->sc_ifp;
12741         struct ieee80211com *ic = ifp->if_l2com;
12742
12743         if (user)
12744                 plp->plp_crsusr_off = 0;
12745         else
12746                 plp->plp_crssys_off = 0;
12747
12748         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12749                 return;
12750
12751         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12752                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12753         else
12754                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12755 }
12756
12757 static unsigned int
12758 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12759 {
12760         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12761         static uint8_t sqrt_table[256] = {
12762                 10, 14, 17, 20, 22, 24, 26, 28,
12763                 30, 31, 33, 34, 36, 37, 38, 40,
12764                 41, 42, 43, 44, 45, 46, 47, 48,
12765                 50, 50, 51, 52, 53, 54, 55, 56,
12766                 57, 58, 59, 60, 60, 61, 62, 63,
12767                 64, 64, 65, 66, 67, 67, 68, 69,
12768                 70, 70, 71, 72, 72, 73, 74, 74,
12769                 75, 76, 76, 77, 78, 78, 79, 80,
12770                 80, 81, 81, 82, 83, 83, 84, 84,
12771                 85, 86, 86, 87, 87, 88, 88, 89,
12772                 90, 90, 91, 91, 92, 92, 93, 93,
12773                 94, 94, 95, 95, 96, 96, 97, 97,
12774                 98, 98, 99, 100, 100, 100, 101, 101,
12775                 102, 102, 103, 103, 104, 104, 105, 105,
12776                 106, 106, 107, 107, 108, 108, 109, 109,
12777                 110, 110, 110, 111, 111, 112, 112, 113,
12778                 113, 114, 114, 114, 115, 115, 116, 116,
12779                 117, 117, 117, 118, 118, 119, 119, 120,
12780                 120, 120, 121, 121, 122, 122, 122, 123,
12781                 123, 124, 124, 124, 125, 125, 126, 126,
12782                 126, 127, 127, 128, 128, 128, 129, 129,
12783                 130, 130, 130, 131, 131, 131, 132, 132,
12784                 133, 133, 133, 134, 134, 134, 135, 135,
12785                 136, 136, 136, 137, 137, 137, 138, 138,
12786                 138, 139, 139, 140, 140, 140, 141, 141,
12787                 141, 142, 142, 142, 143, 143, 143, 144,
12788                 144, 144, 145, 145, 145, 146, 146, 146,
12789                 147, 147, 147, 148, 148, 148, 149, 149,
12790                 150, 150, 150, 150, 151, 151, 151, 152,
12791                 152, 152, 153, 153, 153, 154, 154, 154,
12792                 155, 155, 155, 156, 156, 156, 157, 157,
12793                 157, 158, 158, 158, 159, 159, 159, 160
12794         };
12795
12796         if (x == 0)
12797                 return (0);
12798         if (x >= 256) {
12799                 unsigned int tmp;
12800
12801                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12802                         /* do nothing */ ;
12803                 return (tmp);
12804         }
12805         return (sqrt_table[x - 1] / 10);
12806 }
12807
12808 static int
12809 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12810 {
12811 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12812         int _t;                                                         \
12813         _t = _x - 20;                                                   \
12814         if (_t >= 0) {                                                  \
12815                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12816         } else {                                                        \
12817                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12818         }                                                               \
12819 } while (0)
12820 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12821         int _t;                                                         \
12822         _t = _x - 11;                                                   \
12823         if (_t >= 0)                                                    \
12824                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12825         else                                                            \
12826                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12827 } while (0)
12828         struct bwn_phy_lp_iq_est ie;
12829         uint16_t v0, v1;
12830         int tmp[2], ret;
12831
12832         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12833         v0 = v1 >> 8;
12834         v1 |= 0xff;
12835
12836         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12837         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12838
12839         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12840         if (ret == 0)
12841                 goto done;
12842
12843         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12844                 ret = 0;
12845                 goto done;
12846         }
12847
12848         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12849         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12850
12851         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12852         v0 = tmp[0] >> 3;
12853         v1 = tmp[1] >> 4;
12854 done:
12855         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12856         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12857         return ret;
12858 #undef CALC_COEFF
12859 #undef CALC_COEFF2
12860 }
12861
12862 static void
12863 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12864 {
12865         static const uint16_t noisescale[] = {
12866                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12867                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12868                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12869                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12870                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12871         };
12872         static const uint16_t crsgainnft[] = {
12873                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12874                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12875                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12876                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12877                 0x013d,
12878         };
12879         static const uint16_t filterctl[] = {
12880                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12881                 0xff53, 0x0127,
12882         };
12883         static const uint32_t psctl[] = {
12884                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12885                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12886                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12887                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12888                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12889                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12890                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12891                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12892         };
12893         static const uint16_t ofdmcckgain_r0[] = {
12894                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12895                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12896                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12897                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12898                 0x755d,
12899         };
12900         static const uint16_t ofdmcckgain_r1[] = {
12901                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12902                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12903                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12904                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12905                 0x755d,
12906         };
12907         static const uint16_t gaindelta[] = {
12908                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12909                 0x0000,
12910         };
12911         static const uint32_t txpwrctl[] = {
12912                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12913                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12914                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12915                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12916                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12917                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12918                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12919                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12920                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12921                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12922                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12923                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12924                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12925                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12926                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12950                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12951                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12952                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12953                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12954                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12955                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12956                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12957                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12958                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12959                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12960                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12961                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12962                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12963                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12964                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12965                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12966                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12967                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12968                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12969                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12970                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12971                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12972                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12973                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12974                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12975                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12976                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12977                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12978                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12979                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12980                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12981                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12982                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12983                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12984                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12985                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12986                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12987                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12988                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12989                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12990                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12991                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12992                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12993                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12994                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12995                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12996                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12997                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12998                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12999                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13000                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13001                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13002                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13003                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13004                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13005                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13006                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13007                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13008                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13009                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13010                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13011                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13012                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13013                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13014                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13015                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13016                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13017                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13018                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13019                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13020                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13021                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13022                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13023                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13024                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13025                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13026                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13027                 0x00000702,
13028         };
13029
13030         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13031
13032         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13033             bwn_tab_sigsq_tbl);
13034         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13035         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13036         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13037         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13038         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13039             bwn_tab_pllfrac_tbl);
13040         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13041             bwn_tabl_iqlocal_tbl);
13042         if (mac->mac_phy.rev == 0) {
13043                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13044                     ofdmcckgain_r0);
13045                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13046                     ofdmcckgain_r0);
13047         } else {
13048                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13049                     ofdmcckgain_r1);
13050                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13051                     ofdmcckgain_r1);
13052         }
13053         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13054         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13055 }
13056
13057 static void
13058 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13059 {
13060         struct bwn_softc *sc = mac->mac_sc;
13061         int i;
13062         static const uint16_t noisescale[] = {
13063                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13068                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13069                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13070         };
13071         static const uint32_t filterctl[] = {
13072                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13073                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13074         };
13075         static const uint32_t psctl[] = {
13076                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13077                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13078                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13079                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13080         };
13081         static const uint32_t gainidx[] = {
13082                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13083                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13084                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13085                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13086                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13087                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13088                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13089                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13090                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13091                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13092                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13093                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13094                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13095                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13096                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13097                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13098                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13099                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13100                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13101                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13102                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13103                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13104                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13105                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13106                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13107                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13108                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13109                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13110                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13111                 0x0000001a, 0x64ca55ad, 0x0000001a
13112         };
13113         static const uint16_t auxgainidx[] = {
13114                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13115                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13116                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13117                 0x0004, 0x0016
13118         };
13119         static const uint16_t swctl[] = {
13120                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13121                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13122                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13123                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13124                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13125                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13126                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13127                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13128         };
13129         static const uint8_t hf[] = {
13130                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13131                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13132         };
13133         static const uint32_t gainval[] = {
13134                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13135                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13136                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13137                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13138                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13139                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13142                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13143                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13144                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13145                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13146                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13147                 0x000000f1, 0x00000000, 0x00000000
13148         };
13149         static const uint16_t gain[] = {
13150                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13151                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13152                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13153                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13154                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13155                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13156                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13157                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13158                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13159                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13160                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13161                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13162         };
13163         static const uint32_t papdeps[] = {
13164                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13165                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13166                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13167                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13168                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13169                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13170                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13171                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13172                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13173                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13174                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13175                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13176                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13177         };
13178         static const uint32_t papdmult[] = {
13179                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13180                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13181                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13182                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13183                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13184                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13185                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13186                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13187                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13188                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13189                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13190                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13191                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13192         };
13193         static const uint32_t gainidx_a0[] = {
13194                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13195                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13196                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13197                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13198                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13199                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13200                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13201                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13202                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13203                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13204                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13205                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13206                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13207         };
13208         static const uint16_t auxgainidx_a0[] = {
13209                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13210                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13211                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13212                 0x0002, 0x0014
13213         };
13214         static const uint32_t gainval_a0[] = {
13215                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13216                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13217                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13218                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13219                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13220                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13221                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13222                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13223                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13224                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13225                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13226                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13227                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13228                 0x000000f7, 0x00000000, 0x00000000
13229         };
13230         static const uint16_t gain_a0[] = {
13231                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13232                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13233                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13234                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13235                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13236                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13237                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13238                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13239                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13240                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13241                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13242                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13243         };
13244
13245         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13246
13247         for (i = 0; i < 704; i++)
13248                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13249
13250         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13251             bwn_tab_sigsq_tbl);
13252         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13253         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13254         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13255         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13256         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13257         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13258         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13259         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13260         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13261         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13262             bwn_tab_pllfrac_tbl);
13263         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13264             bwn_tabl_iqlocal_tbl);
13265         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13266         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13267
13268         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13269             (siba_get_chiprev(sc->sc_dev) == 0)) {
13270                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13271                     gainidx_a0);
13272                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13273                     auxgainidx_a0);
13274                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13275                     gainval_a0);
13276                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13277         }
13278 }
13279
13280 static void
13281 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13282 {
13283         struct bwn_softc *sc = mac->mac_sc;
13284         struct ifnet *ifp = sc->sc_ifp;
13285         struct ieee80211com *ic = ifp->if_l2com;
13286         static struct bwn_txgain_entry txgain_r2[] = {
13287                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13288                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13289                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13290                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13291                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13292                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13293                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13294                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13295                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13296                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13297                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13298                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13299                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13300                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13301                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13302                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13303                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13304                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13305                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13306                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13307                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13308                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13309                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13310                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13311                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13312                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13313                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13314                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13315                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13316                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13317                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13318                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13319                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13320                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13321                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13322                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13323                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13324                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13325                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13326                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13327                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13328                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13329                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13330                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13331                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13332                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13333                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13334                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13335                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13336                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13337                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13338                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13339                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13340                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13341                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13342                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13343                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13344                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13345                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13346                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13347                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13348                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13349                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13350                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13351         };
13352         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13353                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13354                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13355                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13356                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13357                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13358                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13359                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13360                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13361                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13362                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13363                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13364                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13365                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13366                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13367                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13368                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13369                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13370                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13371                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13372                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13373                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13374                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13375                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13376                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13377                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13378                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13379                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13380                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13381                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13382                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13383                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13384                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13385                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13386                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13387                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13388                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13389                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13390                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13391                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13392                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13393                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13394                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13395                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13396                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13397                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13398                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13399                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13400                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13401                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13402                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13403                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13404                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13405                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13406                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13407                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13408                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13409                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13410                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13411                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13412                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13413                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13414                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13415                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13416                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13417         };
13418         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13419                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13420                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13421                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13422                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13423                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13424                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13425                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13426                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13427                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13428                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13429                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13430                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13431                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13432                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13433                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13434                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13435                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13436                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13437                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13438                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13439                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13440                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13441                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13442                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13443                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13444                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13445                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13446                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13447                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13448                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13449                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13450                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13451                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13452                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13453                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13454                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13455                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13456                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13457                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13458                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13459                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13460                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13461                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13462                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13463                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13464                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13465                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13466                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13467                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13468                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13469                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13470                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13471                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13472                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13473                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13474                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13475                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13476                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13477                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13478                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13479                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13480                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13481                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13482                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13483         };
13484         static struct bwn_txgain_entry txgain_r0[] = {
13485                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13486                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13487                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13488                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13489                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13490                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13491                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13492                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13493                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13494                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13495                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13496                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13497                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13498                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13499                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13500                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13501                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13502                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13503                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13504                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13505                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13506                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13507                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13508                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13509                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13510                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13511                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13512                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13513                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13514                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13515                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13516                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13517                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13518                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13519                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13520                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13521                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13522                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13523                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13524                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13525                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13526                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13527                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13528                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13529                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13530                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13531                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13532                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13533                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13534                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13535                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13536                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13537                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13538                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13539                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13540                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13541                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13542                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13543                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13544                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13545                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13546                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13547                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13548                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13549         };
13550         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13551                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13552                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13553                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13554                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13555                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13556                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13557                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13558                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13559                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13560                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13561                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13562                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13563                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13564                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13565                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13566                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13567                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13568                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13569                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13570                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13571                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13572                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13573                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13574                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13575                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13576                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13577                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13578                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13579                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13580                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13581                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13582                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13583                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13584                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13585                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13586                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13587                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13588                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13589                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13590                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13591                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13592                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13593                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13594                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13595                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13596                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13597                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13598                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13599                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13600                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13601                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13602                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13603                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13604                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13605                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13606                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13607                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13608                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13609                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13610                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13611                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13612                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13613                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13614                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13615         };
13616         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13617                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13618                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13619                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13620                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13621                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13622                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13623                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13624                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13625                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13626                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13627                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13628                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13629                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13630                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13631                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13632                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13633                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13634                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13635                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13636                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13637                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13638                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13639                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13640                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13641                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13642                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13643                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13644                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13645                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13646                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13647                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13648                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13649                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13650                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13651                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13652                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13653                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13654                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13655                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13656                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13657                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13658                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13659                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13660                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13661                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13662                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13663                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13664                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13665                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13666                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13667                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13668                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13669                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13670                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13671                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13672                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13673                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13674                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13675                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13676                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13677                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13678                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13679                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13680                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13681         };
13682         static struct bwn_txgain_entry txgain_r1[] = {
13683                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13684                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13685                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13686                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13687                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13688                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13689                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13690                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13691                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13692                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13693                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13694                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13695                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13696                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13697                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13698                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13699                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13700                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13701                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13702                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13703                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13704                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13705                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13706                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13707                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13708                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13709                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13710                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13711                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13712                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13713                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13714                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13715                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13716                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13717                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13718                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13719                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13720                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13721                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13722                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13723                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13724                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13725                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13726                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13727                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13728                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13729                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13730                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13731                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13732                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13733                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13734                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13735                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13736                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13737                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13738                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13739                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13740                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13741                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13742                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13743                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13744                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13745                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13746                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13747                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13748                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13749                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13750                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13751                 { 7, 11, 6, 0, 71 }
13752         };
13753         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13754                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13755                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13756                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13757                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13758                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13759                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13760                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13761                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13762                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13763                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13764                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13765                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13766                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13767                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13768                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13769                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13770                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13771                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13772                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13773                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13774                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13775                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13776                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13777                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13778                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13779                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13780                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13781                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13782                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13783                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13784                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13785                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13786                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13787                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13788                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13789                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13790                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13791                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13792                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13793                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13794                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13795                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13796                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13797                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13798                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13799                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13800                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13801                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13802                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13803                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13804                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13805                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13806                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13807                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13808                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13809                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13810                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13811                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13812                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13813                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13814                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13815                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13816                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13817                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13818         };
13819         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13820                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13821                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13822                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13823                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13824                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13825                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13826                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13827                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13828                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13829                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13830                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13831                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13832                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13833                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13834                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13835                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13836                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13837                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13838                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13839                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13840                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13841                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13842                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13843                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13844                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13845                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13846                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13847                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13848                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13849                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13850                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13851                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13852                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13853                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13854                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13855                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13856                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13857                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13858                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13859                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13860                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13861                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13862                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13863                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13864                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13865                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13866                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13867                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13868                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13869                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13870                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13871                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13872                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13873                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13874                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13875                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13876                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13877                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13878                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13879                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13880                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13881                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13882                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13883                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13884         };
13885
13886         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13887                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13888                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13889                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13890                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13891                             txgain_2ghz_r2);
13892                 else
13893                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13894                             txgain_5ghz_r2);
13895                 return;
13896         }
13897
13898         if (mac->mac_phy.rev == 0) {
13899                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13900                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13901                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13902                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13903                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13904                             txgain_2ghz_r0);
13905                 else
13906                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13907                             txgain_5ghz_r0);
13908                 return;
13909         }
13910
13911         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13912             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13913                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13914         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13915                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13916         else
13917                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13918 }
13919
13920 static void
13921 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13922 {
13923         uint32_t offset, type;
13924
13925         type = BWN_TAB_GETTYPE(typeoffset);
13926         offset = BWN_TAB_GETOFFSET(typeoffset);
13927         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13928
13929         switch (type) {
13930         case BWN_TAB_8BIT:
13931                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13932                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13933                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13934                 break;
13935         case BWN_TAB_16BIT:
13936                 KASSERT(!(value & ~0xffff),
13937                     ("%s:%d: fail", __func__, __LINE__));
13938                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13939                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13940                 break;
13941         case BWN_TAB_32BIT:
13942                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13943                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13944                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13945                 break;
13946         default:
13947                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13948         }
13949 }
13950
13951 static int
13952 bwn_phy_lp_loopback(struct bwn_mac *mac)
13953 {
13954         struct bwn_phy_lp_iq_est ie;
13955         int i, index = -1;
13956         uint32_t tmp;
13957
13958         memset(&ie, 0, sizeof(ie));
13959
13960         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13961         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13962         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13963         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13964         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13965         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13966         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13967         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13968         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13969         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13970         for (i = 0; i < 32; i++) {
13971                 bwn_phy_lp_set_rxgain_idx(mac, i);
13972                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13973                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13974                         continue;
13975                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13976                 if ((tmp > 4000) && (tmp < 10000)) {
13977                         index = i;
13978                         break;
13979                 }
13980         }
13981         bwn_phy_lp_ddfs_turnoff(mac);
13982         return (index);
13983 }
13984
13985 static void
13986 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13987 {
13988
13989         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13990 }
13991
13992 static void
13993 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13994     int incr1, int incr2, int scale_idx)
13995 {
13996
13997         bwn_phy_lp_ddfs_turnoff(mac);
13998         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13999         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14000         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14001         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14002         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14003         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14004         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14005         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14006         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14007         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14008 }
14009
14010 static uint8_t
14011 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14012     struct bwn_phy_lp_iq_est *ie)
14013 {
14014         int i;
14015
14016         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14017         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14018         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14019         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14020         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14021
14022         for (i = 0; i < 500; i++) {
14023                 if (!(BWN_PHY_READ(mac,
14024                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14025                         break;
14026                 DELAY(1000);
14027         }
14028         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14029                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14030                 return 0;
14031         }
14032
14033         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14034         ie->ie_iqprod <<= 16;
14035         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14036         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14037         ie->ie_ipwr <<= 16;
14038         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14039         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14040         ie->ie_qpwr <<= 16;
14041         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14042
14043         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14044         return 1;
14045 }
14046
14047 static uint32_t
14048 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14049 {
14050         uint32_t offset, type, value;
14051
14052         type = BWN_TAB_GETTYPE(typeoffset);
14053         offset = BWN_TAB_GETOFFSET(typeoffset);
14054         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14055
14056         switch (type) {
14057         case BWN_TAB_8BIT:
14058                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14059                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14060                 break;
14061         case BWN_TAB_16BIT:
14062                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14063                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14064                 break;
14065         case BWN_TAB_32BIT:
14066                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14067                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14068                 value <<= 16;
14069                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14070                 break;
14071         default:
14072                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14073                 value = 0;
14074         }
14075
14076         return (value);
14077 }
14078
14079 static void
14080 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14081 {
14082
14083         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14084         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14085 }
14086
14087 static void
14088 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14089 {
14090         uint16_t ctl;
14091
14092         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14093         ctl |= dac << 7;
14094         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14095 }
14096
14097 static void
14098 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14099 {
14100
14101         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14102         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14103 }
14104
14105 static void
14106 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14107 {
14108
14109         if (mac->mac_phy.rev < 2)
14110                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14111         else {
14112                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14113                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14114         }
14115         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14116 }
14117
14118 static uint16_t
14119 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14120 {
14121
14122         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14123 }
14124
14125 static uint8_t
14126 bwn_nbits(int32_t val)
14127 {
14128         uint32_t tmp;
14129         uint8_t nbits = 0;
14130
14131         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14132                 nbits++;
14133         return (nbits);
14134 }
14135
14136 static void
14137 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14138     struct bwn_txgain_entry *table)
14139 {
14140         int i;
14141
14142         for (i = offset; i < count; i++)
14143                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14144 }
14145
14146 static void
14147 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14148     struct bwn_txgain_entry data)
14149 {
14150
14151         if (mac->mac_phy.rev >= 2)
14152                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14153         else
14154                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14155 }
14156
14157 static void
14158 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14159     struct bwn_txgain_entry te)
14160 {
14161         struct bwn_softc *sc = mac->mac_sc;
14162         struct ifnet *ifp = sc->sc_ifp;
14163         struct ieee80211com *ic = ifp->if_l2com;
14164         uint32_t tmp;
14165
14166         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14167
14168         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14169         if (mac->mac_phy.rev >= 3) {
14170                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14171                     (0x10 << 24) : (0x70 << 24));
14172         } else {
14173                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14174                     (0x14 << 24) : (0x7f << 24));
14175         }
14176         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14177         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14178             te.te_bbmult << 20 | te.te_dac << 28);
14179 }
14180
14181 static void
14182 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14183     struct bwn_txgain_entry te)
14184 {
14185
14186         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14187
14188         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14189             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14190             te.te_dac);
14191         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14192 }
14193
14194 static void
14195 bwn_sysctl_node(struct bwn_softc *sc)
14196 {
14197         device_t dev = sc->sc_dev;
14198         struct bwn_mac *mac;
14199         struct bwn_stats *stats;
14200
14201         /* XXX assume that count of MAC is only 1. */
14202
14203         if ((mac = sc->sc_curmac) == NULL)
14204                 return;
14205         stats = &mac->mac_stats;
14206
14207         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14208             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14209             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14210         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14211             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14212             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14213         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14214             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14215             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14216
14217 #ifdef BWN_DEBUG
14218         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14219             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14220             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14221 #endif
14222 }
14223
14224 static device_method_t bwn_methods[] = {
14225         /* Device interface */
14226         DEVMETHOD(device_probe,         bwn_probe),
14227         DEVMETHOD(device_attach,        bwn_attach),
14228         DEVMETHOD(device_detach,        bwn_detach),
14229         DEVMETHOD(device_suspend,       bwn_suspend),
14230         DEVMETHOD(device_resume,        bwn_resume),
14231         DEVMETHOD_END
14232 };
14233 static driver_t bwn_driver = {
14234         "bwn",
14235         bwn_methods,
14236         sizeof(struct bwn_softc)
14237 };
14238 static devclass_t bwn_devclass;
14239 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14240 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14241 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14242 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14243 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);