]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwn/if_bwn.c
Upgrade to Unbound 1.5.4.
[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 void     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 int      bwn_init(struct bwn_softc *);
140 static void     bwn_parent(struct ieee80211com *);
141 static void     bwn_start(struct bwn_softc *);
142 static int      bwn_transmit(struct ieee80211com *, struct mbuf *);
143 static int      bwn_attach_core(struct bwn_mac *);
144 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
145 static int      bwn_phy_getinfo(struct bwn_mac *, int);
146 static int      bwn_chiptest(struct bwn_mac *);
147 static int      bwn_setup_channels(struct bwn_mac *, int, int);
148 static int      bwn_phy_g_attach(struct bwn_mac *);
149 static void     bwn_phy_g_detach(struct bwn_mac *);
150 static void     bwn_phy_g_init_pre(struct bwn_mac *);
151 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
152 static int      bwn_phy_g_init(struct bwn_mac *);
153 static void     bwn_phy_g_exit(struct bwn_mac *);
154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
155 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
156                     uint16_t);
157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
158 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
159                     uint16_t);
160 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
161 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
162 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
164 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
165 static int      bwn_phy_g_im(struct bwn_mac *, int);
166 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
167 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
168 static void     bwn_phy_g_task_15s(struct bwn_mac *);
169 static void     bwn_phy_g_task_60s(struct bwn_mac *);
170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
171 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
173 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
174                     uint16_t);
175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
176 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
177                     uint32_t);
178 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
179                     uint16_t);
180 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
181                     const struct bwn_channelinfo *, int);
182 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
183                     const struct ieee80211_bpf_params *);
184 static void     bwn_updateslot(struct ieee80211com *);
185 static void     bwn_update_promisc(struct ieee80211com *);
186 static void     bwn_wme_init(struct bwn_mac *);
187 static int      bwn_wme_update(struct ieee80211com *);
188 static void     bwn_wme_clear(struct bwn_softc *);
189 static void     bwn_wme_load(struct bwn_mac *);
190 static void     bwn_wme_loadparams(struct bwn_mac *,
191                     const struct wmeParams *, uint16_t);
192 static void     bwn_scan_start(struct ieee80211com *);
193 static void     bwn_scan_end(struct ieee80211com *);
194 static void     bwn_set_channel(struct ieee80211com *);
195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
196                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
197                     const uint8_t [IEEE80211_ADDR_LEN],
198                     const uint8_t [IEEE80211_ADDR_LEN]);
199 static void     bwn_vap_delete(struct ieee80211vap *);
200 static void     bwn_stop(struct bwn_softc *);
201 static int      bwn_core_init(struct bwn_mac *);
202 static void     bwn_core_start(struct bwn_mac *);
203 static void     bwn_core_exit(struct bwn_mac *);
204 static void     bwn_bt_disable(struct bwn_mac *);
205 static int      bwn_chip_init(struct bwn_mac *);
206 static uint64_t bwn_hf_read(struct bwn_mac *);
207 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void     bwn_set_txretry(struct bwn_mac *, int, int);
209 static void     bwn_rate_init(struct bwn_mac *);
210 static void     bwn_set_phytxctl(struct bwn_mac *);
211 static void     bwn_spu_setdelay(struct bwn_mac *, int);
212 static void     bwn_bt_enable(struct bwn_mac *);
213 static void     bwn_set_macaddr(struct bwn_mac *);
214 static void     bwn_crypt_init(struct bwn_mac *);
215 static void     bwn_chip_exit(struct bwn_mac *);
216 static int      bwn_fw_fillinfo(struct bwn_mac *);
217 static int      bwn_fw_loaducode(struct bwn_mac *);
218 static int      bwn_gpio_init(struct bwn_mac *);
219 static int      bwn_fw_loadinitvals(struct bwn_mac *);
220 static int      bwn_phy_init(struct bwn_mac *);
221 static void     bwn_set_txantenna(struct bwn_mac *, int);
222 static void     bwn_set_opmode(struct bwn_mac *);
223 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t  bwn_plcp_getcck(const uint8_t);
225 static uint8_t  bwn_plcp_getofdm(const uint8_t);
226 static void     bwn_pio_init(struct bwn_mac *);
227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
228 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
229                     int);
230 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
231                     struct bwn_pio_rxqueue *, int);
232 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
234                     uint16_t);
235 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void     bwn_pio_handle_txeof(struct bwn_mac *,
239                     const struct bwn_txstatus *);
240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
243                     uint16_t);
244 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
245                     uint32_t);
246 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
247                     struct mbuf *);
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
250                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
252                     uint16_t, uint32_t);
253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
254                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
256                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258                     uint16_t, struct bwn_pio_txpkt **);
259 static void     bwn_dma_init(struct bwn_mac *);
260 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int      bwn_dma_mask2type(uint64_t);
262 static uint64_t bwn_dma_mask(struct bwn_mac *);
263 static uint16_t bwn_dma_base(int, int);
264 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
266                     int, struct bwn_dmadesc_generic **,
267                     struct bwn_dmadesc_meta **);
268 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
269                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
270                     int, int);
271 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
277                     int, struct bwn_dmadesc_generic **,
278                     struct bwn_dmadesc_meta **);
279 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
280                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
281                     int, int);
282 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void     bwn_dma_setup(struct bwn_dma_ring *);
289 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void     bwn_dma_rx(struct bwn_dma_ring *);
294 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
296                     struct bwn_dmadesc_meta *);
297 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int      bwn_dma_gettype(struct bwn_mac *);
299 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
304                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
305                     int);
306 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
307                     bus_size_t, int);
308 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void     bwn_dma_handle_txeof(struct bwn_mac *,
310                     const struct bwn_txstatus *);
311 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
312                     struct mbuf *);
313 static int      bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
315                     uint8_t);
316 static int      bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
318                     int, int, int);
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320                     const struct bwn_txstatus *, uint16_t, int *);
321 static void     bwn_dma_free(struct bwn_mac *);
322 static void     bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
324 static void     bwn_phy_init_b5(struct bwn_mac *);
325 static void     bwn_phy_init_b6(struct bwn_mac *);
326 static void     bwn_phy_init_a(struct bwn_mac *);
327 static void     bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void     bwn_lo_g_init(struct bwn_mac *);
330 static void     bwn_lo_g_adjust(struct bwn_mac *);
331 static void     bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333                     const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338                     const struct bwn_bbatt *, const struct bwn_rfatt *,
339                     uint8_t);
340 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void     bwn_wa_init(struct bwn_mac *);
344 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
345                     uint16_t);
346 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
348                     uint32_t);
349 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
350                     uint16_t);
351 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void     bwn_mac_suspend(struct bwn_mac *);
353 static void     bwn_mac_enable(struct bwn_mac *);
354 static void     bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void     bwn_nrssi_offset(struct bwn_mac *);
357 static void     bwn_nrssi_threshold(struct bwn_mac *);
358 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360                     int16_t);
361 static void     bwn_set_original_gains(struct bwn_mac *);
362 static void     bwn_hwpctl_early_init(struct bwn_mac *);
363 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t bwn_phy_g_chan2freq(uint8_t);
365 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367                     const char *, struct bwn_fwfile *);
368 static void     bwn_release_firmware(struct bwn_mac *);
369 static void     bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371 static int      bwn_fwinitvals_write(struct bwn_mac *,
372                     const struct bwn_fwinitvals *, size_t, size_t);
373 static int      bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t bwn_ant2phy(int);
375 static void     bwn_mac_write_bssid(struct bwn_mac *);
376 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377                     const uint8_t *);
378 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379                     const uint8_t *, size_t, const uint8_t *);
380 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
381                     const uint8_t *);
382 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
383                     const uint8_t *);
384 static void     bwn_phy_exit(struct bwn_mac *);
385 static void     bwn_core_stop(struct bwn_mac *);
386 static int      bwn_switch_band(struct bwn_softc *,
387                     struct ieee80211_channel *);
388 static void     bwn_phy_reset(struct bwn_mac *);
389 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void     bwn_set_pretbtt(struct bwn_mac *);
391 static int      bwn_intr(void *);
392 static void     bwn_intrtask(void *, int);
393 static void     bwn_restart(struct bwn_mac *, const char *);
394 static void     bwn_intr_ucode_debug(struct bwn_mac *);
395 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void     bwn_intr_atim_end(struct bwn_mac *);
397 static void     bwn_intr_beacon(struct bwn_mac *);
398 static void     bwn_intr_pmq(struct bwn_mac *);
399 static void     bwn_intr_noise(struct bwn_mac *);
400 static void     bwn_intr_txeof(struct bwn_mac *);
401 static void     bwn_hwreset(void *, int);
402 static void     bwn_handle_fwpanic(struct bwn_mac *);
403 static void     bwn_load_beacon0(struct bwn_mac *);
404 static void     bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t bwn_jssi_read(struct bwn_mac *);
406 static void     bwn_noise_gensample(struct bwn_mac *);
407 static void     bwn_handle_txeof(struct bwn_mac *,
408                     const struct bwn_txstatus *);
409 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
412                     struct mbuf *);
413 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
414 static int      bwn_set_txhdr(struct bwn_mac *,
415                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
416                     uint16_t);
417 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
418                     const uint8_t);
419 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
420 static uint8_t  bwn_get_fbrate(uint8_t);
421 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
422 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
423 static void     bwn_phy_lock(struct bwn_mac *);
424 static void     bwn_phy_unlock(struct bwn_mac *);
425 static void     bwn_rf_lock(struct bwn_mac *);
426 static void     bwn_rf_unlock(struct bwn_mac *);
427 static void     bwn_txpwr(void *, int);
428 static void     bwn_tasks(void *);
429 static void     bwn_task_15s(struct bwn_mac *);
430 static void     bwn_task_30s(struct bwn_mac *);
431 static void     bwn_task_60s(struct bwn_mac *);
432 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
433                     uint8_t);
434 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
435 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
436                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
437                     int, int);
438 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
439 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
440 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
441 static void     bwn_watchdog(void *);
442 static void     bwn_dma_stop(struct bwn_mac *);
443 static void     bwn_pio_stop(struct bwn_mac *);
444 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
445 static void     bwn_led_attach(struct bwn_mac *);
446 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
447 static void     bwn_led_event(struct bwn_mac *, int);
448 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
449 static void     bwn_led_blink_next(void *);
450 static void     bwn_led_blink_end(void *);
451 static void     bwn_rfswitch(void *);
452 static void     bwn_rf_turnon(struct bwn_mac *);
453 static void     bwn_rf_turnoff(struct bwn_mac *);
454 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
455 static int      bwn_phy_lp_init(struct bwn_mac *);
456 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
457 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
458 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
459                     uint16_t);
460 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
461 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
462 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
463 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
464 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
465 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
466 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
467 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
468 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
469 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
470 static void     bwn_phy_lp_calib(struct bwn_mac *);
471 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
472 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
473 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
474 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
475 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
476 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
477 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
478 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
479 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
480 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
481 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
482 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
483 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
484 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
485 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
486 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
487 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
488 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
489 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
490 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
491 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
492 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
493                     const void *);
494 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
495 static struct bwn_txgain
496                 bwn_phy_lp_get_txgain(struct bwn_mac *);
497 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
498 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
499 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
500 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
501 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
502 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
503 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
504 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
505 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
506 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
507 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
508 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
509 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
510 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
511 static int      bwn_phy_lp_loopback(struct bwn_mac *);
512 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
513 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
514                     int);
515 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
516                     struct bwn_phy_lp_iq_est *);
517 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
518 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
519 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
520 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
521 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
522 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
523 static uint8_t  bwn_nbits(int32_t);
524 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
525                     struct bwn_txgain_entry *);
526 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
527                     struct bwn_txgain_entry);
528 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
529                     struct bwn_txgain_entry);
530 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
531                     struct bwn_txgain_entry);
532 static void     bwn_sysctl_node(struct bwn_softc *);
533
534 static struct resource_spec bwn_res_spec_legacy[] = {
535         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
536         { -1,                   0,              0 }
537 };
538
539 static struct resource_spec bwn_res_spec_msi[] = {
540         { SYS_RES_IRQ,          1,              RF_ACTIVE },
541         { -1,                   0,              0 }
542 };
543
544 static const struct bwn_channelinfo bwn_chantable_bg = {
545         .channels = {
546                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
547                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
548                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
549                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
550                 { 2472, 13, 30 }, { 2484, 14, 30 } },
551         .nchannels = 14
552 };
553
554 static const struct bwn_channelinfo bwn_chantable_a = {
555         .channels = {
556                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
557                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
558                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
559                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
560                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
561                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
562                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
563                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
564                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
565                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
566                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
567                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
568                 { 6080, 216, 30 } },
569         .nchannels = 37
570 };
571
572 static const struct bwn_channelinfo bwn_chantable_n = {
573         .channels = {
574                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
575                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
576                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
577                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
578                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
579                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
580                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
581                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
582                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
583                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
584                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
585                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
586                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
587                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
588                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
589                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
590                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
591                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
592                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
593                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
594                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
595                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
596                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
597                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
598                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
599                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
600                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
601                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
602                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
603                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
604                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
605                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
606                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
607                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
608                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
609                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
610                 { 6130, 226, 30 }, { 6140, 228, 30 } },
611         .nchannels = 110
612 };
613
614 static const uint8_t bwn_b2063_chantable_data[33][12] = {
615         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
616         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
621         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
622         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
623         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
624         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
628         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
629         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
630         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
632         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
633         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
634         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
635         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
637         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
640         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
643         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
646         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
648 };
649
650 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
651         { 1, 2412, bwn_b2063_chantable_data[0] },
652         { 2, 2417, bwn_b2063_chantable_data[0] },
653         { 3, 2422, bwn_b2063_chantable_data[0] },
654         { 4, 2427, bwn_b2063_chantable_data[1] },
655         { 5, 2432, bwn_b2063_chantable_data[1] },
656         { 6, 2437, bwn_b2063_chantable_data[1] },
657         { 7, 2442, bwn_b2063_chantable_data[1] },
658         { 8, 2447, bwn_b2063_chantable_data[1] },
659         { 9, 2452, bwn_b2063_chantable_data[2] },
660         { 10, 2457, bwn_b2063_chantable_data[2] },
661         { 11, 2462, bwn_b2063_chantable_data[3] },
662         { 12, 2467, bwn_b2063_chantable_data[3] },
663         { 13, 2472, bwn_b2063_chantable_data[3] },
664         { 14, 2484, bwn_b2063_chantable_data[4] },
665         { 34, 5170, bwn_b2063_chantable_data[5] },
666         { 36, 5180, bwn_b2063_chantable_data[6] },
667         { 38, 5190, bwn_b2063_chantable_data[7] },
668         { 40, 5200, bwn_b2063_chantable_data[8] },
669         { 42, 5210, bwn_b2063_chantable_data[9] },
670         { 44, 5220, bwn_b2063_chantable_data[10] },
671         { 46, 5230, bwn_b2063_chantable_data[11] },
672         { 48, 5240, bwn_b2063_chantable_data[12] },
673         { 52, 5260, bwn_b2063_chantable_data[13] },
674         { 56, 5280, bwn_b2063_chantable_data[14] },
675         { 60, 5300, bwn_b2063_chantable_data[14] },
676         { 64, 5320, bwn_b2063_chantable_data[15] },
677         { 100, 5500, bwn_b2063_chantable_data[16] },
678         { 104, 5520, bwn_b2063_chantable_data[17] },
679         { 108, 5540, bwn_b2063_chantable_data[18] },
680         { 112, 5560, bwn_b2063_chantable_data[19] },
681         { 116, 5580, bwn_b2063_chantable_data[20] },
682         { 120, 5600, bwn_b2063_chantable_data[21] },
683         { 124, 5620, bwn_b2063_chantable_data[21] },
684         { 128, 5640, bwn_b2063_chantable_data[22] },
685         { 132, 5660, bwn_b2063_chantable_data[22] },
686         { 136, 5680, bwn_b2063_chantable_data[22] },
687         { 140, 5700, bwn_b2063_chantable_data[23] },
688         { 149, 5745, bwn_b2063_chantable_data[23] },
689         { 153, 5765, bwn_b2063_chantable_data[23] },
690         { 157, 5785, bwn_b2063_chantable_data[23] },
691         { 161, 5805, bwn_b2063_chantable_data[23] },
692         { 165, 5825, bwn_b2063_chantable_data[23] },
693         { 184, 4920, bwn_b2063_chantable_data[24] },
694         { 188, 4940, bwn_b2063_chantable_data[25] },
695         { 192, 4960, bwn_b2063_chantable_data[26] },
696         { 196, 4980, bwn_b2063_chantable_data[27] },
697         { 200, 5000, bwn_b2063_chantable_data[28] },
698         { 204, 5020, bwn_b2063_chantable_data[29] },
699         { 208, 5040, bwn_b2063_chantable_data[30] },
700         { 212, 5060, bwn_b2063_chantable_data[31] },
701         { 216, 5080, bwn_b2063_chantable_data[32] }
702 };
703
704 static const uint8_t bwn_b2062_chantable_data[22][12] = {
705         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
706         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
726         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
727 };
728
729 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
730         { 1, 2412, bwn_b2062_chantable_data[0] },
731         { 2, 2417, bwn_b2062_chantable_data[0] },
732         { 3, 2422, bwn_b2062_chantable_data[0] },
733         { 4, 2427, bwn_b2062_chantable_data[0] },
734         { 5, 2432, bwn_b2062_chantable_data[0] },
735         { 6, 2437, bwn_b2062_chantable_data[0] },
736         { 7, 2442, bwn_b2062_chantable_data[0] },
737         { 8, 2447, bwn_b2062_chantable_data[0] },
738         { 9, 2452, bwn_b2062_chantable_data[0] },
739         { 10, 2457, bwn_b2062_chantable_data[0] },
740         { 11, 2462, bwn_b2062_chantable_data[0] },
741         { 12, 2467, bwn_b2062_chantable_data[0] },
742         { 13, 2472, bwn_b2062_chantable_data[0] },
743         { 14, 2484, bwn_b2062_chantable_data[0] },
744         { 34, 5170, bwn_b2062_chantable_data[1] },
745         { 38, 5190, bwn_b2062_chantable_data[2] },
746         { 42, 5210, bwn_b2062_chantable_data[2] },
747         { 46, 5230, bwn_b2062_chantable_data[3] },
748         { 36, 5180, bwn_b2062_chantable_data[4] },
749         { 40, 5200, bwn_b2062_chantable_data[5] },
750         { 44, 5220, bwn_b2062_chantable_data[6] },
751         { 48, 5240, bwn_b2062_chantable_data[3] },
752         { 52, 5260, bwn_b2062_chantable_data[3] },
753         { 56, 5280, bwn_b2062_chantable_data[3] },
754         { 60, 5300, bwn_b2062_chantable_data[7] },
755         { 64, 5320, bwn_b2062_chantable_data[8] },
756         { 100, 5500, bwn_b2062_chantable_data[9] },
757         { 104, 5520, bwn_b2062_chantable_data[10] },
758         { 108, 5540, bwn_b2062_chantable_data[10] },
759         { 112, 5560, bwn_b2062_chantable_data[10] },
760         { 116, 5580, bwn_b2062_chantable_data[11] },
761         { 120, 5600, bwn_b2062_chantable_data[12] },
762         { 124, 5620, bwn_b2062_chantable_data[12] },
763         { 128, 5640, bwn_b2062_chantable_data[12] },
764         { 132, 5660, bwn_b2062_chantable_data[12] },
765         { 136, 5680, bwn_b2062_chantable_data[12] },
766         { 140, 5700, bwn_b2062_chantable_data[12] },
767         { 149, 5745, bwn_b2062_chantable_data[12] },
768         { 153, 5765, bwn_b2062_chantable_data[12] },
769         { 157, 5785, bwn_b2062_chantable_data[12] },
770         { 161, 5805, bwn_b2062_chantable_data[12] },
771         { 165, 5825, bwn_b2062_chantable_data[12] },
772         { 184, 4920, bwn_b2062_chantable_data[13] },
773         { 188, 4940, bwn_b2062_chantable_data[14] },
774         { 192, 4960, bwn_b2062_chantable_data[15] },
775         { 196, 4980, bwn_b2062_chantable_data[16] },
776         { 200, 5000, bwn_b2062_chantable_data[17] },
777         { 204, 5020, bwn_b2062_chantable_data[18] },
778         { 208, 5040, bwn_b2062_chantable_data[19] },
779         { 212, 5060, bwn_b2062_chantable_data[20] },
780         { 216, 5080, bwn_b2062_chantable_data[21] }
781 };
782
783 /* for LP PHY */
784 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
785         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
786         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
787         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
788         { 13, -66, 13 }, { 14, -66, 13 },
789 };
790
791 /* for LP PHY */
792 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
793         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
794         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
795         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
796         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
797         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
798         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
799         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
800         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
801         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
802         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
803         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
804         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
805         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
806 };
807
808 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
809
810 static const uint8_t bwn_tab_sigsq_tbl[] = {
811         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
812         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
813         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
814         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
816         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
817 };
818
819 static const uint8_t bwn_tab_pllfrac_tbl[] = {
820         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
821         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
822 };
823
824 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
825         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
826         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
827         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
829         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
830         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
831         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
832         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837 };
838
839 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
840 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
841 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
842 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
843 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
844 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
845
846 #define VENDOR_LED_ACT(vendor)                          \
847 {                                                       \
848         .vid = PCI_VENDOR_##vendor,                     \
849         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
850 }
851
852 static const struct {
853         uint16_t        vid;
854         uint8_t         led_act[BWN_LED_MAX];
855 } bwn_vendor_led_act[] = {
856         VENDOR_LED_ACT(COMPAQ),
857         VENDOR_LED_ACT(ASUSTEK)
858 };
859
860 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
861         { BWN_VENDOR_LED_ACT_DEFAULT };
862
863 #undef VENDOR_LED_ACT
864
865 static const struct {
866         int             on_dur;
867         int             off_dur;
868 } bwn_led_duration[109] = {
869         [0]     = { 400, 100 },
870         [2]     = { 150, 75 },
871         [4]     = { 90, 45 },
872         [11]    = { 66, 34 },
873         [12]    = { 53, 26 },
874         [18]    = { 42, 21 },
875         [22]    = { 35, 17 },
876         [24]    = { 32, 16 },
877         [36]    = { 21, 10 },
878         [48]    = { 16, 8 },
879         [72]    = { 11, 5 },
880         [96]    = { 9, 4 },
881         [108]   = { 7, 3 }
882 };
883
884 static const uint16_t bwn_wme_shm_offsets[] = {
885         [0] = BWN_WME_BESTEFFORT,
886         [1] = BWN_WME_BACKGROUND,
887         [2] = BWN_WME_VOICE,
888         [3] = BWN_WME_VIDEO,
889 };
890
891 static const struct siba_devid bwn_devs[] = {
892         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
893         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
894         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
895         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
896         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
897         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
898         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
899         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
900         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
901 };
902
903 static int
904 bwn_probe(device_t dev)
905 {
906         int i;
907
908         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
909                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
910                     siba_get_device(dev) == bwn_devs[i].sd_device &&
911                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
912                         return (BUS_PROBE_DEFAULT);
913         }
914
915         return (ENXIO);
916 }
917
918 static int
919 bwn_attach(device_t dev)
920 {
921         struct bwn_mac *mac;
922         struct bwn_softc *sc = device_get_softc(dev);
923         int error, i, msic, reg;
924
925         sc->sc_dev = dev;
926 #ifdef BWN_DEBUG
927         sc->sc_debug = bwn_debug;
928 #endif
929
930         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
931                 bwn_attach_pre(sc);
932                 bwn_sprom_bugfixes(dev);
933                 sc->sc_flags |= BWN_FLAG_ATTACHED;
934         }
935
936         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
937                 if (siba_get_pci_device(dev) != 0x4313 &&
938                     siba_get_pci_device(dev) != 0x431a &&
939                     siba_get_pci_device(dev) != 0x4321) {
940                         device_printf(sc->sc_dev,
941                             "skip 802.11 cores\n");
942                         return (ENODEV);
943                 }
944         }
945
946         mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
947         mac->mac_sc = sc;
948         mac->mac_status = BWN_MAC_STATUS_UNINIT;
949         if (bwn_bfp != 0)
950                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
951
952         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
953         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
954         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
955
956         error = bwn_attach_core(mac);
957         if (error)
958                 goto fail0;
959         bwn_led_attach(mac);
960
961         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
962             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
963             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
964             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
965             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
966             mac->mac_phy.rf_rev);
967         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
968                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
969                     mac->mac_method.dma.dmatype);
970         else
971                 device_printf(sc->sc_dev, "PIO\n");
972
973         /*
974          * setup PCI resources and interrupt.
975          */
976         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
977                 msic = pci_msi_count(dev);
978                 if (bootverbose)
979                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
980         } else
981                 msic = 0;
982
983         mac->mac_intr_spec = bwn_res_spec_legacy;
984         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
985                 if (pci_alloc_msi(dev, &msic) == 0) {
986                         device_printf(sc->sc_dev,
987                             "Using %d MSI messages\n", msic);
988                         mac->mac_intr_spec = bwn_res_spec_msi;
989                         mac->mac_msi = 1;
990                 }
991         }
992
993         error = bus_alloc_resources(dev, mac->mac_intr_spec,
994             mac->mac_res_irq);
995         if (error) {
996                 device_printf(sc->sc_dev,
997                     "couldn't allocate IRQ resources (%d)\n", error);
998                 goto fail1;
999         }
1000
1001         if (mac->mac_msi == 0)
1002                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1003                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1004                     &mac->mac_intrhand[0]);
1005         else {
1006                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1007                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1008                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1009                             &mac->mac_intrhand[i]);
1010                         if (error != 0) {
1011                                 device_printf(sc->sc_dev,
1012                                     "couldn't setup interrupt (%d)\n", error);
1013                                 break;
1014                         }
1015                 }
1016         }
1017
1018         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1019
1020         /*
1021          * calls attach-post routine
1022          */
1023         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1024                 bwn_attach_post(sc);
1025
1026         return (0);
1027 fail1:
1028         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1029                 pci_release_msi(dev);
1030 fail0:
1031         free(mac, M_DEVBUF);
1032         return (error);
1033 }
1034
1035 static int
1036 bwn_is_valid_ether_addr(uint8_t *addr)
1037 {
1038         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1039
1040         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1041                 return (FALSE);
1042
1043         return (TRUE);
1044 }
1045
1046 static int
1047 bwn_attach_post(struct bwn_softc *sc)
1048 {
1049         struct ieee80211com *ic = &sc->sc_ic;
1050
1051         ic->ic_softc = sc;
1052         ic->ic_name = device_get_nameunit(sc->sc_dev);
1053         /* XXX not right but it's not used anywhere important */
1054         ic->ic_phytype = IEEE80211_T_OFDM;
1055         ic->ic_opmode = IEEE80211_M_STA;
1056         ic->ic_caps =
1057                   IEEE80211_C_STA               /* station mode supported */
1058                 | IEEE80211_C_MONITOR           /* monitor mode */
1059                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1060                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1061                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1062                 | IEEE80211_C_WME               /* WME/WMM supported */
1063                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1064                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1065                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1066                 ;
1067
1068         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1069
1070         IEEE80211_ADDR_COPY(ic->ic_macaddr,
1071             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1072             siba_sprom_get_mac_80211a(sc->sc_dev) :
1073             siba_sprom_get_mac_80211bg(sc->sc_dev));
1074
1075         /* call MI attach routine. */
1076         ieee80211_ifattach(ic);
1077
1078         ic->ic_headroom = sizeof(struct bwn_txhdr);
1079
1080         /* override default methods */
1081         ic->ic_raw_xmit = bwn_raw_xmit;
1082         ic->ic_updateslot = bwn_updateslot;
1083         ic->ic_update_promisc = bwn_update_promisc;
1084         ic->ic_wme.wme_update = bwn_wme_update;
1085         ic->ic_scan_start = bwn_scan_start;
1086         ic->ic_scan_end = bwn_scan_end;
1087         ic->ic_set_channel = bwn_set_channel;
1088         ic->ic_vap_create = bwn_vap_create;
1089         ic->ic_vap_delete = bwn_vap_delete;
1090         ic->ic_transmit = bwn_transmit;
1091         ic->ic_parent = bwn_parent;
1092
1093         ieee80211_radiotap_attach(ic,
1094             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1095             BWN_TX_RADIOTAP_PRESENT,
1096             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1097             BWN_RX_RADIOTAP_PRESENT);
1098
1099         bwn_sysctl_node(sc);
1100
1101         if (bootverbose)
1102                 ieee80211_announce(ic);
1103         return (0);
1104 }
1105
1106 static void
1107 bwn_phy_detach(struct bwn_mac *mac)
1108 {
1109
1110         if (mac->mac_phy.detach != NULL)
1111                 mac->mac_phy.detach(mac);
1112 }
1113
1114 static int
1115 bwn_detach(device_t dev)
1116 {
1117         struct bwn_softc *sc = device_get_softc(dev);
1118         struct bwn_mac *mac = sc->sc_curmac;
1119         struct ieee80211com *ic = &sc->sc_ic;
1120         int i;
1121
1122         sc->sc_flags |= BWN_FLAG_INVALID;
1123
1124         if (device_is_attached(sc->sc_dev)) {
1125                 BWN_LOCK(sc);
1126                 bwn_stop(sc);
1127                 BWN_UNLOCK(sc);
1128                 bwn_dma_free(mac);
1129                 callout_drain(&sc->sc_led_blink_ch);
1130                 callout_drain(&sc->sc_rfswitch_ch);
1131                 callout_drain(&sc->sc_task_ch);
1132                 callout_drain(&sc->sc_watchdog_ch);
1133                 bwn_phy_detach(mac);
1134                 ieee80211_draintask(ic, &mac->mac_hwreset);
1135                 ieee80211_draintask(ic, &mac->mac_txpower);
1136                 ieee80211_ifdetach(ic);
1137         }
1138         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1139         taskqueue_free(sc->sc_tq);
1140
1141         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1142                 if (mac->mac_intrhand[i] != NULL) {
1143                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1144                             mac->mac_intrhand[i]);
1145                         mac->mac_intrhand[i] = NULL;
1146                 }
1147         }
1148         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1149         if (mac->mac_msi != 0)
1150                 pci_release_msi(dev);
1151         mbufq_drain(&sc->sc_snd);
1152         BWN_LOCK_DESTROY(sc);
1153         return (0);
1154 }
1155
1156 static void
1157 bwn_attach_pre(struct bwn_softc *sc)
1158 {
1159
1160         BWN_LOCK_INIT(sc);
1161         TAILQ_INIT(&sc->sc_maclist);
1162         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1163         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1164         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1165         mbufq_init(&sc->sc_snd, ifqmaxlen);
1166         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1167                 taskqueue_thread_enqueue, &sc->sc_tq);
1168         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1169                 "%s taskq", device_get_nameunit(sc->sc_dev));
1170 }
1171
1172 static void
1173 bwn_sprom_bugfixes(device_t dev)
1174 {
1175 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1176         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1177          (siba_get_pci_device(dev) == _device) &&                       \
1178          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1179          (siba_get_pci_subdevice(dev) == _subdevice))
1180
1181         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1182             siba_get_pci_subdevice(dev) == 0x4e &&
1183             siba_get_pci_revid(dev) > 0x40)
1184                 siba_sprom_set_bf_lo(dev,
1185                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1186         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1187             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1188                 siba_sprom_set_bf_lo(dev,
1189                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1190         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1191                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1192                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1193                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1194                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1195                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1196                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1197                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1198                         siba_sprom_set_bf_lo(dev,
1199                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1200         }
1201 #undef  BWN_ISDEV
1202 }
1203
1204 static void
1205 bwn_parent(struct ieee80211com *ic)
1206 {
1207         struct bwn_softc *sc = ic->ic_softc;
1208         int startall = 0;
1209
1210         BWN_LOCK(sc);
1211         if (ic->ic_nrunning > 0) {
1212                 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1213                         bwn_init(sc);
1214                         startall = 1;
1215                 } else
1216                         bwn_update_promisc(ic);
1217         } else if (sc->sc_flags & BWN_FLAG_RUNNING)
1218                 bwn_stop(sc);
1219         BWN_UNLOCK(sc);
1220
1221         if (startall)
1222                 ieee80211_start_all(ic);
1223 }
1224
1225 static int
1226 bwn_transmit(struct ieee80211com *ic, struct mbuf *m)
1227 {
1228         struct bwn_softc *sc = ic->ic_softc;
1229         int error;
1230
1231         BWN_LOCK(sc);
1232         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1233                 BWN_UNLOCK(sc);
1234                 return (ENXIO);
1235         }
1236         error = mbufq_enqueue(&sc->sc_snd, m);
1237         if (error) {
1238                 BWN_UNLOCK(sc);
1239                 return (error);
1240         }
1241         bwn_start(sc);
1242         BWN_UNLOCK(sc);
1243         return (0);
1244 }
1245
1246 static void
1247 bwn_start(struct bwn_softc *sc)
1248 {
1249         struct bwn_mac *mac = sc->sc_curmac;
1250         struct ieee80211_frame *wh;
1251         struct ieee80211_node *ni;
1252         struct ieee80211_key *k;
1253         struct mbuf *m;
1254
1255         BWN_ASSERT_LOCKED(sc);
1256
1257         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
1258             mac->mac_status < BWN_MAC_STATUS_STARTED)
1259                 return;
1260
1261         while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1262                 if (bwn_tx_isfull(sc, m))
1263                         break;
1264                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1265                 if (ni == NULL) {
1266                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1267                         m_freem(m);
1268                         counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1269                         continue;
1270                 }
1271                 wh = mtod(m, struct ieee80211_frame *);
1272                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1273                         k = ieee80211_crypto_encap(ni, m);
1274                         if (k == NULL) {
1275                                 if_inc_counter(ni->ni_vap->iv_ifp,
1276                                     IFCOUNTER_OERRORS, 1);
1277                                 ieee80211_free_node(ni);
1278                                 m_freem(m);
1279                                 continue;
1280                         }
1281                 }
1282                 wh = NULL;      /* Catch any invalid use */
1283                 if (bwn_tx_start(sc, ni, m) != 0) {
1284                         if (ni != NULL) {
1285                                 if_inc_counter(ni->ni_vap->iv_ifp,
1286                                     IFCOUNTER_OERRORS, 1);
1287                                 ieee80211_free_node(ni);
1288                         }
1289                         continue;
1290                 }
1291                 sc->sc_watchdog_timer = 5;
1292         }
1293 }
1294
1295 static int
1296 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1297 {
1298         struct bwn_dma_ring *dr;
1299         struct bwn_mac *mac = sc->sc_curmac;
1300         struct bwn_pio_txqueue *tq;
1301         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1302
1303         BWN_ASSERT_LOCKED(sc);
1304
1305         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1306                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1307                 if (dr->dr_stop == 1 ||
1308                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1309                         dr->dr_stop = 1;
1310                         goto full;
1311                 }
1312         } else {
1313                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1314                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1315                     pktlen > (tq->tq_size - tq->tq_used))
1316                         goto full;
1317         }
1318         return (0);
1319 full:
1320         mbufq_prepend(&sc->sc_snd, m);
1321         return (1);
1322 }
1323
1324 static int
1325 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1326 {
1327         struct bwn_mac *mac = sc->sc_curmac;
1328         int error;
1329
1330         BWN_ASSERT_LOCKED(sc);
1331
1332         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1333                 m_freem(m);
1334                 return (ENXIO);
1335         }
1336
1337         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1338             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1339         if (error) {
1340                 m_freem(m);
1341                 return (error);
1342         }
1343         return (0);
1344 }
1345
1346 static int
1347 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1348 {
1349         struct bwn_pio_txpkt *tp;
1350         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1351         struct bwn_softc *sc = mac->mac_sc;
1352         struct bwn_txhdr txhdr;
1353         struct mbuf *m_new;
1354         uint32_t ctl32;
1355         int error;
1356         uint16_t ctl16;
1357
1358         BWN_ASSERT_LOCKED(sc);
1359
1360         /* XXX TODO send packets after DTIM */
1361
1362         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1363         tp = TAILQ_FIRST(&tq->tq_pktlist);
1364         tp->tp_ni = ni;
1365         tp->tp_m = m;
1366
1367         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1368         if (error) {
1369                 device_printf(sc->sc_dev, "tx fail\n");
1370                 return (error);
1371         }
1372
1373         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1374         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1375         tq->tq_free--;
1376
1377         if (siba_get_revid(sc->sc_dev) >= 8) {
1378                 /*
1379                  * XXX please removes m_defrag(9)
1380                  */
1381                 m_new = m_defrag(m, M_NOWAIT);
1382                 if (m_new == NULL) {
1383                         device_printf(sc->sc_dev,
1384                             "%s: can't defrag TX buffer\n",
1385                             __func__);
1386                         return (ENOBUFS);
1387                 }
1388                 if (m_new->m_next != NULL)
1389                         device_printf(sc->sc_dev,
1390                             "TODO: fragmented packets for PIO\n");
1391                 tp->tp_m = m_new;
1392
1393                 /* send HEADER */
1394                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1395                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1396                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1397                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1398                 /* send BODY */
1399                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1400                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1401                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1402                     ctl32 | BWN_PIO8_TXCTL_EOF);
1403         } else {
1404                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1405                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1406                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1407                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1408                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1409                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1410                     ctl16 | BWN_PIO_TXCTL_EOF);
1411         }
1412
1413         return (0);
1414 }
1415
1416 static struct bwn_pio_txqueue *
1417 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1418 {
1419
1420         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1421                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1422
1423         switch (prio) {
1424         case 0:
1425                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1426         case 1:
1427                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1428         case 2:
1429                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1430         case 3:
1431                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1432         }
1433         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1434         return (NULL);
1435 }
1436
1437 static int
1438 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1439 {
1440 #define BWN_GET_TXHDRCACHE(slot)                                        \
1441         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1442         struct bwn_dma *dma = &mac->mac_method.dma;
1443         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1444         struct bwn_dmadesc_generic *desc;
1445         struct bwn_dmadesc_meta *mt;
1446         struct bwn_softc *sc = mac->mac_sc;
1447         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1448         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1449
1450         BWN_ASSERT_LOCKED(sc);
1451         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1452
1453         /* XXX send after DTIM */
1454
1455         slot = bwn_dma_getslot(dr);
1456         dr->getdesc(dr, slot, &desc, &mt);
1457         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1458             ("%s:%d: fail", __func__, __LINE__));
1459
1460         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1461             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1462             BWN_DMA_COOKIE(dr, slot));
1463         if (error)
1464                 goto fail;
1465         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1466             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1467             &mt->mt_paddr, BUS_DMA_NOWAIT);
1468         if (error) {
1469                 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1470                     __func__, error);
1471                 goto fail;
1472         }
1473         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1474             BUS_DMASYNC_PREWRITE);
1475         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1476         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1477             BUS_DMASYNC_PREWRITE);
1478
1479         slot = bwn_dma_getslot(dr);
1480         dr->getdesc(dr, slot, &desc, &mt);
1481         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1482             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1483         mt->mt_m = m;
1484         mt->mt_ni = ni;
1485
1486         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1487             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1488         if (error && error != EFBIG) {
1489                 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1490                     __func__, error);
1491                 goto fail;
1492         }
1493         if (error) {    /* error == EFBIG */
1494                 struct mbuf *m_new;
1495
1496                 m_new = m_defrag(m, M_NOWAIT);
1497                 if (m_new == NULL) {
1498                         device_printf(sc->sc_dev,
1499                             "%s: can't defrag TX buffer\n",
1500                             __func__);
1501                         error = ENOBUFS;
1502                         goto fail;
1503                 } else {
1504                         m = m_new;
1505                 }
1506
1507                 mt->mt_m = m;
1508                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1509                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1510                 if (error) {
1511                         device_printf(sc->sc_dev,
1512                             "%s: can't load TX buffer (2) %d\n",
1513                             __func__, error);
1514                         goto fail;
1515                 }
1516         }
1517         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1518         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1519         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1520             BUS_DMASYNC_PREWRITE);
1521
1522         /* XXX send after DTIM */
1523
1524         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1525         return (0);
1526 fail:
1527         dr->dr_curslot = backup[0];
1528         dr->dr_usedslot = backup[1];
1529         return (error);
1530 #undef BWN_GET_TXHDRCACHE
1531 }
1532
1533 static void
1534 bwn_watchdog(void *arg)
1535 {
1536         struct bwn_softc *sc = arg;
1537
1538         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1539                 device_printf(sc->sc_dev, "device timeout\n");
1540                 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1541         }
1542         callout_schedule(&sc->sc_watchdog_ch, hz);
1543 }
1544
1545 static int
1546 bwn_attach_core(struct bwn_mac *mac)
1547 {
1548         struct bwn_softc *sc = mac->mac_sc;
1549         int error, have_bg = 0, have_a = 0;
1550         uint32_t high;
1551
1552         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1553             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1554
1555         siba_powerup(sc->sc_dev, 0);
1556
1557         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1558         bwn_reset_core(mac,
1559             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1560         error = bwn_phy_getinfo(mac, high);
1561         if (error)
1562                 goto fail;
1563
1564         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1565         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1566         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1567             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1568             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1569                 have_a = have_bg = 0;
1570                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1571                         have_a = 1;
1572                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1573                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1574                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1575                         have_bg = 1;
1576                 else
1577                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1578                             mac->mac_phy.type));
1579         }
1580         /* XXX turns off PHY A because it's not supported */
1581         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1582             mac->mac_phy.type != BWN_PHYTYPE_N) {
1583                 have_a = 0;
1584                 have_bg = 1;
1585         }
1586
1587         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1588                 mac->mac_phy.attach = bwn_phy_g_attach;
1589                 mac->mac_phy.detach = bwn_phy_g_detach;
1590                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1591                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1592                 mac->mac_phy.init = bwn_phy_g_init;
1593                 mac->mac_phy.exit = bwn_phy_g_exit;
1594                 mac->mac_phy.phy_read = bwn_phy_g_read;
1595                 mac->mac_phy.phy_write = bwn_phy_g_write;
1596                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1597                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1598                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1599                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1600                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1601                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1602                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1603                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1604                 mac->mac_phy.set_im = bwn_phy_g_im;
1605                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1606                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1607                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1608                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1609         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1610                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1611                 mac->mac_phy.init = bwn_phy_lp_init;
1612                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1613                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1614                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1615                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1616                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1617                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1618                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1619                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1620                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1621                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1622                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1623         } else {
1624                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1625                     mac->mac_phy.type);
1626                 error = ENXIO;
1627                 goto fail;
1628         }
1629
1630         mac->mac_phy.gmode = have_bg;
1631         if (mac->mac_phy.attach != NULL) {
1632                 error = mac->mac_phy.attach(mac);
1633                 if (error) {
1634                         device_printf(sc->sc_dev, "failed\n");
1635                         goto fail;
1636                 }
1637         }
1638
1639         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1640
1641         error = bwn_chiptest(mac);
1642         if (error)
1643                 goto fail;
1644         error = bwn_setup_channels(mac, have_bg, have_a);
1645         if (error) {
1646                 device_printf(sc->sc_dev, "failed to setup channels\n");
1647                 goto fail;
1648         }
1649
1650         if (sc->sc_curmac == NULL)
1651                 sc->sc_curmac = mac;
1652
1653         error = bwn_dma_attach(mac);
1654         if (error != 0) {
1655                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1656                 goto fail;
1657         }
1658
1659         mac->mac_phy.switch_analog(mac, 0);
1660
1661         siba_dev_down(sc->sc_dev, 0);
1662 fail:
1663         siba_powerdown(sc->sc_dev);
1664         return (error);
1665 }
1666
1667 static void
1668 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1669 {
1670         struct bwn_softc *sc = mac->mac_sc;
1671         uint32_t low, ctl;
1672
1673         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1674
1675         siba_dev_up(sc->sc_dev, flags);
1676         DELAY(2000);
1677
1678         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1679             ~BWN_TGSLOW_PHYRESET;
1680         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1681         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1682         DELAY(1000);
1683         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1684         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1685         DELAY(1000);
1686
1687         if (mac->mac_phy.switch_analog != NULL)
1688                 mac->mac_phy.switch_analog(mac, 1);
1689
1690         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1691         if (flags & BWN_TGSLOW_SUPPORT_G)
1692                 ctl |= BWN_MACCTL_GMODE;
1693         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1694 }
1695
1696 static int
1697 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1698 {
1699         struct bwn_phy *phy = &mac->mac_phy;
1700         struct bwn_softc *sc = mac->mac_sc;
1701         uint32_t tmp;
1702
1703         /* PHY */
1704         tmp = BWN_READ_2(mac, BWN_PHYVER);
1705         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1706         phy->rf_on = 1;
1707         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1708         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1709         phy->rev = (tmp & BWN_PHYVER_VERSION);
1710         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1711             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1712                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1713             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1714             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1715             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1716                 goto unsupphy;
1717
1718         /* RADIO */
1719         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1720                 if (siba_get_chiprev(sc->sc_dev) == 0)
1721                         tmp = 0x3205017f;
1722                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1723                         tmp = 0x4205017f;
1724                 else
1725                         tmp = 0x5205017f;
1726         } else {
1727                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1728                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1729                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1730                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1731         }
1732         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1733         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1734         phy->rf_manuf = (tmp & 0x00000fff);
1735         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1736                 goto unsupradio;
1737         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1738              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1739             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1740             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1741             (phy->type == BWN_PHYTYPE_N &&
1742              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1743             (phy->type == BWN_PHYTYPE_LP &&
1744              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1745                 goto unsupradio;
1746
1747         return (0);
1748 unsupphy:
1749         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1750             "analog %#x)\n",
1751             phy->type, phy->rev, phy->analog);
1752         return (ENXIO);
1753 unsupradio:
1754         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1755             "rev %#x)\n",
1756             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1757         return (ENXIO);
1758 }
1759
1760 static int
1761 bwn_chiptest(struct bwn_mac *mac)
1762 {
1763 #define TESTVAL0        0x55aaaa55
1764 #define TESTVAL1        0xaa5555aa
1765         struct bwn_softc *sc = mac->mac_sc;
1766         uint32_t v, backup;
1767
1768         BWN_LOCK(sc);
1769
1770         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1771
1772         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1773         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1774                 goto error;
1775         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1776         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1777                 goto error;
1778
1779         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1780
1781         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1782             (siba_get_revid(sc->sc_dev) <= 10)) {
1783                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1784                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1785                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1786                         goto error;
1787                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1788                         goto error;
1789         }
1790         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1791
1792         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1793         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1794                 goto error;
1795
1796         BWN_UNLOCK(sc);
1797         return (0);
1798 error:
1799         BWN_UNLOCK(sc);
1800         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1801         return (ENODEV);
1802 }
1803
1804 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1805 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1806
1807 static int
1808 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1809 {
1810         struct bwn_softc *sc = mac->mac_sc;
1811         struct ieee80211com *ic = &sc->sc_ic;
1812
1813         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1814         ic->ic_nchans = 0;
1815
1816         if (have_bg)
1817                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1818                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1819         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1820                 if (have_a)
1821                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1822                             &ic->ic_nchans, &bwn_chantable_n,
1823                             IEEE80211_CHAN_HTA);
1824         } else {
1825                 if (have_a)
1826                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1827                             &ic->ic_nchans, &bwn_chantable_a,
1828                             IEEE80211_CHAN_A);
1829         }
1830
1831         mac->mac_phy.supports_2ghz = have_bg;
1832         mac->mac_phy.supports_5ghz = have_a;
1833
1834         return (ic->ic_nchans == 0 ? ENXIO : 0);
1835 }
1836
1837 static uint32_t
1838 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1839 {
1840         uint32_t ret;
1841
1842         BWN_ASSERT_LOCKED(mac->mac_sc);
1843
1844         if (way == BWN_SHARED) {
1845                 KASSERT((offset & 0x0001) == 0,
1846                     ("%s:%d warn", __func__, __LINE__));
1847                 if (offset & 0x0003) {
1848                         bwn_shm_ctlword(mac, way, offset >> 2);
1849                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1850                         ret <<= 16;
1851                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1852                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1853                         goto out;
1854                 }
1855                 offset >>= 2;
1856         }
1857         bwn_shm_ctlword(mac, way, offset);
1858         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1859 out:
1860         return (ret);
1861 }
1862
1863 static uint16_t
1864 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1865 {
1866         uint16_t ret;
1867
1868         BWN_ASSERT_LOCKED(mac->mac_sc);
1869
1870         if (way == BWN_SHARED) {
1871                 KASSERT((offset & 0x0001) == 0,
1872                     ("%s:%d warn", __func__, __LINE__));
1873                 if (offset & 0x0003) {
1874                         bwn_shm_ctlword(mac, way, offset >> 2);
1875                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1876                         goto out;
1877                 }
1878                 offset >>= 2;
1879         }
1880         bwn_shm_ctlword(mac, way, offset);
1881         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1882 out:
1883
1884         return (ret);
1885 }
1886
1887 static void
1888 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1889     uint16_t offset)
1890 {
1891         uint32_t control;
1892
1893         control = way;
1894         control <<= 16;
1895         control |= offset;
1896         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1897 }
1898
1899 static void
1900 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1901     uint32_t value)
1902 {
1903         BWN_ASSERT_LOCKED(mac->mac_sc);
1904
1905         if (way == BWN_SHARED) {
1906                 KASSERT((offset & 0x0001) == 0,
1907                     ("%s:%d warn", __func__, __LINE__));
1908                 if (offset & 0x0003) {
1909                         bwn_shm_ctlword(mac, way, offset >> 2);
1910                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911                                     (value >> 16) & 0xffff);
1912                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1914                         return;
1915                 }
1916                 offset >>= 2;
1917         }
1918         bwn_shm_ctlword(mac, way, offset);
1919         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1920 }
1921
1922 static void
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1924     uint16_t value)
1925 {
1926         BWN_ASSERT_LOCKED(mac->mac_sc);
1927
1928         if (way == BWN_SHARED) {
1929                 KASSERT((offset & 0x0001) == 0,
1930                     ("%s:%d warn", __func__, __LINE__));
1931                 if (offset & 0x0003) {
1932                         bwn_shm_ctlword(mac, way, offset >> 2);
1933                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1934                         return;
1935                 }
1936                 offset >>= 2;
1937         }
1938         bwn_shm_ctlword(mac, way, offset);
1939         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1940 }
1941
1942 static void
1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1944     int txpow)
1945 {
1946
1947         c->ic_freq = freq;
1948         c->ic_flags = flags;
1949         c->ic_ieee = ieee;
1950         c->ic_minpower = 0;
1951         c->ic_maxpower = 2 * txpow;
1952         c->ic_maxregpower = txpow;
1953 }
1954
1955 static void
1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1957     const struct bwn_channelinfo *ci, int flags)
1958 {
1959         struct ieee80211_channel *c;
1960         int i;
1961
1962         c = &chans[*nchans];
1963
1964         for (i = 0; i < ci->nchannels; i++) {
1965                 const struct bwn_channel *hc;
1966
1967                 hc = &ci->channels[i];
1968                 if (*nchans >= maxchans)
1969                         break;
1970                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1971                 c++, (*nchans)++;
1972                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1973                         /* g channel have a separate b-only entry */
1974                         if (*nchans >= maxchans)
1975                                 break;
1976                         c[0] = c[-1];
1977                         c[-1].ic_flags = IEEE80211_CHAN_B;
1978                         c++, (*nchans)++;
1979                 }
1980                 if (flags == IEEE80211_CHAN_HTG) {
1981                         /* HT g channel have a separate g-only entry */
1982                         if (*nchans >= maxchans)
1983                                 break;
1984                         c[-1].ic_flags = IEEE80211_CHAN_G;
1985                         c[0] = c[-1];
1986                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1987                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1988                         c++, (*nchans)++;
1989                 }
1990                 if (flags == IEEE80211_CHAN_HTA) {
1991                         /* HT a channel have a separate a-only entry */
1992                         if (*nchans >= maxchans)
1993                                 break;
1994                         c[-1].ic_flags = IEEE80211_CHAN_A;
1995                         c[0] = c[-1];
1996                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1997                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1998                         c++, (*nchans)++;
1999                 }
2000         }
2001 }
2002
2003 static int
2004 bwn_phy_g_attach(struct bwn_mac *mac)
2005 {
2006         struct bwn_softc *sc = mac->mac_sc;
2007         struct bwn_phy *phy = &mac->mac_phy;
2008         struct bwn_phy_g *pg = &phy->phy_g;
2009         unsigned int i;
2010         int16_t pab0, pab1, pab2;
2011         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2012         int8_t bg;
2013
2014         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2015         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2016         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2017         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2018
2019         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2020                 device_printf(sc->sc_dev, "not supported anymore\n");
2021
2022         pg->pg_flags = 0;
2023         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2024             pab2 == -1) {
2025                 pg->pg_idletssi = 52;
2026                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2027                 return (0);
2028         }
2029
2030         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2031         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2032         if (pg->pg_tssi2dbm == NULL) {
2033                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2034                 return (ENOMEM);
2035         }
2036         for (i = 0; i < 64; i++) {
2037                 int32_t m1, m2, f, q, delta;
2038                 int8_t j = 0;
2039
2040                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2041                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2042                 f = 256;
2043
2044                 do {
2045                         if (j > 15) {
2046                                 device_printf(sc->sc_dev,
2047                                     "failed to generate tssi2dBm\n");
2048                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2049                                 return (ENOMEM);
2050                         }
2051                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2052                             f, 2048);
2053                         delta = abs(q - f);
2054                         f = q;
2055                         j++;
2056                 } while (delta >= 2);
2057
2058                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2059                     128);
2060         }
2061
2062         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2063         return (0);
2064 }
2065
2066 static void
2067 bwn_phy_g_detach(struct bwn_mac *mac)
2068 {
2069         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2070
2071         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2072                 free(pg->pg_tssi2dbm, M_DEVBUF);
2073                 pg->pg_tssi2dbm = NULL;
2074         }
2075         pg->pg_flags = 0;
2076 }
2077
2078 static void
2079 bwn_phy_g_init_pre(struct bwn_mac *mac)
2080 {
2081         struct bwn_phy *phy = &mac->mac_phy;
2082         struct bwn_phy_g *pg = &phy->phy_g;
2083         void *tssi2dbm;
2084         int idletssi;
2085         unsigned int i;
2086
2087         tssi2dbm = pg->pg_tssi2dbm;
2088         idletssi = pg->pg_idletssi;
2089
2090         memset(pg, 0, sizeof(*pg));
2091
2092         pg->pg_tssi2dbm = tssi2dbm;
2093         pg->pg_idletssi = idletssi;
2094
2095         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2096
2097         for (i = 0; i < N(pg->pg_nrssi); i++)
2098                 pg->pg_nrssi[i] = -1000;
2099         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2100                 pg->pg_nrssi_lt[i] = i;
2101         pg->pg_lofcal = 0xffff;
2102         pg->pg_initval = 0xffff;
2103         pg->pg_immode = BWN_IMMODE_NONE;
2104         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2105         pg->pg_avgtssi = 0xff;
2106
2107         pg->pg_loctl.tx_bias = 0xff;
2108         TAILQ_INIT(&pg->pg_loctl.calib_list);
2109 }
2110
2111 static int
2112 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2113 {
2114         struct bwn_phy *phy = &mac->mac_phy;
2115         struct bwn_phy_g *pg = &phy->phy_g;
2116         struct bwn_softc *sc = mac->mac_sc;
2117         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2118         static const struct bwn_rfatt rfatt0[] = {
2119                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2120                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2121                 { 3, 1 }, { 4, 1 }
2122         };
2123         static const struct bwn_rfatt rfatt1[] = {
2124                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2125                 { 14, 1 }
2126         };
2127         static const struct bwn_rfatt rfatt2[] = {
2128                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2129                 { 9, 1 }
2130         };
2131         static const struct bwn_bbatt bbatt_0[] = {
2132                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2133         };
2134
2135         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2136
2137         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2138                 pg->pg_bbatt.att = 0;
2139         else
2140                 pg->pg_bbatt.att = 2;
2141
2142         /* prepare Radio Attenuation */
2143         pg->pg_rfatt.padmix = 0;
2144
2145         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2146             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2147                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2148                         pg->pg_rfatt.att = 2;
2149                         goto done;
2150                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2151                         pg->pg_rfatt.att = 3;
2152                         goto done;
2153                 }
2154         }
2155
2156         if (phy->type == BWN_PHYTYPE_A) {
2157                 pg->pg_rfatt.att = 0x60;
2158                 goto done;
2159         }
2160
2161         switch (phy->rf_ver) {
2162         case 0x2050:
2163                 switch (phy->rf_rev) {
2164                 case 0:
2165                         pg->pg_rfatt.att = 5;
2166                         goto done;
2167                 case 1:
2168                         if (phy->type == BWN_PHYTYPE_G) {
2169                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2170                                     SIBA_BOARDVENDOR_BCM &&
2171                                     siba_get_pci_subdevice(sc->sc_dev) ==
2172                                     SIBA_BOARD_BCM4309G &&
2173                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2174                                         pg->pg_rfatt.att = 3;
2175                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2176                                     SIBA_BOARDVENDOR_BCM &&
2177                                     siba_get_pci_subdevice(sc->sc_dev) ==
2178                                     SIBA_BOARD_BU4306)
2179                                         pg->pg_rfatt.att = 3;
2180                                 else
2181                                         pg->pg_rfatt.att = 1;
2182                         } else {
2183                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2184                                     SIBA_BOARDVENDOR_BCM &&
2185                                     siba_get_pci_subdevice(sc->sc_dev) ==
2186                                     SIBA_BOARD_BCM4309G &&
2187                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2188                                         pg->pg_rfatt.att = 7;
2189                                 else
2190                                         pg->pg_rfatt.att = 6;
2191                         }
2192                         goto done;
2193                 case 2:
2194                         if (phy->type == BWN_PHYTYPE_G) {
2195                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2196                                     SIBA_BOARDVENDOR_BCM &&
2197                                     siba_get_pci_subdevice(sc->sc_dev) ==
2198                                     SIBA_BOARD_BCM4309G &&
2199                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2200                                         pg->pg_rfatt.att = 3;
2201                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2202                                     SIBA_BOARDVENDOR_BCM &&
2203                                     siba_get_pci_subdevice(sc->sc_dev) ==
2204                                     SIBA_BOARD_BU4306)
2205                                         pg->pg_rfatt.att = 5;
2206                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2207                                         pg->pg_rfatt.att = 4;
2208                                 else
2209                                         pg->pg_rfatt.att = 3;
2210                         } else
2211                                 pg->pg_rfatt.att = 6;
2212                         goto done;
2213                 case 3:
2214                         pg->pg_rfatt.att = 5;
2215                         goto done;
2216                 case 4:
2217                 case 5:
2218                         pg->pg_rfatt.att = 1;
2219                         goto done;
2220                 case 6:
2221                 case 7:
2222                         pg->pg_rfatt.att = 5;
2223                         goto done;
2224                 case 8:
2225                         pg->pg_rfatt.att = 0xa;
2226                         pg->pg_rfatt.padmix = 1;
2227                         goto done;
2228                 case 9:
2229                 default:
2230                         pg->pg_rfatt.att = 5;
2231                         goto done;
2232                 }
2233                 break;
2234         case 0x2053:
2235                 switch (phy->rf_rev) {
2236                 case 1:
2237                         pg->pg_rfatt.att = 6;
2238                         goto done;
2239                 }
2240                 break;
2241         }
2242         pg->pg_rfatt.att = 5;
2243 done:
2244         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2245
2246         if (!bwn_has_hwpctl(mac)) {
2247                 lo->rfatt.array = rfatt0;
2248                 lo->rfatt.len = N(rfatt0);
2249                 lo->rfatt.min = 0;
2250                 lo->rfatt.max = 9;
2251                 goto genbbatt;
2252         }
2253         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2254                 lo->rfatt.array = rfatt1;
2255                 lo->rfatt.len = N(rfatt1);
2256                 lo->rfatt.min = 0;
2257                 lo->rfatt.max = 14;
2258                 goto genbbatt;
2259         }
2260         lo->rfatt.array = rfatt2;
2261         lo->rfatt.len = N(rfatt2);
2262         lo->rfatt.min = 0;
2263         lo->rfatt.max = 9;
2264 genbbatt:
2265         lo->bbatt.array = bbatt_0;
2266         lo->bbatt.len = N(bbatt_0);
2267         lo->bbatt.min = 0;
2268         lo->bbatt.max = 8;
2269
2270         BWN_READ_4(mac, BWN_MACCTL);
2271         if (phy->rev == 1) {
2272                 phy->gmode = 0;
2273                 bwn_reset_core(mac, 0);
2274                 bwn_phy_g_init_sub(mac);
2275                 phy->gmode = 1;
2276                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2277         }
2278         return (0);
2279 }
2280
2281 static uint16_t
2282 bwn_phy_g_txctl(struct bwn_mac *mac)
2283 {
2284         struct bwn_phy *phy = &mac->mac_phy;
2285
2286         if (phy->rf_ver != 0x2050)
2287                 return (0);
2288         if (phy->rf_rev == 1)
2289                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2290         if (phy->rf_rev < 6)
2291                 return (BWN_TXCTL_PA2DB);
2292         if (phy->rf_rev == 8)
2293                 return (BWN_TXCTL_TXMIX);
2294         return (0);
2295 }
2296
2297 static int
2298 bwn_phy_g_init(struct bwn_mac *mac)
2299 {
2300
2301         bwn_phy_g_init_sub(mac);
2302         return (0);
2303 }
2304
2305 static void
2306 bwn_phy_g_exit(struct bwn_mac *mac)
2307 {
2308         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2309         struct bwn_lo_calib *cal, *tmp;
2310
2311         if (lo == NULL)
2312                 return;
2313         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2314                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2315                 free(cal, M_DEVBUF);
2316         }
2317 }
2318
2319 static uint16_t
2320 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2321 {
2322
2323         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2324         return (BWN_READ_2(mac, BWN_PHYDATA));
2325 }
2326
2327 static void
2328 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2329 {
2330
2331         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2332         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2333 }
2334
2335 static uint16_t
2336 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2337 {
2338
2339         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2340         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2341         return (BWN_READ_2(mac, BWN_RFDATALO));
2342 }
2343
2344 static void
2345 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2346 {
2347
2348         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2349         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2350         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2351 }
2352
2353 static int
2354 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2355 {
2356
2357         return (mac->mac_phy.rev >= 6);
2358 }
2359
2360 static void
2361 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2362 {
2363         struct bwn_phy *phy = &mac->mac_phy;
2364         struct bwn_phy_g *pg = &phy->phy_g;
2365         unsigned int channel;
2366         uint16_t rfover, rfoverval;
2367
2368         if (on) {
2369                 if (phy->rf_on)
2370                         return;
2371
2372                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2373                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2374                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2375                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2376                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2377                             pg->pg_radioctx_over);
2378                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2379                             pg->pg_radioctx_overval);
2380                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2381                 }
2382                 channel = phy->chan;
2383                 bwn_phy_g_switch_chan(mac, 6, 1);
2384                 bwn_phy_g_switch_chan(mac, channel, 0);
2385                 return;
2386         }
2387
2388         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2389         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2390         pg->pg_radioctx_over = rfover;
2391         pg->pg_radioctx_overval = rfoverval;
2392         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2393         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2394         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2395 }
2396
2397 static int
2398 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2399 {
2400
2401         if ((newchan < 1) || (newchan > 14))
2402                 return (EINVAL);
2403         bwn_phy_g_switch_chan(mac, newchan, 0);
2404
2405         return (0);
2406 }
2407
2408 static uint32_t
2409 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2410 {
2411
2412         return (1);
2413 }
2414
2415 static void
2416 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2417 {
2418         struct bwn_phy *phy = &mac->mac_phy;
2419         uint64_t hf;
2420         int autodiv = 0;
2421         uint16_t tmp;
2422
2423         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2424                 autodiv = 1;
2425
2426         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2427         bwn_hf_write(mac, hf);
2428
2429         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2430             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2431             ((autodiv ? BWN_ANTAUTO1 : antenna)
2432                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2433
2434         if (autodiv) {
2435                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2436                 if (antenna == BWN_ANTAUTO1)
2437                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2438                 else
2439                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2440                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2441         }
2442         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2443         if (autodiv)
2444                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2445         else
2446                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2447         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2448         if (phy->rev >= 2) {
2449                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2450                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2451                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2452                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2453                     0x15);
2454                 if (phy->rev == 2)
2455                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2456                 else
2457                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2458                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2459                             8);
2460         }
2461         if (phy->rev >= 6)
2462                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2463
2464         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2465         bwn_hf_write(mac, hf);
2466 }
2467
2468 static int
2469 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2470 {
2471         struct bwn_phy *phy = &mac->mac_phy;
2472         struct bwn_phy_g *pg = &phy->phy_g;
2473
2474         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2475         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2476
2477         if (phy->rev == 0 || !phy->gmode)
2478                 return (ENODEV);
2479
2480         pg->pg_aci_wlan_automatic = 0;
2481         return (0);
2482 }
2483
2484 static int
2485 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2486 {
2487         struct bwn_phy *phy = &mac->mac_phy;
2488         struct bwn_phy_g *pg = &phy->phy_g;
2489         struct bwn_softc *sc = mac->mac_sc;
2490         unsigned int tssi;
2491         int cck, ofdm;
2492         int power;
2493         int rfatt, bbatt;
2494         unsigned int max;
2495
2496         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2497
2498         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2499         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2500         if (cck < 0 && ofdm < 0) {
2501                 if (ignore_tssi == 0)
2502                         return (BWN_TXPWR_RES_DONE);
2503                 cck = 0;
2504                 ofdm = 0;
2505         }
2506         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2507         if (pg->pg_avgtssi != 0xff)
2508                 tssi = (tssi + pg->pg_avgtssi) / 2;
2509         pg->pg_avgtssi = tssi;
2510         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2511
2512         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2513         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2514                 max -= 3;
2515         if (max >= 120) {
2516                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2517                 max = 80;
2518                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2519         }
2520
2521         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2522             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2523              tssi, 0x00), 0x3f)]);
2524         if (power == 0)
2525                 return (BWN_TXPWR_RES_DONE);
2526
2527         rfatt = -((power + 7) / 8);
2528         bbatt = (-(power / 2)) - (4 * rfatt);
2529         if ((rfatt == 0) && (bbatt == 0))
2530                 return (BWN_TXPWR_RES_DONE);
2531         pg->pg_bbatt_delta = bbatt;
2532         pg->pg_rfatt_delta = rfatt;
2533         return (BWN_TXPWR_RES_NEED_ADJUST);
2534 }
2535
2536 static void
2537 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2538 {
2539         struct bwn_phy *phy = &mac->mac_phy;
2540         struct bwn_phy_g *pg = &phy->phy_g;
2541         struct bwn_softc *sc = mac->mac_sc;
2542         int rfatt, bbatt;
2543         uint8_t txctl;
2544
2545         bwn_mac_suspend(mac);
2546
2547         BWN_ASSERT_LOCKED(sc);
2548
2549         bbatt = pg->pg_bbatt.att;
2550         bbatt += pg->pg_bbatt_delta;
2551         rfatt = pg->pg_rfatt.att;
2552         rfatt += pg->pg_rfatt_delta;
2553
2554         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2555         txctl = pg->pg_txctl;
2556         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2557                 if (rfatt <= 1) {
2558                         if (txctl == 0) {
2559                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2560                                 rfatt += 2;
2561                                 bbatt += 2;
2562                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2563                             BWN_BFL_PACTRL) {
2564                                 bbatt += 4 * (rfatt - 2);
2565                                 rfatt = 2;
2566                         }
2567                 } else if (rfatt > 4 && txctl) {
2568                         txctl = 0;
2569                         if (bbatt < 3) {
2570                                 rfatt -= 3;
2571                                 bbatt += 2;
2572                         } else {
2573                                 rfatt -= 2;
2574                                 bbatt -= 2;
2575                         }
2576                 }
2577         }
2578         pg->pg_txctl = txctl;
2579         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2580         pg->pg_rfatt.att = rfatt;
2581         pg->pg_bbatt.att = bbatt;
2582
2583         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2584
2585         bwn_phy_lock(mac);
2586         bwn_rf_lock(mac);
2587         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2588             pg->pg_txctl);
2589         bwn_rf_unlock(mac);
2590         bwn_phy_unlock(mac);
2591
2592         bwn_mac_enable(mac);
2593 }
2594
2595 static void
2596 bwn_phy_g_task_15s(struct bwn_mac *mac)
2597 {
2598         struct bwn_phy *phy = &mac->mac_phy;
2599         struct bwn_phy_g *pg = &phy->phy_g;
2600         struct bwn_softc *sc = mac->mac_sc;
2601         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2602         unsigned long expire, now;
2603         struct bwn_lo_calib *cal, *tmp;
2604         uint8_t expired = 0;
2605
2606         bwn_mac_suspend(mac);
2607
2608         if (lo == NULL)
2609                 goto fail;
2610
2611         BWN_GETTIME(now);
2612         if (bwn_has_hwpctl(mac)) {
2613                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2614                 if (time_before(lo->pwr_vec_read_time, expire)) {
2615                         bwn_lo_get_powervector(mac);
2616                         bwn_phy_g_dc_lookup_init(mac, 0);
2617                 }
2618                 goto fail;
2619         }
2620
2621         expire = now - BWN_LO_CALIB_EXPIRE;
2622         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2623                 if (!time_before(cal->calib_time, expire))
2624                         continue;
2625                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2626                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2627                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2628                         expired = 1;
2629                 }
2630
2631                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2632                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2633                     cal->ctl.i, cal->ctl.q);
2634
2635                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2636                 free(cal, M_DEVBUF);
2637         }
2638         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2639                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2640                     &pg->pg_rfatt);
2641                 if (cal == NULL) {
2642                         device_printf(sc->sc_dev,
2643                             "failed to recalibrate LO\n");
2644                         goto fail;
2645                 }
2646                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2647                 bwn_lo_write(mac, &cal->ctl);
2648         }
2649
2650 fail:
2651         bwn_mac_enable(mac);
2652 }
2653
2654 static void
2655 bwn_phy_g_task_60s(struct bwn_mac *mac)
2656 {
2657         struct bwn_phy *phy = &mac->mac_phy;
2658         struct bwn_softc *sc = mac->mac_sc;
2659         uint8_t old = phy->chan;
2660
2661         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2662                 return;
2663
2664         bwn_mac_suspend(mac);
2665         bwn_nrssi_slope_11g(mac);
2666         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2667                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2668                 bwn_switch_channel(mac, old);
2669         }
2670         bwn_mac_enable(mac);
2671 }
2672
2673 static void
2674 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2675 {
2676
2677         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2678 }
2679
2680 static int
2681 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2682         const struct ieee80211_bpf_params *params)
2683 {
2684         struct ieee80211com *ic = ni->ni_ic;
2685         struct bwn_softc *sc = ic->ic_softc;
2686         struct bwn_mac *mac = sc->sc_curmac;
2687
2688         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
2689             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2690                 ieee80211_free_node(ni);
2691                 m_freem(m);
2692                 return (ENETDOWN);
2693         }
2694
2695         BWN_LOCK(sc);
2696         if (bwn_tx_isfull(sc, m)) {
2697                 ieee80211_free_node(ni);
2698                 m_freem(m);
2699                 BWN_UNLOCK(sc);
2700                 return (ENOBUFS);
2701         }
2702
2703         if (bwn_tx_start(sc, ni, m) != 0) {
2704                 if (ni != NULL)
2705                         ieee80211_free_node(ni);
2706         }
2707         sc->sc_watchdog_timer = 5;
2708         BWN_UNLOCK(sc);
2709         return (0);
2710 }
2711
2712 /*
2713  * Callback from the 802.11 layer to update the slot time
2714  * based on the current setting.  We use it to notify the
2715  * firmware of ERP changes and the f/w takes care of things
2716  * like slot time and preamble.
2717  */
2718 static void
2719 bwn_updateslot(struct ieee80211com *ic)
2720 {
2721         struct bwn_softc *sc = ic->ic_softc;
2722         struct bwn_mac *mac;
2723
2724         BWN_LOCK(sc);
2725         if (sc->sc_flags & BWN_FLAG_RUNNING) {
2726                 mac = (struct bwn_mac *)sc->sc_curmac;
2727                 bwn_set_slot_time(mac,
2728                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2729         }
2730         BWN_UNLOCK(sc);
2731 }
2732
2733 /*
2734  * Callback from the 802.11 layer after a promiscuous mode change.
2735  * Note this interface does not check the operating mode as this
2736  * is an internal callback and we are expected to honor the current
2737  * state (e.g. this is used for setting the interface in promiscuous
2738  * mode when operating in hostap mode to do ACS).
2739  */
2740 static void
2741 bwn_update_promisc(struct ieee80211com *ic)
2742 {
2743         struct bwn_softc *sc = ic->ic_softc;
2744         struct bwn_mac *mac = sc->sc_curmac;
2745
2746         BWN_LOCK(sc);
2747         mac = sc->sc_curmac;
2748         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2749                 if (ic->ic_promisc > 0)
2750                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2751                 else
2752                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2753                 bwn_set_opmode(mac);
2754         }
2755         BWN_UNLOCK(sc);
2756 }
2757
2758 /*
2759  * Callback from the 802.11 layer to update WME parameters.
2760  */
2761 static int
2762 bwn_wme_update(struct ieee80211com *ic)
2763 {
2764         struct bwn_softc *sc = ic->ic_softc;
2765         struct bwn_mac *mac = sc->sc_curmac;
2766         struct wmeParams *wmep;
2767         int i;
2768
2769         BWN_LOCK(sc);
2770         mac = sc->sc_curmac;
2771         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2772                 bwn_mac_suspend(mac);
2773                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2774                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2775                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2776                 }
2777                 bwn_mac_enable(mac);
2778         }
2779         BWN_UNLOCK(sc);
2780         return (0);
2781 }
2782
2783 static void
2784 bwn_scan_start(struct ieee80211com *ic)
2785 {
2786         struct bwn_softc *sc = ic->ic_softc;
2787         struct bwn_mac *mac;
2788
2789         BWN_LOCK(sc);
2790         mac = sc->sc_curmac;
2791         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2792                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2793                 bwn_set_opmode(mac);
2794                 /* disable CFP update during scan */
2795                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2796         }
2797         BWN_UNLOCK(sc);
2798 }
2799
2800 static void
2801 bwn_scan_end(struct ieee80211com *ic)
2802 {
2803         struct bwn_softc *sc = ic->ic_softc;
2804         struct bwn_mac *mac;
2805
2806         BWN_LOCK(sc);
2807         mac = sc->sc_curmac;
2808         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2809                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2810                 bwn_set_opmode(mac);
2811                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2812         }
2813         BWN_UNLOCK(sc);
2814 }
2815
2816 static void
2817 bwn_set_channel(struct ieee80211com *ic)
2818 {
2819         struct bwn_softc *sc = ic->ic_softc;
2820         struct bwn_mac *mac = sc->sc_curmac;
2821         struct bwn_phy *phy = &mac->mac_phy;
2822         int chan, error;
2823
2824         BWN_LOCK(sc);
2825
2826         error = bwn_switch_band(sc, ic->ic_curchan);
2827         if (error)
2828                 goto fail;
2829         bwn_mac_suspend(mac);
2830         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2831         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2832         if (chan != phy->chan)
2833                 bwn_switch_channel(mac, chan);
2834
2835         /* TX power level */
2836         if (ic->ic_curchan->ic_maxpower != 0 &&
2837             ic->ic_curchan->ic_maxpower != phy->txpower) {
2838                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2839                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2840                     BWN_TXPWR_IGNORE_TSSI);
2841         }
2842
2843         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2844         if (phy->set_antenna)
2845                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2846
2847         if (sc->sc_rf_enabled != phy->rf_on) {
2848                 if (sc->sc_rf_enabled) {
2849                         bwn_rf_turnon(mac);
2850                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2851                                 device_printf(sc->sc_dev,
2852                                     "please turn on the RF switch\n");
2853                 } else
2854                         bwn_rf_turnoff(mac);
2855         }
2856
2857         bwn_mac_enable(mac);
2858
2859 fail:
2860         /*
2861          * Setup radio tap channel freq and flags
2862          */
2863         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2864                 htole16(ic->ic_curchan->ic_freq);
2865         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2866                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2867
2868         BWN_UNLOCK(sc);
2869 }
2870
2871 static struct ieee80211vap *
2872 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2873     enum ieee80211_opmode opmode, int flags,
2874     const uint8_t bssid[IEEE80211_ADDR_LEN],
2875     const uint8_t mac[IEEE80211_ADDR_LEN])
2876 {
2877         struct ieee80211vap *vap;
2878         struct bwn_vap *bvp;
2879
2880         switch (opmode) {
2881         case IEEE80211_M_HOSTAP:
2882         case IEEE80211_M_MBSS:
2883         case IEEE80211_M_STA:
2884         case IEEE80211_M_WDS:
2885         case IEEE80211_M_MONITOR:
2886         case IEEE80211_M_IBSS:
2887         case IEEE80211_M_AHDEMO:
2888                 break;
2889         default:
2890                 return (NULL);
2891         }
2892
2893         bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
2894         vap = &bvp->bv_vap;
2895         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
2896         /* override with driver methods */
2897         bvp->bv_newstate = vap->iv_newstate;
2898         vap->iv_newstate = bwn_newstate;
2899
2900         /* override max aid so sta's cannot assoc when we're out of sta id's */
2901         vap->iv_max_aid = BWN_STAID_MAX;
2902
2903         ieee80211_ratectl_init(vap);
2904
2905         /* complete setup */
2906         ieee80211_vap_attach(vap, ieee80211_media_change,
2907             ieee80211_media_status, mac);
2908         return (vap);
2909 }
2910
2911 static void
2912 bwn_vap_delete(struct ieee80211vap *vap)
2913 {
2914         struct bwn_vap *bvp = BWN_VAP(vap);
2915
2916         ieee80211_ratectl_deinit(vap);
2917         ieee80211_vap_detach(vap);
2918         free(bvp, M_80211_VAP);
2919 }
2920
2921 static int
2922 bwn_init(struct bwn_softc *sc)
2923 {
2924         struct bwn_mac *mac;
2925         int error;
2926
2927         BWN_ASSERT_LOCKED(sc);
2928
2929         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2930         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2931         sc->sc_filters = 0;
2932         bwn_wme_clear(sc);
2933         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2934         sc->sc_rf_enabled = 1;
2935
2936         mac = sc->sc_curmac;
2937         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2938                 error = bwn_core_init(mac);
2939                 if (error != 0)
2940                         return (error);
2941         }
2942         if (mac->mac_status == BWN_MAC_STATUS_INITED)
2943                 bwn_core_start(mac);
2944
2945         bwn_set_opmode(mac);
2946         bwn_set_pretbtt(mac);
2947         bwn_spu_setdelay(mac, 0);
2948         bwn_set_macaddr(mac);
2949
2950         sc->sc_flags |= BWN_FLAG_RUNNING;
2951         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2952         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2953
2954         return (0);
2955 }
2956
2957 static void
2958 bwn_stop(struct bwn_softc *sc)
2959 {
2960         struct bwn_mac *mac = sc->sc_curmac;
2961
2962         BWN_ASSERT_LOCKED(sc);
2963
2964         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2965                 /* XXX FIXME opmode not based on VAP */
2966                 bwn_set_opmode(mac);
2967                 bwn_set_macaddr(mac);
2968         }
2969
2970         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2971                 bwn_core_stop(mac);
2972
2973         callout_stop(&sc->sc_led_blink_ch);
2974         sc->sc_led_blinking = 0;
2975
2976         bwn_core_exit(mac);
2977         sc->sc_rf_enabled = 0;
2978
2979         sc->sc_flags &= ~BWN_FLAG_RUNNING;
2980 }
2981
2982 static void
2983 bwn_wme_clear(struct bwn_softc *sc)
2984 {
2985 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
2986         struct wmeParams *p;
2987         unsigned int i;
2988
2989         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2990             ("%s:%d: fail", __func__, __LINE__));
2991
2992         for (i = 0; i < N(sc->sc_wmeParams); i++) {
2993                 p = &(sc->sc_wmeParams[i]);
2994
2995                 switch (bwn_wme_shm_offsets[i]) {
2996                 case BWN_WME_VOICE:
2997                         p->wmep_txopLimit = 0;
2998                         p->wmep_aifsn = 2;
2999                         /* XXX FIXME: log2(cwmin) */
3000                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3001                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3002                         break;
3003                 case BWN_WME_VIDEO:
3004                         p->wmep_txopLimit = 0;
3005                         p->wmep_aifsn = 2;
3006                         /* XXX FIXME: log2(cwmin) */
3007                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3008                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3009                         break;
3010                 case BWN_WME_BESTEFFORT:
3011                         p->wmep_txopLimit = 0;
3012                         p->wmep_aifsn = 3;
3013                         /* XXX FIXME: log2(cwmin) */
3014                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3015                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3016                         break;
3017                 case BWN_WME_BACKGROUND:
3018                         p->wmep_txopLimit = 0;
3019                         p->wmep_aifsn = 7;
3020                         /* XXX FIXME: log2(cwmin) */
3021                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3022                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3023                         break;
3024                 default:
3025                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3026                 }
3027         }
3028 }
3029
3030 static int
3031 bwn_core_init(struct bwn_mac *mac)
3032 {
3033         struct bwn_softc *sc = mac->mac_sc;
3034         uint64_t hf;
3035         int error;
3036
3037         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3038             ("%s:%d: fail", __func__, __LINE__));
3039
3040         siba_powerup(sc->sc_dev, 0);
3041         if (!siba_dev_isup(sc->sc_dev))
3042                 bwn_reset_core(mac,
3043                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3044
3045         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3046         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3047         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3048         BWN_GETTIME(mac->mac_phy.nexttime);
3049         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3050         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3051         mac->mac_stats.link_noise = -95;
3052         mac->mac_reason_intr = 0;
3053         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3054         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3055 #ifdef BWN_DEBUG
3056         if (sc->sc_debug & BWN_DEBUG_XMIT)
3057                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3058 #endif
3059         mac->mac_suspended = 1;
3060         mac->mac_task_state = 0;
3061         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3062
3063         mac->mac_phy.init_pre(mac);
3064
3065         siba_pcicore_intr(sc->sc_dev);
3066
3067         siba_fix_imcfglobug(sc->sc_dev);
3068         bwn_bt_disable(mac);
3069         if (mac->mac_phy.prepare_hw) {
3070                 error = mac->mac_phy.prepare_hw(mac);
3071                 if (error)
3072                         goto fail0;
3073         }
3074         error = bwn_chip_init(mac);
3075         if (error)
3076                 goto fail0;
3077         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3078             siba_get_revid(sc->sc_dev));
3079         hf = bwn_hf_read(mac);
3080         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3081                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3082                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3083                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3084                 if (mac->mac_phy.rev == 1)
3085                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3086         }
3087         if (mac->mac_phy.rf_ver == 0x2050) {
3088                 if (mac->mac_phy.rf_rev < 6)
3089                         hf |= BWN_HF_FORCE_VCO_RECALC;
3090                 if (mac->mac_phy.rf_rev == 6)
3091                         hf |= BWN_HF_4318_TSSI;
3092         }
3093         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3094                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3095         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3096             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3097                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3098         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3099         bwn_hf_write(mac, hf);
3100
3101         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3102         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3103         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3104         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3105
3106         bwn_rate_init(mac);
3107         bwn_set_phytxctl(mac);
3108
3109         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3110             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3111         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3112
3113         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3114                 bwn_pio_init(mac);
3115         else
3116                 bwn_dma_init(mac);
3117         bwn_wme_init(mac);
3118         bwn_spu_setdelay(mac, 1);
3119         bwn_bt_enable(mac);
3120
3121         siba_powerup(sc->sc_dev,
3122             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3123         bwn_set_macaddr(mac);
3124         bwn_crypt_init(mac);
3125
3126         /* XXX LED initializatin */
3127
3128         mac->mac_status = BWN_MAC_STATUS_INITED;
3129
3130         return (error);
3131
3132 fail0:
3133         siba_powerdown(sc->sc_dev);
3134         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3135             ("%s:%d: fail", __func__, __LINE__));
3136         return (error);
3137 }
3138
3139 static void
3140 bwn_core_start(struct bwn_mac *mac)
3141 {
3142         struct bwn_softc *sc = mac->mac_sc;
3143         uint32_t tmp;
3144
3145         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3146             ("%s:%d: fail", __func__, __LINE__));
3147
3148         if (siba_get_revid(sc->sc_dev) < 5)
3149                 return;
3150
3151         while (1) {
3152                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3153                 if (!(tmp & 0x00000001))
3154                         break;
3155                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3156         }
3157
3158         bwn_mac_enable(mac);
3159         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3160         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3161
3162         mac->mac_status = BWN_MAC_STATUS_STARTED;
3163 }
3164
3165 static void
3166 bwn_core_exit(struct bwn_mac *mac)
3167 {
3168         struct bwn_softc *sc = mac->mac_sc;
3169         uint32_t macctl;
3170
3171         BWN_ASSERT_LOCKED(mac->mac_sc);
3172
3173         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3174             ("%s:%d: fail", __func__, __LINE__));
3175
3176         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3177                 return;
3178         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3179
3180         macctl = BWN_READ_4(mac, BWN_MACCTL);
3181         macctl &= ~BWN_MACCTL_MCODE_RUN;
3182         macctl |= BWN_MACCTL_MCODE_JMP0;
3183         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3184
3185         bwn_dma_stop(mac);
3186         bwn_pio_stop(mac);
3187         bwn_chip_exit(mac);
3188         mac->mac_phy.switch_analog(mac, 0);
3189         siba_dev_down(sc->sc_dev, 0);
3190         siba_powerdown(sc->sc_dev);
3191 }
3192
3193 static void
3194 bwn_bt_disable(struct bwn_mac *mac)
3195 {
3196         struct bwn_softc *sc = mac->mac_sc;
3197
3198         (void)sc;
3199         /* XXX do nothing yet */
3200 }
3201
3202 static int
3203 bwn_chip_init(struct bwn_mac *mac)
3204 {
3205         struct bwn_softc *sc = mac->mac_sc;
3206         struct bwn_phy *phy = &mac->mac_phy;
3207         uint32_t macctl;
3208         int error;
3209
3210         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3211         if (phy->gmode)
3212                 macctl |= BWN_MACCTL_GMODE;
3213         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3214
3215         error = bwn_fw_fillinfo(mac);
3216         if (error)
3217                 return (error);
3218         error = bwn_fw_loaducode(mac);
3219         if (error)
3220                 return (error);
3221
3222         error = bwn_gpio_init(mac);
3223         if (error)
3224                 return (error);
3225
3226         error = bwn_fw_loadinitvals(mac);
3227         if (error) {
3228                 siba_gpio_set(sc->sc_dev, 0);
3229                 return (error);
3230         }
3231         phy->switch_analog(mac, 1);
3232         error = bwn_phy_init(mac);
3233         if (error) {
3234                 siba_gpio_set(sc->sc_dev, 0);
3235                 return (error);
3236         }
3237         if (phy->set_im)
3238                 phy->set_im(mac, BWN_IMMODE_NONE);
3239         if (phy->set_antenna)
3240                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3241         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3242
3243         if (phy->type == BWN_PHYTYPE_B)
3244                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3245         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3246         if (siba_get_revid(sc->sc_dev) < 5)
3247                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3248
3249         BWN_WRITE_4(mac, BWN_MACCTL,
3250             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3251         BWN_WRITE_4(mac, BWN_MACCTL,
3252             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3253         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3254
3255         bwn_set_opmode(mac);
3256         if (siba_get_revid(sc->sc_dev) < 3) {
3257                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3258                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3259                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3260                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3261         } else {
3262                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3263                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3264         }
3265         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3266         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3267         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3268         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3269         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3270         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3271         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3272         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3273             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3274         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3275         return (error);
3276 }
3277
3278 /* read hostflags */
3279 static uint64_t
3280 bwn_hf_read(struct bwn_mac *mac)
3281 {
3282         uint64_t ret;
3283
3284         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3285         ret <<= 16;
3286         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3287         ret <<= 16;
3288         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3289         return (ret);
3290 }
3291
3292 static void
3293 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3294 {
3295
3296         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3297             (value & 0x00000000ffffull));
3298         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3299             (value & 0x0000ffff0000ull) >> 16);
3300         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3301             (value & 0xffff00000000ULL) >> 32);
3302 }
3303
3304 static void
3305 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3306 {
3307
3308         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3309         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3310 }
3311
3312 static void
3313 bwn_rate_init(struct bwn_mac *mac)
3314 {
3315
3316         switch (mac->mac_phy.type) {
3317         case BWN_PHYTYPE_A:
3318         case BWN_PHYTYPE_G:
3319         case BWN_PHYTYPE_LP:
3320         case BWN_PHYTYPE_N:
3321                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3322                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3323                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3324                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3325                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3326                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3327                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3328                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3329                         break;
3330                 /* FALLTHROUGH */
3331         case BWN_PHYTYPE_B:
3332                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3333                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3334                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3335                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3336                 break;
3337         default:
3338                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3339         }
3340 }
3341
3342 static void
3343 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3344 {
3345         uint16_t offset;
3346
3347         if (ofdm) {
3348                 offset = 0x480;
3349                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3350         } else {
3351                 offset = 0x4c0;
3352                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3353         }
3354         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3355             bwn_shm_read_2(mac, BWN_SHARED, offset));
3356 }
3357
3358 static uint8_t
3359 bwn_plcp_getcck(const uint8_t bitrate)
3360 {
3361
3362         switch (bitrate) {
3363         case BWN_CCK_RATE_1MB:
3364                 return (0x0a);
3365         case BWN_CCK_RATE_2MB:
3366                 return (0x14);
3367         case BWN_CCK_RATE_5MB:
3368                 return (0x37);
3369         case BWN_CCK_RATE_11MB:
3370                 return (0x6e);
3371         }
3372         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3373         return (0);
3374 }
3375
3376 static uint8_t
3377 bwn_plcp_getofdm(const uint8_t bitrate)
3378 {
3379
3380         switch (bitrate) {
3381         case BWN_OFDM_RATE_6MB:
3382                 return (0xb);
3383         case BWN_OFDM_RATE_9MB:
3384                 return (0xf);
3385         case BWN_OFDM_RATE_12MB:
3386                 return (0xa);
3387         case BWN_OFDM_RATE_18MB:
3388                 return (0xe);
3389         case BWN_OFDM_RATE_24MB:
3390                 return (0x9);
3391         case BWN_OFDM_RATE_36MB:
3392                 return (0xd);
3393         case BWN_OFDM_RATE_48MB:
3394                 return (0x8);
3395         case BWN_OFDM_RATE_54MB:
3396                 return (0xc);
3397         }
3398         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3399         return (0);
3400 }
3401
3402 static void
3403 bwn_set_phytxctl(struct bwn_mac *mac)
3404 {
3405         uint16_t ctl;
3406
3407         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3408             BWN_TX_PHY_TXPWR);
3409         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3410         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3411         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3412 }
3413
3414 static void
3415 bwn_pio_init(struct bwn_mac *mac)
3416 {
3417         struct bwn_pio *pio = &mac->mac_method.pio;
3418
3419         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3420             & ~BWN_MACCTL_BIGENDIAN);
3421         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3422
3423         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3424         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3425         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3426         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3427         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3428         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3429 }
3430
3431 static void
3432 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3433     int index)
3434 {
3435         struct bwn_pio_txpkt *tp;
3436         struct bwn_softc *sc = mac->mac_sc;
3437         unsigned int i;
3438
3439         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3440         tq->tq_index = index;
3441
3442         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3443         if (siba_get_revid(sc->sc_dev) >= 8)
3444                 tq->tq_size = 1920;
3445         else {
3446                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3447                 tq->tq_size -= 80;
3448         }
3449
3450         TAILQ_INIT(&tq->tq_pktlist);
3451         for (i = 0; i < N(tq->tq_pkts); i++) {
3452                 tp = &(tq->tq_pkts[i]);
3453                 tp->tp_index = i;
3454                 tp->tp_queue = tq;
3455                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3456         }
3457 }
3458
3459 static uint16_t
3460 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3461 {
3462         struct bwn_softc *sc = mac->mac_sc;
3463         static const uint16_t bases[] = {
3464                 BWN_PIO_BASE0,
3465                 BWN_PIO_BASE1,
3466                 BWN_PIO_BASE2,
3467                 BWN_PIO_BASE3,
3468                 BWN_PIO_BASE4,
3469                 BWN_PIO_BASE5,
3470                 BWN_PIO_BASE6,
3471                 BWN_PIO_BASE7,
3472         };
3473         static const uint16_t bases_rev11[] = {
3474                 BWN_PIO11_BASE0,
3475                 BWN_PIO11_BASE1,
3476                 BWN_PIO11_BASE2,
3477                 BWN_PIO11_BASE3,
3478                 BWN_PIO11_BASE4,
3479                 BWN_PIO11_BASE5,
3480         };
3481
3482         if (siba_get_revid(sc->sc_dev) >= 11) {
3483                 if (index >= N(bases_rev11))
3484                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3485                 return (bases_rev11[index]);
3486         }
3487         if (index >= N(bases))
3488                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3489         return (bases[index]);
3490 }
3491
3492 static void
3493 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3494     int index)
3495 {
3496         struct bwn_softc *sc = mac->mac_sc;
3497
3498         prq->prq_mac = mac;
3499         prq->prq_rev = siba_get_revid(sc->sc_dev);
3500         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3501         bwn_dma_rxdirectfifo(mac, index, 1);
3502 }
3503
3504 static void
3505 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3506 {
3507         if (tq == NULL)
3508                 return;
3509         bwn_pio_cancel_tx_packets(tq);
3510 }
3511
3512 static void
3513 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3514 {
3515
3516         bwn_destroy_pioqueue_tx(pio);
3517 }
3518
3519 static uint16_t
3520 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3521     uint16_t offset)
3522 {
3523
3524         return (BWN_READ_2(mac, tq->tq_base + offset));
3525 }
3526
3527 static void
3528 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3529 {
3530         uint32_t ctl;
3531         int type;
3532         uint16_t base;
3533
3534         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3535         base = bwn_dma_base(type, idx);
3536         if (type == BWN_DMA_64BIT) {
3537                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3538                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3539                 if (enable)
3540                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3541                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3542         } else {
3543                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3544                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3545                 if (enable)
3546                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3547                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3548         }
3549 }
3550
3551 static uint64_t
3552 bwn_dma_mask(struct bwn_mac *mac)
3553 {
3554         uint32_t tmp;
3555         uint16_t base;
3556
3557         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3558         if (tmp & SIBA_TGSHIGH_DMA64)
3559                 return (BWN_DMA_BIT_MASK(64));
3560         base = bwn_dma_base(0, 0);
3561         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3562         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3563         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3564                 return (BWN_DMA_BIT_MASK(32));
3565
3566         return (BWN_DMA_BIT_MASK(30));
3567 }
3568
3569 static int
3570 bwn_dma_mask2type(uint64_t dmamask)
3571 {
3572
3573         if (dmamask == BWN_DMA_BIT_MASK(30))
3574                 return (BWN_DMA_30BIT);
3575         if (dmamask == BWN_DMA_BIT_MASK(32))
3576                 return (BWN_DMA_32BIT);
3577         if (dmamask == BWN_DMA_BIT_MASK(64))
3578                 return (BWN_DMA_64BIT);
3579         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3580         return (BWN_DMA_30BIT);
3581 }
3582
3583 static void
3584 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3585 {
3586         struct bwn_pio_txpkt *tp;
3587         unsigned int i;
3588
3589         for (i = 0; i < N(tq->tq_pkts); i++) {
3590                 tp = &(tq->tq_pkts[i]);
3591                 if (tp->tp_m) {
3592                         m_freem(tp->tp_m);
3593                         tp->tp_m = NULL;
3594                 }
3595         }
3596 }
3597
3598 static uint16_t
3599 bwn_dma_base(int type, int controller_idx)
3600 {
3601         static const uint16_t map64[] = {
3602                 BWN_DMA64_BASE0,
3603                 BWN_DMA64_BASE1,
3604                 BWN_DMA64_BASE2,
3605                 BWN_DMA64_BASE3,
3606                 BWN_DMA64_BASE4,
3607                 BWN_DMA64_BASE5,
3608         };
3609         static const uint16_t map32[] = {
3610                 BWN_DMA32_BASE0,
3611                 BWN_DMA32_BASE1,
3612                 BWN_DMA32_BASE2,
3613                 BWN_DMA32_BASE3,
3614                 BWN_DMA32_BASE4,
3615                 BWN_DMA32_BASE5,
3616         };
3617
3618         if (type == BWN_DMA_64BIT) {
3619                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3620                     ("%s:%d: fail", __func__, __LINE__));
3621                 return (map64[controller_idx]);
3622         }
3623         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3624             ("%s:%d: fail", __func__, __LINE__));
3625         return (map32[controller_idx]);
3626 }
3627
3628 static void
3629 bwn_dma_init(struct bwn_mac *mac)
3630 {
3631         struct bwn_dma *dma = &mac->mac_method.dma;
3632
3633         /* setup TX DMA channels. */
3634         bwn_dma_setup(dma->wme[WME_AC_BK]);
3635         bwn_dma_setup(dma->wme[WME_AC_BE]);
3636         bwn_dma_setup(dma->wme[WME_AC_VI]);
3637         bwn_dma_setup(dma->wme[WME_AC_VO]);
3638         bwn_dma_setup(dma->mcast);
3639         /* setup RX DMA channel. */
3640         bwn_dma_setup(dma->rx);
3641 }
3642
3643 static struct bwn_dma_ring *
3644 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3645     int for_tx, int type)
3646 {
3647         struct bwn_dma *dma = &mac->mac_method.dma;
3648         struct bwn_dma_ring *dr;
3649         struct bwn_dmadesc_generic *desc;
3650         struct bwn_dmadesc_meta *mt;
3651         struct bwn_softc *sc = mac->mac_sc;
3652         int error, i;
3653
3654         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3655         if (dr == NULL)
3656                 goto out;
3657         dr->dr_numslots = BWN_RXRING_SLOTS;
3658         if (for_tx)
3659                 dr->dr_numslots = BWN_TXRING_SLOTS;
3660
3661         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3662             M_DEVBUF, M_NOWAIT | M_ZERO);
3663         if (dr->dr_meta == NULL)
3664                 goto fail0;
3665
3666         dr->dr_type = type;
3667         dr->dr_mac = mac;
3668         dr->dr_base = bwn_dma_base(type, controller_index);
3669         dr->dr_index = controller_index;
3670         if (type == BWN_DMA_64BIT) {
3671                 dr->getdesc = bwn_dma_64_getdesc;
3672                 dr->setdesc = bwn_dma_64_setdesc;
3673                 dr->start_transfer = bwn_dma_64_start_transfer;
3674                 dr->suspend = bwn_dma_64_suspend;
3675                 dr->resume = bwn_dma_64_resume;
3676                 dr->get_curslot = bwn_dma_64_get_curslot;
3677                 dr->set_curslot = bwn_dma_64_set_curslot;
3678         } else {
3679                 dr->getdesc = bwn_dma_32_getdesc;
3680                 dr->setdesc = bwn_dma_32_setdesc;
3681                 dr->start_transfer = bwn_dma_32_start_transfer;
3682                 dr->suspend = bwn_dma_32_suspend;
3683                 dr->resume = bwn_dma_32_resume;
3684                 dr->get_curslot = bwn_dma_32_get_curslot;
3685                 dr->set_curslot = bwn_dma_32_set_curslot;
3686         }
3687         if (for_tx) {
3688                 dr->dr_tx = 1;
3689                 dr->dr_curslot = -1;
3690         } else {
3691                 if (dr->dr_index == 0) {
3692                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3693                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3694                 } else
3695                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3696         }
3697
3698         error = bwn_dma_allocringmemory(dr);
3699         if (error)
3700                 goto fail2;
3701
3702         if (for_tx) {
3703                 /*
3704                  * Assumption: BWN_TXRING_SLOTS can be divided by
3705                  * BWN_TX_SLOTS_PER_FRAME
3706                  */
3707                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3708                     ("%s:%d: fail", __func__, __LINE__));
3709
3710                 dr->dr_txhdr_cache =
3711                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3712                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3713                 KASSERT(dr->dr_txhdr_cache != NULL,
3714                     ("%s:%d: fail", __func__, __LINE__));
3715
3716                 /*
3717                  * Create TX ring DMA stuffs
3718                  */
3719                 error = bus_dma_tag_create(dma->parent_dtag,
3720                                     BWN_ALIGN, 0,
3721                                     BUS_SPACE_MAXADDR,
3722                                     BUS_SPACE_MAXADDR,
3723                                     NULL, NULL,
3724                                     BWN_HDRSIZE(mac),
3725                                     1,
3726                                     BUS_SPACE_MAXSIZE_32BIT,
3727                                     0,
3728                                     NULL, NULL,
3729                                     &dr->dr_txring_dtag);
3730                 if (error) {
3731                         device_printf(sc->sc_dev,
3732                             "can't create TX ring DMA tag: TODO frees\n");
3733                         goto fail1;
3734                 }
3735
3736                 for (i = 0; i < dr->dr_numslots; i += 2) {
3737                         dr->getdesc(dr, i, &desc, &mt);
3738
3739                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3740                         mt->mt_m = NULL;
3741                         mt->mt_ni = NULL;
3742                         mt->mt_islast = 0;
3743                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3744                             &mt->mt_dmap);
3745                         if (error) {
3746                                 device_printf(sc->sc_dev,
3747                                      "can't create RX buf DMA map\n");
3748                                 goto fail1;
3749                         }
3750
3751                         dr->getdesc(dr, i + 1, &desc, &mt);
3752
3753                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3754                         mt->mt_m = NULL;
3755                         mt->mt_ni = NULL;
3756                         mt->mt_islast = 1;
3757                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3758                             &mt->mt_dmap);
3759                         if (error) {
3760                                 device_printf(sc->sc_dev,
3761                                      "can't create RX buf DMA map\n");
3762                                 goto fail1;
3763                         }
3764                 }
3765         } else {
3766                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3767                     &dr->dr_spare_dmap);
3768                 if (error) {
3769                         device_printf(sc->sc_dev,
3770                             "can't create RX buf DMA map\n");
3771                         goto out;               /* XXX wrong! */
3772                 }
3773
3774                 for (i = 0; i < dr->dr_numslots; i++) {
3775                         dr->getdesc(dr, i, &desc, &mt);
3776
3777                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3778                             &mt->mt_dmap);
3779                         if (error) {
3780                                 device_printf(sc->sc_dev,
3781                                     "can't create RX buf DMA map\n");
3782                                 goto out;       /* XXX wrong! */
3783                         }
3784                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3785                         if (error) {
3786                                 device_printf(sc->sc_dev,
3787                                     "failed to allocate RX buf\n");
3788                                 goto out;       /* XXX wrong! */
3789                         }
3790                 }
3791
3792                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3793                     BUS_DMASYNC_PREWRITE);
3794
3795                 dr->dr_usedslot = dr->dr_numslots;
3796         }
3797
3798       out:
3799         return (dr);
3800
3801 fail2:
3802         free(dr->dr_txhdr_cache, M_DEVBUF);
3803 fail1:
3804         free(dr->dr_meta, M_DEVBUF);
3805 fail0:
3806         free(dr, M_DEVBUF);
3807         return (NULL);
3808 }
3809
3810 static void
3811 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3812 {
3813
3814         if (dr == NULL)
3815                 return;
3816
3817         bwn_dma_free_descbufs(*dr);
3818         bwn_dma_free_ringmemory(*dr);
3819
3820         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3821         free((*dr)->dr_meta, M_DEVBUF);
3822         free(*dr, M_DEVBUF);
3823
3824         *dr = NULL;
3825 }
3826
3827 static void
3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3829     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3830 {
3831         struct bwn_dmadesc32 *desc;
3832
3833         *meta = &(dr->dr_meta[slot]);
3834         desc = dr->dr_ring_descbase;
3835         desc = &(desc[slot]);
3836
3837         *gdesc = (struct bwn_dmadesc_generic *)desc;
3838 }
3839
3840 static void
3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3842     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3843     int start, int end, int irq)
3844 {
3845         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3846         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3847         uint32_t addr, addrext, ctl;
3848         int slot;
3849
3850         slot = (int)(&(desc->dma.dma32) - descbase);
3851         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3852             ("%s:%d: fail", __func__, __LINE__));
3853
3854         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3855         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3856         addr |= siba_dma_translation(sc->sc_dev);
3857         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3858         if (slot == dr->dr_numslots - 1)
3859                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3860         if (start)
3861                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3862         if (end)
3863                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3864         if (irq)
3865                 ctl |= BWN_DMA32_DCTL_IRQ;
3866         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3867             & BWN_DMA32_DCTL_ADDREXT_MASK;
3868
3869         desc->dma.dma32.control = htole32(ctl);
3870         desc->dma.dma32.address = htole32(addr);
3871 }
3872
3873 static void
3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3875 {
3876
3877         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3878             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3879 }
3880
3881 static void
3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3883 {
3884
3885         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3886             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3887 }
3888
3889 static void
3890 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3891 {
3892
3893         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3894             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3895 }
3896
3897 static int
3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3899 {
3900         uint32_t val;
3901
3902         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3903         val &= BWN_DMA32_RXDPTR;
3904
3905         return (val / sizeof(struct bwn_dmadesc32));
3906 }
3907
3908 static void
3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3910 {
3911
3912         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3913             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3914 }
3915
3916 static void
3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3918     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3919 {
3920         struct bwn_dmadesc64 *desc;
3921
3922         *meta = &(dr->dr_meta[slot]);
3923         desc = dr->dr_ring_descbase;
3924         desc = &(desc[slot]);
3925
3926         *gdesc = (struct bwn_dmadesc_generic *)desc;
3927 }
3928
3929 static void
3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3931     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3932     int start, int end, int irq)
3933 {
3934         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3935         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3936         int slot;
3937         uint32_t ctl0 = 0, ctl1 = 0;
3938         uint32_t addrlo, addrhi;
3939         uint32_t addrext;
3940
3941         slot = (int)(&(desc->dma.dma64) - descbase);
3942         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3943             ("%s:%d: fail", __func__, __LINE__));
3944
3945         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3946         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3947         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3948             30;
3949         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3950         if (slot == dr->dr_numslots - 1)
3951                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3952         if (start)
3953                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3954         if (end)
3955                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3956         if (irq)
3957                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3958         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3959         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3960             & BWN_DMA64_DCTL1_ADDREXT_MASK;
3961
3962         desc->dma.dma64.control0 = htole32(ctl0);
3963         desc->dma.dma64.control1 = htole32(ctl1);
3964         desc->dma.dma64.address_low = htole32(addrlo);
3965         desc->dma.dma64.address_high = htole32(addrhi);
3966 }
3967
3968 static void
3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3970 {
3971
3972         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3973             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3974 }
3975
3976 static void
3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3978 {
3979
3980         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3981             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3982 }
3983
3984 static void
3985 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3986 {
3987
3988         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3989             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3990 }
3991
3992 static int
3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3994 {
3995         uint32_t val;
3996
3997         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3998         val &= BWN_DMA64_RXSTATDPTR;
3999
4000         return (val / sizeof(struct bwn_dmadesc64));
4001 }
4002
4003 static void
4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4005 {
4006
4007         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4008             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4009 }
4010
4011 static int
4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4013 {
4014         struct bwn_mac *mac = dr->dr_mac;
4015         struct bwn_dma *dma = &mac->mac_method.dma;
4016         struct bwn_softc *sc = mac->mac_sc;
4017         int error;
4018
4019         error = bus_dma_tag_create(dma->parent_dtag,
4020                             BWN_ALIGN, 0,
4021                             BUS_SPACE_MAXADDR,
4022                             BUS_SPACE_MAXADDR,
4023                             NULL, NULL,
4024                             BWN_DMA_RINGMEMSIZE,
4025                             1,
4026                             BUS_SPACE_MAXSIZE_32BIT,
4027                             0,
4028                             NULL, NULL,
4029                             &dr->dr_ring_dtag);
4030         if (error) {
4031                 device_printf(sc->sc_dev,
4032                     "can't create TX ring DMA tag: TODO frees\n");
4033                 return (-1);
4034         }
4035
4036         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4037             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4038             &dr->dr_ring_dmap);
4039         if (error) {
4040                 device_printf(sc->sc_dev,
4041                     "can't allocate DMA mem: TODO frees\n");
4042                 return (-1);
4043         }
4044         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4045             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4046             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4047         if (error) {
4048                 device_printf(sc->sc_dev,
4049                     "can't load DMA mem: TODO free\n");
4050                 return (-1);
4051         }
4052
4053         return (0);
4054 }
4055
4056 static void
4057 bwn_dma_setup(struct bwn_dma_ring *dr)
4058 {
4059         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4060         uint64_t ring64;
4061         uint32_t addrext, ring32, value;
4062         uint32_t trans = siba_dma_translation(sc->sc_dev);
4063
4064         if (dr->dr_tx) {
4065                 dr->dr_curslot = -1;
4066
4067                 if (dr->dr_type == BWN_DMA_64BIT) {
4068                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4069                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4070                             >> 30;
4071                         value = BWN_DMA64_TXENABLE;
4072                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4073                             & BWN_DMA64_TXADDREXT_MASK;
4074                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4075                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4076                             (ring64 & 0xffffffff));
4077                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4078                             ((ring64 >> 32) &
4079                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4080                 } else {
4081                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4082                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4083                         value = BWN_DMA32_TXENABLE;
4084                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4085                             & BWN_DMA32_TXADDREXT_MASK;
4086                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4087                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4088                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4089                 }
4090                 return;
4091         }
4092
4093         /*
4094          * set for RX
4095          */
4096         dr->dr_usedslot = dr->dr_numslots;
4097
4098         if (dr->dr_type == BWN_DMA_64BIT) {
4099                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4100                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4101                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4102                 value |= BWN_DMA64_RXENABLE;
4103                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4104                     & BWN_DMA64_RXADDREXT_MASK;
4105                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4106                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4107                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4108                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4109                     | (trans << 1));
4110                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4111                     sizeof(struct bwn_dmadesc64));
4112         } else {
4113                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4114                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4115                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4116                 value |= BWN_DMA32_RXENABLE;
4117                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4118                     & BWN_DMA32_RXADDREXT_MASK;
4119                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4120                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4121                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4122                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4123                     sizeof(struct bwn_dmadesc32));
4124         }
4125 }
4126
4127 static void
4128 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4129 {
4130
4131         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4132         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4133             dr->dr_ring_dmap);
4134 }
4135
4136 static void
4137 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4138 {
4139
4140         if (dr->dr_tx) {
4141                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4142                 if (dr->dr_type == BWN_DMA_64BIT) {
4143                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4144                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4145                 } else
4146                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4147         } else {
4148                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4149                 if (dr->dr_type == BWN_DMA_64BIT) {
4150                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4151                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4152                 } else
4153                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4154         }
4155 }
4156
4157 static void
4158 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4159 {
4160         struct bwn_dmadesc_generic *desc;
4161         struct bwn_dmadesc_meta *meta;
4162         struct bwn_mac *mac = dr->dr_mac;
4163         struct bwn_dma *dma = &mac->mac_method.dma;
4164         struct bwn_softc *sc = mac->mac_sc;
4165         int i;
4166
4167         if (!dr->dr_usedslot)
4168                 return;
4169         for (i = 0; i < dr->dr_numslots; i++) {
4170                 dr->getdesc(dr, i, &desc, &meta);
4171
4172                 if (meta->mt_m == NULL) {
4173                         if (!dr->dr_tx)
4174                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4175                                     __func__);
4176                         continue;
4177                 }
4178                 if (dr->dr_tx) {
4179                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4180                                 bus_dmamap_unload(dr->dr_txring_dtag,
4181                                     meta->mt_dmap);
4182                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4183                                 bus_dmamap_unload(dma->txbuf_dtag,
4184                                     meta->mt_dmap);
4185                 } else
4186                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4187                 bwn_dma_free_descbuf(dr, meta);
4188         }
4189 }
4190
4191 static int
4192 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4193     int type)
4194 {
4195         struct bwn_softc *sc = mac->mac_sc;
4196         uint32_t value;
4197         int i;
4198         uint16_t offset;
4199
4200         for (i = 0; i < 10; i++) {
4201                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4202                     BWN_DMA32_TXSTATUS;
4203                 value = BWN_READ_4(mac, base + offset);
4204                 if (type == BWN_DMA_64BIT) {
4205                         value &= BWN_DMA64_TXSTAT;
4206                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4207                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4208                             value == BWN_DMA64_TXSTAT_STOPPED)
4209                                 break;
4210                 } else {
4211                         value &= BWN_DMA32_TXSTATE;
4212                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4213                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4214                             value == BWN_DMA32_TXSTAT_STOPPED)
4215                                 break;
4216                 }
4217                 DELAY(1000);
4218         }
4219         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4220         BWN_WRITE_4(mac, base + offset, 0);
4221         for (i = 0; i < 10; i++) {
4222                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4223                                                    BWN_DMA32_TXSTATUS;
4224                 value = BWN_READ_4(mac, base + offset);
4225                 if (type == BWN_DMA_64BIT) {
4226                         value &= BWN_DMA64_TXSTAT;
4227                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4228                                 i = -1;
4229                                 break;
4230                         }
4231                 } else {
4232                         value &= BWN_DMA32_TXSTATE;
4233                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4234                                 i = -1;
4235                                 break;
4236                         }
4237                 }
4238                 DELAY(1000);
4239         }
4240         if (i != -1) {
4241                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4242                 return (ENODEV);
4243         }
4244         DELAY(1000);
4245
4246         return (0);
4247 }
4248
4249 static int
4250 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4251     int type)
4252 {
4253         struct bwn_softc *sc = mac->mac_sc;
4254         uint32_t value;
4255         int i;
4256         uint16_t offset;
4257
4258         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4259         BWN_WRITE_4(mac, base + offset, 0);
4260         for (i = 0; i < 10; i++) {
4261                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4262                     BWN_DMA32_RXSTATUS;
4263                 value = BWN_READ_4(mac, base + offset);
4264                 if (type == BWN_DMA_64BIT) {
4265                         value &= BWN_DMA64_RXSTAT;
4266                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4267                                 i = -1;
4268                                 break;
4269                         }
4270                 } else {
4271                         value &= BWN_DMA32_RXSTATE;
4272                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4273                                 i = -1;
4274                                 break;
4275                         }
4276                 }
4277                 DELAY(1000);
4278         }
4279         if (i != -1) {
4280                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4281                 return (ENODEV);
4282         }
4283
4284         return (0);
4285 }
4286
4287 static void
4288 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4289     struct bwn_dmadesc_meta *meta)
4290 {
4291
4292         if (meta->mt_m != NULL) {
4293                 m_freem(meta->mt_m);
4294                 meta->mt_m = NULL;
4295         }
4296         if (meta->mt_ni != NULL) {
4297                 ieee80211_free_node(meta->mt_ni);
4298                 meta->mt_ni = NULL;
4299         }
4300 }
4301
4302 static void
4303 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4304 {
4305         struct bwn_rxhdr4 *rxhdr;
4306         unsigned char *frame;
4307
4308         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4309         rxhdr->frame_len = 0;
4310
4311         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4312             sizeof(struct bwn_plcp6) + 2,
4313             ("%s:%d: fail", __func__, __LINE__));
4314         frame = mtod(m, char *) + dr->dr_frameoffset;
4315         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4316 }
4317
4318 static uint8_t
4319 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4320 {
4321         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4322
4323         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4324             == 0xff);
4325 }
4326
4327 static void
4328 bwn_wme_init(struct bwn_mac *mac)
4329 {
4330
4331         bwn_wme_load(mac);
4332
4333         /* enable WME support. */
4334         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4335         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4336             BWN_IFSCTL_USE_EDCF);
4337 }
4338
4339 static void
4340 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4341 {
4342         struct bwn_softc *sc = mac->mac_sc;
4343         struct ieee80211com *ic = &sc->sc_ic;
4344         uint16_t delay; /* microsec */
4345
4346         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4347         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4348                 delay = 500;
4349         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4350                 delay = max(delay, (uint16_t)2400);
4351
4352         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4353 }
4354
4355 static void
4356 bwn_bt_enable(struct bwn_mac *mac)
4357 {
4358         struct bwn_softc *sc = mac->mac_sc;
4359         uint64_t hf;
4360
4361         if (bwn_bluetooth == 0)
4362                 return;
4363         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4364                 return;
4365         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4366                 return;
4367
4368         hf = bwn_hf_read(mac);
4369         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4370                 hf |= BWN_HF_BT_COEXISTALT;
4371         else
4372                 hf |= BWN_HF_BT_COEXIST;
4373         bwn_hf_write(mac, hf);
4374 }
4375
4376 static void
4377 bwn_set_macaddr(struct bwn_mac *mac)
4378 {
4379
4380         bwn_mac_write_bssid(mac);
4381         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
4382             mac->mac_sc->sc_ic.ic_macaddr);
4383 }
4384
4385 static void
4386 bwn_clear_keys(struct bwn_mac *mac)
4387 {
4388         int i;
4389
4390         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4391                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4392                     ("%s:%d: fail", __func__, __LINE__));
4393
4394                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4395                     NULL, BWN_SEC_KEYSIZE, NULL);
4396                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4397                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4398                             NULL, BWN_SEC_KEYSIZE, NULL);
4399                 }
4400                 mac->mac_key[i].keyconf = NULL;
4401         }
4402 }
4403
4404 static void
4405 bwn_crypt_init(struct bwn_mac *mac)
4406 {
4407         struct bwn_softc *sc = mac->mac_sc;
4408
4409         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4410         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4411             ("%s:%d: fail", __func__, __LINE__));
4412         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4413         mac->mac_ktp *= 2;
4414         if (siba_get_revid(sc->sc_dev) >= 5)
4415                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4416         bwn_clear_keys(mac);
4417 }
4418
4419 static void
4420 bwn_chip_exit(struct bwn_mac *mac)
4421 {
4422         struct bwn_softc *sc = mac->mac_sc;
4423
4424         bwn_phy_exit(mac);
4425         siba_gpio_set(sc->sc_dev, 0);
4426 }
4427
4428 static int
4429 bwn_fw_fillinfo(struct bwn_mac *mac)
4430 {
4431         int error;
4432
4433         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4434         if (error == 0)
4435                 return (0);
4436         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4437         if (error == 0)
4438                 return (0);
4439         return (error);
4440 }
4441
4442 static int
4443 bwn_gpio_init(struct bwn_mac *mac)
4444 {
4445         struct bwn_softc *sc = mac->mac_sc;
4446         uint32_t mask = 0x1f, set = 0xf, value;
4447
4448         BWN_WRITE_4(mac, BWN_MACCTL,
4449             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4450         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4451             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4452
4453         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4454                 mask |= 0x0060;
4455                 set |= 0x0060;
4456         }
4457         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4458                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4459                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4460                 mask |= 0x0200;
4461                 set |= 0x0200;
4462         }
4463         if (siba_get_revid(sc->sc_dev) >= 2)
4464                 mask |= 0x0010;
4465
4466         value = siba_gpio_get(sc->sc_dev);
4467         if (value == -1)
4468                 return (0);
4469         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4470
4471         return (0);
4472 }
4473
4474 static int
4475 bwn_fw_loadinitvals(struct bwn_mac *mac)
4476 {
4477 #define GETFWOFFSET(fwp, offset)                                \
4478         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4479         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4480         const struct bwn_fwhdr *hdr;
4481         struct bwn_fw *fw = &mac->mac_fw;
4482         int error;
4483
4484         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4485         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4486             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4487         if (error)
4488                 return (error);
4489         if (fw->initvals_band.fw) {
4490                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4491                 error = bwn_fwinitvals_write(mac,
4492                     GETFWOFFSET(fw->initvals_band, hdr_len),
4493                     be32toh(hdr->size),
4494                     fw->initvals_band.fw->datasize - hdr_len);
4495         }
4496         return (error);
4497 #undef GETFWOFFSET
4498 }
4499
4500 static int
4501 bwn_phy_init(struct bwn_mac *mac)
4502 {
4503         struct bwn_softc *sc = mac->mac_sc;
4504         int error;
4505
4506         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4507         mac->mac_phy.rf_onoff(mac, 1);
4508         error = mac->mac_phy.init(mac);
4509         if (error) {
4510                 device_printf(sc->sc_dev, "PHY init failed\n");
4511                 goto fail0;
4512         }
4513         error = bwn_switch_channel(mac,
4514             mac->mac_phy.get_default_chan(mac));
4515         if (error) {
4516                 device_printf(sc->sc_dev,
4517                     "failed to switch default channel\n");
4518                 goto fail1;
4519         }
4520         return (0);
4521 fail1:
4522         if (mac->mac_phy.exit)
4523                 mac->mac_phy.exit(mac);
4524 fail0:
4525         mac->mac_phy.rf_onoff(mac, 0);
4526
4527         return (error);
4528 }
4529
4530 static void
4531 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4532 {
4533         uint16_t ant;
4534         uint16_t tmp;
4535
4536         ant = bwn_ant2phy(antenna);
4537
4538         /* For ACK/CTS */
4539         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4540         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4541         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4542         /* For Probe Resposes */
4543         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4544         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4545         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4546 }
4547
4548 static void
4549 bwn_set_opmode(struct bwn_mac *mac)
4550 {
4551         struct bwn_softc *sc = mac->mac_sc;
4552         struct ieee80211com *ic = &sc->sc_ic;
4553         uint32_t ctl;
4554         uint16_t cfp_pretbtt;
4555
4556         ctl = BWN_READ_4(mac, BWN_MACCTL);
4557         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4558             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4559             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4560         ctl |= BWN_MACCTL_STA;
4561
4562         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4563             ic->ic_opmode == IEEE80211_M_MBSS)
4564                 ctl |= BWN_MACCTL_HOSTAP;
4565         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4566                 ctl &= ~BWN_MACCTL_STA;
4567         ctl |= sc->sc_filters;
4568
4569         if (siba_get_revid(sc->sc_dev) <= 4)
4570                 ctl |= BWN_MACCTL_PROMISC;
4571
4572         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4573
4574         cfp_pretbtt = 2;
4575         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4576                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4577                     siba_get_chiprev(sc->sc_dev) == 3)
4578                         cfp_pretbtt = 100;
4579                 else
4580                         cfp_pretbtt = 50;
4581         }
4582         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4583 }
4584
4585 static int
4586 bwn_dma_gettype(struct bwn_mac *mac)
4587 {
4588         uint32_t tmp;
4589         uint16_t base;
4590
4591         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4592         if (tmp & SIBA_TGSHIGH_DMA64)
4593                 return (BWN_DMA_64BIT);
4594         base = bwn_dma_base(0, 0);
4595         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4596         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4597         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4598                 return (BWN_DMA_32BIT);
4599
4600         return (BWN_DMA_30BIT);
4601 }
4602
4603 static void
4604 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4605 {
4606         if (!error) {
4607                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4608                 *((bus_addr_t *)arg) = seg->ds_addr;
4609         }
4610 }
4611
4612 static void
4613 bwn_phy_g_init_sub(struct bwn_mac *mac)
4614 {
4615         struct bwn_phy *phy = &mac->mac_phy;
4616         struct bwn_phy_g *pg = &phy->phy_g;
4617         struct bwn_softc *sc = mac->mac_sc;
4618         uint16_t i, tmp;
4619
4620         if (phy->rev == 1)
4621                 bwn_phy_init_b5(mac);
4622         else
4623                 bwn_phy_init_b6(mac);
4624
4625         if (phy->rev >= 2 || phy->gmode)
4626                 bwn_phy_init_a(mac);
4627
4628         if (phy->rev >= 2) {
4629                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4630                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4631         }
4632         if (phy->rev == 2) {
4633                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4634                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4635         }
4636         if (phy->rev > 5) {
4637                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4638                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4639         }
4640         if (phy->gmode || phy->rev >= 2) {
4641                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4642                 tmp &= BWN_PHYVER_VERSION;
4643                 if (tmp == 3 || tmp == 5) {
4644                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4645                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4646                 }
4647                 if (tmp == 5) {
4648                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4649                             0x1f00);
4650                 }
4651         }
4652         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4653                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4654         if (phy->rf_rev == 8) {
4655                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4656                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4657         }
4658         if (BWN_HAS_LOOPBACK(phy))
4659                 bwn_loopback_calcgain(mac);
4660
4661         if (phy->rf_rev != 8) {
4662                 if (pg->pg_initval == 0xffff)
4663                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4664                 else
4665                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4666         }
4667         bwn_lo_g_init(mac);
4668         if (BWN_HAS_TXMAG(phy)) {
4669                 BWN_RF_WRITE(mac, 0x52,
4670                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4671                     | pg->pg_loctl.tx_bias |
4672                     pg->pg_loctl.tx_magn);
4673         } else {
4674                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4675         }
4676         if (phy->rev >= 6) {
4677                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4678                     (pg->pg_loctl.tx_bias << 12));
4679         }
4680         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4681                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4682         else
4683                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4684         if (phy->rev < 2)
4685                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4686         else
4687                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4688         if (phy->gmode || phy->rev >= 2) {
4689                 bwn_lo_g_adjust(mac);
4690                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4691         }
4692
4693         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4694                 for (i = 0; i < 64; i++) {
4695                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4696                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4697                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4698                             -32), 31));
4699                 }
4700                 bwn_nrssi_threshold(mac);
4701         } else if (phy->gmode || phy->rev >= 2) {
4702                 if (pg->pg_nrssi[0] == -1000) {
4703                         KASSERT(pg->pg_nrssi[1] == -1000,
4704                             ("%s:%d: fail", __func__, __LINE__));
4705                         bwn_nrssi_slope_11g(mac);
4706                 } else
4707                         bwn_nrssi_threshold(mac);
4708         }
4709         if (phy->rf_rev == 8)
4710                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4711         bwn_phy_hwpctl_init(mac);
4712         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4713              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4714                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4715                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4716         }
4717 }
4718
4719 static uint8_t
4720 bwn_has_hwpctl(struct bwn_mac *mac)
4721 {
4722
4723         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4724                 return (0);
4725         return (mac->mac_phy.use_hwpctl(mac));
4726 }
4727
4728 static void
4729 bwn_phy_init_b5(struct bwn_mac *mac)
4730 {
4731         struct bwn_phy *phy = &mac->mac_phy;
4732         struct bwn_phy_g *pg = &phy->phy_g;
4733         struct bwn_softc *sc = mac->mac_sc;
4734         uint16_t offset, value;
4735         uint8_t old_channel;
4736
4737         if (phy->analog == 1)
4738                 BWN_RF_SET(mac, 0x007a, 0x0050);
4739         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4740             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4741                 value = 0x2120;
4742                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4743                         BWN_PHY_WRITE(mac, offset, value);
4744                         value += 0x202;
4745                 }
4746         }
4747         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4748         if (phy->rf_ver == 0x2050)
4749                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4750
4751         if (phy->gmode || phy->rev >= 2) {
4752                 if (phy->rf_ver == 0x2050) {
4753                         BWN_RF_SET(mac, 0x007a, 0x0020);
4754                         BWN_RF_SET(mac, 0x0051, 0x0004);
4755                 }
4756                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4757
4758                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4759                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4760
4761                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4762
4763                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4764                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4765                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4766         }
4767
4768         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4769                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4770
4771         if (phy->analog == 1) {
4772                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4773                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4774                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4775                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4776                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4777         } else
4778                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4779         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4780         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4781
4782         if (phy->analog == 1)
4783                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4784         else
4785                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4786
4787         if (phy->analog == 0)
4788                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4789
4790         old_channel = phy->chan;
4791         bwn_phy_g_switch_chan(mac, 7, 0);
4792
4793         if (phy->rf_ver != 0x2050) {
4794                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4795                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4796         }
4797
4798         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4799         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4800
4801         if (phy->rf_ver == 0x2050) {
4802                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4803                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4804         }
4805
4806         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4807         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4808         BWN_RF_SET(mac, 0x007a, 0x0007);
4809
4810         bwn_phy_g_switch_chan(mac, old_channel, 0);
4811         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4812         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4813         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4814
4815         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4816             pg->pg_txctl);
4817
4818         if (phy->rf_ver == 0x2050)
4819                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4820
4821         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4822 }
4823
4824 static void
4825 bwn_loopback_calcgain(struct bwn_mac *mac)
4826 {
4827         struct bwn_phy *phy = &mac->mac_phy;
4828         struct bwn_phy_g *pg = &phy->phy_g;
4829         struct bwn_softc *sc = mac->mac_sc;
4830         uint16_t backup_phy[16] = { 0 };
4831         uint16_t backup_radio[3];
4832         uint16_t backup_bband;
4833         uint16_t i, j, loop_i_max;
4834         uint16_t trsw_rx;
4835         uint16_t loop1_outer_done, loop1_inner_done;
4836
4837         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4838         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4839         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4840         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4841         if (phy->rev != 1) {
4842                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4843                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4844         }
4845         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4846         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4847         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4848         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4849         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4850         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4851         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4852         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4853         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4854         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4855         backup_bband = pg->pg_bbatt.att;
4856         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4857         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4858         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4859
4860         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4861         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4862         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4863         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4864         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4865         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4866         if (phy->rev != 1) {
4867                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4868                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4869                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4870                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4871         }
4872         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4873         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4874         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4875         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4876
4877         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4878         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4879         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4880
4881         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4882         if (phy->rev != 1) {
4883                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4884                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4885         }
4886         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4887
4888         if (phy->rf_rev == 8)
4889                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4890         else {
4891                 BWN_RF_WRITE(mac, 0x52, 0);
4892                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4893         }
4894         bwn_phy_g_set_bbatt(mac, 11);
4895
4896         if (phy->rev >= 3)
4897                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4898         else
4899                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4900         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4901
4902         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4903         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4904
4905         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4906         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4907
4908         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4909                 if (phy->rev >= 7) {
4910                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4911                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4912                 }
4913         }
4914         BWN_RF_MASK(mac, 0x7a, 0x00f7);
4915
4916         j = 0;
4917         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4918         for (i = 0; i < loop_i_max; i++) {
4919                 for (j = 0; j < 16; j++) {
4920                         BWN_RF_WRITE(mac, 0x43, i);
4921                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4922                             (j << 8));
4923                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4924                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4925                         DELAY(20);
4926                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4927                                 goto done0;
4928                 }
4929         }
4930 done0:
4931         loop1_outer_done = i;
4932         loop1_inner_done = j;
4933         if (j >= 8) {
4934                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4935                 trsw_rx = 0x1b;
4936                 for (j = j - 8; j < 16; j++) {
4937                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4938                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4939                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4940                         DELAY(20);
4941                         trsw_rx -= 3;
4942                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4943                                 goto done1;
4944                 }
4945         } else
4946                 trsw_rx = 0x18;
4947 done1:
4948
4949         if (phy->rev != 1) {
4950                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4951                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4952         }
4953         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4954         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4955         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4956         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4957         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4958         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4959         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4960         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4961         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4962
4963         bwn_phy_g_set_bbatt(mac, backup_bband);
4964
4965         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4966         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4967         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4968
4969         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4970         DELAY(10);
4971         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4972         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4973         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4974         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4975
4976         pg->pg_max_lb_gain =
4977             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4978         pg->pg_trsw_rx_gain = trsw_rx * 2;
4979 }
4980
4981 static uint16_t
4982 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4983 {
4984         struct bwn_phy *phy = &mac->mac_phy;
4985         uint32_t tmp1 = 0, tmp2 = 0;
4986         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4987             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4988             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4989         static const uint8_t rcc_table[] = {
4990                 0x02, 0x03, 0x01, 0x0f,
4991                 0x06, 0x07, 0x05, 0x0f,
4992                 0x0a, 0x0b, 0x09, 0x0f,
4993                 0x0e, 0x0f, 0x0d, 0x0f,
4994         };
4995
4996         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
4997             rfoverval = rfover = cck3 = 0;
4998         radio0 = BWN_RF_READ(mac, 0x43);
4999         radio1 = BWN_RF_READ(mac, 0x51);
5000         radio2 = BWN_RF_READ(mac, 0x52);
5001         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5002         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5003         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5004         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5005
5006         if (phy->type == BWN_PHYTYPE_B) {
5007                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5008                 reg0 = BWN_READ_2(mac, 0x3ec);
5009
5010                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5011                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5012         } else if (phy->gmode || phy->rev >= 2) {
5013                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5014                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5015                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5016                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5017                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5018                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5019
5020                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5021                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5022                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5023                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5024                 if (BWN_HAS_LOOPBACK(phy)) {
5025                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5026                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5027                         if (phy->rev >= 3)
5028                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5029                         else
5030                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5031                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5032                 }
5033
5034                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5035                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5036                         BWN_LPD(0, 1, 1)));
5037                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5038                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5039         }
5040         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5041
5042         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5043         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5044         reg1 = BWN_READ_2(mac, 0x3e6);
5045         reg2 = BWN_READ_2(mac, 0x3f4);
5046
5047         if (phy->analog == 0)
5048                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5049         else {
5050                 if (phy->analog >= 2)
5051                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5052                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5053                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5054         }
5055
5056         reg = BWN_RF_READ(mac, 0x60);
5057         index = (reg & 0x001e) >> 1;
5058         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5059
5060         if (phy->type == BWN_PHYTYPE_B)
5061                 BWN_RF_WRITE(mac, 0x78, 0x26);
5062         if (phy->gmode || phy->rev >= 2) {
5063                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5064                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5065                         BWN_LPD(0, 1, 1)));
5066         }
5067         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5068         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5069         if (phy->gmode || phy->rev >= 2) {
5070                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5071                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5072                         BWN_LPD(0, 0, 1)));
5073         }
5074         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5075         BWN_RF_SET(mac, 0x51, 0x0004);
5076         if (phy->rf_rev == 8)
5077                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5078         else {
5079                 BWN_RF_WRITE(mac, 0x52, 0);
5080                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5081         }
5082         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5083
5084         for (i = 0; i < 16; i++) {
5085                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5086                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5087                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5088                 if (phy->gmode || phy->rev >= 2) {
5089                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5090                             bwn_rf_2050_rfoverval(mac,
5091                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5092                 }
5093                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5094                 DELAY(10);
5095                 if (phy->gmode || phy->rev >= 2) {
5096                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5097                             bwn_rf_2050_rfoverval(mac,
5098                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5099                 }
5100                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5101                 DELAY(10);
5102                 if (phy->gmode || phy->rev >= 2) {
5103                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5104                             bwn_rf_2050_rfoverval(mac,
5105                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5106                 }
5107                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5108                 DELAY(20);
5109                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5110                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5111                 if (phy->gmode || phy->rev >= 2) {
5112                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5113                             bwn_rf_2050_rfoverval(mac,
5114                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5115                 }
5116                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5117         }
5118         DELAY(10);
5119
5120         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5121         tmp1++;
5122         tmp1 >>= 9;
5123
5124         for (i = 0; i < 16; i++) {
5125                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5126                 BWN_RF_WRITE(mac, 0x78, radio78);
5127                 DELAY(10);
5128                 for (j = 0; j < 16; j++) {
5129                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5130                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5131                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5132                         if (phy->gmode || phy->rev >= 2) {
5133                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5134                                     bwn_rf_2050_rfoverval(mac,
5135                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5136                         }
5137                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5138                         DELAY(10);
5139                         if (phy->gmode || phy->rev >= 2) {
5140                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5141                                     bwn_rf_2050_rfoverval(mac,
5142                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5143                         }
5144                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5145                         DELAY(10);
5146                         if (phy->gmode || phy->rev >= 2) {
5147                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5148                                     bwn_rf_2050_rfoverval(mac,
5149                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5150                         }
5151                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5152                         DELAY(10);
5153                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5154                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5155                         if (phy->gmode || phy->rev >= 2) {
5156                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5157                                     bwn_rf_2050_rfoverval(mac,
5158                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5159                         }
5160                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5161                 }
5162                 tmp2++;
5163                 tmp2 >>= 8;
5164                 if (tmp1 < tmp2)
5165                         break;
5166         }
5167
5168         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5169         BWN_RF_WRITE(mac, 0x51, radio1);
5170         BWN_RF_WRITE(mac, 0x52, radio2);
5171         BWN_RF_WRITE(mac, 0x43, radio0);
5172         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5173         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5174         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5175         BWN_WRITE_2(mac, 0x3e6, reg1);
5176         if (phy->analog != 0)
5177                 BWN_WRITE_2(mac, 0x3f4, reg2);
5178         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5179         bwn_spu_workaround(mac, phy->chan);
5180         if (phy->type == BWN_PHYTYPE_B) {
5181                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5182                 BWN_WRITE_2(mac, 0x3ec, reg0);
5183         } else if (phy->gmode) {
5184                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5185                             BWN_READ_2(mac, BWN_PHY_RADIO)
5186                             & 0x7fff);
5187                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5188                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5189                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5190                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5191                               analogoverval);
5192                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5193                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5194                 if (BWN_HAS_LOOPBACK(phy)) {
5195                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5196                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5197                 }
5198         }
5199
5200         return ((i > 15) ? radio78 : rcc);
5201 }
5202
5203 static void
5204 bwn_phy_init_b6(struct bwn_mac *mac)
5205 {
5206         struct bwn_phy *phy = &mac->mac_phy;
5207         struct bwn_phy_g *pg = &phy->phy_g;
5208         struct bwn_softc *sc = mac->mac_sc;
5209         uint16_t offset, val;
5210         uint8_t old_channel;
5211
5212         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5213             ("%s:%d: fail", __func__, __LINE__));
5214
5215         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5216         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5217         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5218                 BWN_RF_WRITE(mac, 0x51, 0x37);
5219                 BWN_RF_WRITE(mac, 0x52, 0x70);
5220                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5221                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5222                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5223                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5224                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5225                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5226                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5227                 bwn_hf_write(mac,
5228                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5229         }
5230         if (phy->rf_rev == 8) {
5231                 BWN_RF_WRITE(mac, 0x51, 0);
5232                 BWN_RF_WRITE(mac, 0x52, 0x40);
5233                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5234                 BWN_RF_WRITE(mac, 0x54, 0x98);
5235                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5236                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5237                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5238                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5239                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5240                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5241                 } else {
5242                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5243                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5244                 }
5245                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5246                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5247                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5248                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5249         }
5250         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5251                 BWN_PHY_WRITE(mac, offset, val);
5252                 val -= 0x0202;
5253         }
5254         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5255                 BWN_PHY_WRITE(mac, offset, val);
5256                 val -= 0x0202;
5257         }
5258         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5259                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5260                 val += 0x0202;
5261         }
5262         if (phy->type == BWN_PHYTYPE_G) {
5263                 BWN_RF_SET(mac, 0x007a, 0x0020);
5264                 BWN_RF_SET(mac, 0x0051, 0x0004);
5265                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5266                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5267                 BWN_PHY_WRITE(mac, 0x5b, 0);
5268                 BWN_PHY_WRITE(mac, 0x5c, 0);
5269         }
5270
5271         old_channel = phy->chan;
5272         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5273
5274         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5275         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5276         DELAY(40);
5277         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5278                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5279                 BWN_RF_WRITE(mac, 0x50, 0x20);
5280         }
5281         if (phy->rf_rev <= 2) {
5282                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5283                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5284                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5285                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5286         }
5287         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5288
5289         bwn_phy_g_switch_chan(mac, old_channel, 0);
5290
5291         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5292         if (phy->rf_rev >= 6)
5293                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5294         else
5295                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5296         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5297         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5298             pg->pg_txctl);
5299         if (phy->rf_rev <= 5)
5300                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5301         if (phy->rf_rev <= 2)
5302                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5303
5304         if (phy->analog == 4) {
5305                 BWN_WRITE_2(mac, 0x3e4, 9);
5306                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5307         } else
5308                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5309         if (phy->type == BWN_PHYTYPE_B)
5310                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5311         else if (phy->type == BWN_PHYTYPE_G)
5312                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5313 }
5314
5315 static void
5316 bwn_phy_init_a(struct bwn_mac *mac)
5317 {
5318         struct bwn_phy *phy = &mac->mac_phy;
5319         struct bwn_softc *sc = mac->mac_sc;
5320
5321         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5322             ("%s:%d: fail", __func__, __LINE__));
5323
5324         if (phy->rev >= 6) {
5325                 if (phy->type == BWN_PHYTYPE_A)
5326                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5327                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5328                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5329                 else
5330                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5331         }
5332
5333         bwn_wa_init(mac);
5334
5335         if (phy->type == BWN_PHYTYPE_G &&
5336             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5337                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5338 }
5339
5340 static void
5341 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5342 {
5343         int i;
5344
5345         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5346                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5347 }
5348
5349 static void
5350 bwn_wa_agc(struct bwn_mac *mac)
5351 {
5352         struct bwn_phy *phy = &mac->mac_phy;
5353
5354         if (phy->rev == 1) {
5355                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5356                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5357                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5358                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5359                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5360                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5361                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5362                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5363                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5364         } else {
5365                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5366                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5367                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5368                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5369         }
5370
5371         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5372             0x5700);
5373         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5374         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5375         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5376         BWN_RF_SET(mac, 0x7a, 0x0008);
5377         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5378         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5379         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5380         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5381         if (phy->rev == 1)
5382                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5383         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5384         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5385         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5386         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5387         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5388         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5389         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5390         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5391         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5392         if (phy->rev == 1) {
5393                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5394                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5395         } else {
5396                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5397                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5398                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5399                 if (phy->rev >= 6) {
5400                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5401                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5402                             (uint16_t)~0xf000, 0x3000);
5403                 }
5404         }
5405         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5406         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5407         if (phy->rev == 1) {
5408                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5409                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5410                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5411                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5412                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5413                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5414                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5415                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5416         } else {
5417                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5418                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5419                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5420                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5421         }
5422         if (phy->rev >= 6) {
5423                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5424                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5425         }
5426         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5427 }
5428
5429 static void
5430 bwn_wa_grev1(struct bwn_mac *mac)
5431 {
5432         struct bwn_phy *phy = &mac->mac_phy;
5433         int i;
5434         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5435         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5436         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5437
5438         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5439
5440         /* init CRSTHRES and ANTDWELL */
5441         if (phy->rev == 1) {
5442                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5443         } else if (phy->rev == 2) {
5444                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5445                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5446                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5447         } else {
5448                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5449                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5450                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5451                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5452         }
5453         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5454         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5455         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5456
5457         /* XXX support PHY-A??? */
5458         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5459                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5460                     bwn_tab_finefreqg[i]);
5461
5462         /* XXX support PHY-A??? */
5463         if (phy->rev == 1)
5464                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5465                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5466                             bwn_tab_noise_g1[i]);
5467         else
5468                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5469                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5470                             bwn_tab_noise_g2[i]);
5471
5472
5473         for (i = 0; i < N(bwn_tab_rotor); i++)
5474                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5475                     bwn_tab_rotor[i]);
5476
5477         /* XXX support PHY-A??? */
5478         if (phy->rev >= 6) {
5479                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5480                     BWN_PHY_ENCORE_EN)
5481                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5482                 else
5483                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5484         } else
5485                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5486
5487         for (i = 0; i < N(bwn_tab_retard); i++)
5488                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5489                     bwn_tab_retard[i]);
5490
5491         if (phy->rev == 1) {
5492                 for (i = 0; i < 16; i++)
5493                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5494                             i, 0x0020);
5495         } else {
5496                 for (i = 0; i < 32; i++)
5497                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5498         }
5499
5500         bwn_wa_agc(mac);
5501 }
5502
5503 static void
5504 bwn_wa_grev26789(struct bwn_mac *mac)
5505 {
5506         struct bwn_phy *phy = &mac->mac_phy;
5507         int i;
5508         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5509         uint16_t ofdmrev;
5510
5511         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5512
5513         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5514
5515         /* init CRSTHRES and ANTDWELL */
5516         if (phy->rev == 1)
5517                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5518         else if (phy->rev == 2) {
5519                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5520                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5521                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5522         } else {
5523                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5524                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5525                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5526                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5527         }
5528
5529         for (i = 0; i < 64; i++)
5530                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5531
5532         /* XXX support PHY-A??? */
5533         if (phy->rev == 1)
5534                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5535                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5536                             bwn_tab_noise_g1[i]);
5537         else
5538                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5539                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5540                             bwn_tab_noise_g2[i]);
5541
5542         /* XXX support PHY-A??? */
5543         if (phy->rev >= 6) {
5544                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5545                     BWN_PHY_ENCORE_EN)
5546                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5547                 else
5548                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5549         } else
5550                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5551
5552         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5553                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5554                     bwn_tab_sigmasqr2[i]);
5555
5556         if (phy->rev == 1) {
5557                 for (i = 0; i < 16; i++)
5558                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5559                             0x0020);
5560         } else {
5561                 for (i = 0; i < 32; i++)
5562                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5563         }
5564
5565         bwn_wa_agc(mac);
5566
5567         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5568         if (ofdmrev > 2) {
5569                 if (phy->type == BWN_PHYTYPE_A)
5570                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5571                 else
5572                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5573         } else {
5574                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5575                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5576                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5577         }
5578
5579         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5580         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5581 }
5582
5583 static void
5584 bwn_wa_init(struct bwn_mac *mac)
5585 {
5586         struct bwn_phy *phy = &mac->mac_phy;
5587         struct bwn_softc *sc = mac->mac_sc;
5588
5589         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5590
5591         switch (phy->rev) {
5592         case 1:
5593                 bwn_wa_grev1(mac);
5594                 break;
5595         case 2:
5596         case 6:
5597         case 7:
5598         case 8:
5599         case 9:
5600                 bwn_wa_grev26789(mac);
5601                 break;
5602         default:
5603                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5604         }
5605
5606         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5607             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5608             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5609                 if (phy->rev < 2) {
5610                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5611                             0x0002);
5612                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5613                             0x0001);
5614                 } else {
5615                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5616                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5617                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5618                              BWN_BFL_EXTLNA) &&
5619                             (phy->rev >= 7)) {
5620                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5621                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5622                                     0x0020, 0x0001);
5623                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5624                                     0x0021, 0x0001);
5625                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5626                                     0x0022, 0x0001);
5627                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5628                                     0x0023, 0x0000);
5629                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5630                                     0x0000, 0x0000);
5631                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5632                                     0x0003, 0x0002);
5633                         }
5634                 }
5635         }
5636         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5637                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5638                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5639         }
5640
5641         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5642         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5643 }
5644
5645 static void
5646 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5647     uint16_t value)
5648 {
5649         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5650         uint16_t addr;
5651
5652         addr = table + offset;
5653         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5654             (addr - 1 != pg->pg_ofdmtab_addr)) {
5655                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5656                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5657         }
5658         pg->pg_ofdmtab_addr = addr;
5659         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5660 }
5661
5662 static void
5663 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5664     uint32_t value)
5665 {
5666         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5667         uint16_t addr;
5668
5669         addr = table + offset;
5670         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5671             (addr - 1 != pg->pg_ofdmtab_addr)) {
5672                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5673                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5674         }
5675         pg->pg_ofdmtab_addr = addr;
5676
5677         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5678         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5679 }
5680
5681 static void
5682 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5683     uint16_t value)
5684 {
5685
5686         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5687         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5688 }
5689
5690 static void
5691 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5692 {
5693         struct bwn_phy *phy = &mac->mac_phy;
5694         struct bwn_softc *sc = mac->mac_sc;
5695         unsigned int i, max_loop;
5696         uint16_t value;
5697         uint32_t buffer[5] = {
5698                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5699         };
5700
5701         if (ofdm) {
5702                 max_loop = 0x1e;
5703                 buffer[0] = 0x000201cc;
5704         } else {
5705                 max_loop = 0xfa;
5706                 buffer[0] = 0x000b846e;
5707         }
5708
5709         BWN_ASSERT_LOCKED(mac->mac_sc);
5710
5711         for (i = 0; i < 5; i++)
5712                 bwn_ram_write(mac, i * 4, buffer[i]);
5713
5714         BWN_WRITE_2(mac, 0x0568, 0x0000);
5715         BWN_WRITE_2(mac, 0x07c0,
5716             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5717         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5718         BWN_WRITE_2(mac, 0x050c, value);
5719         if (phy->type == BWN_PHYTYPE_LP)
5720                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5721         BWN_WRITE_2(mac, 0x0508, 0x0000);
5722         BWN_WRITE_2(mac, 0x050a, 0x0000);
5723         BWN_WRITE_2(mac, 0x054c, 0x0000);
5724         BWN_WRITE_2(mac, 0x056a, 0x0014);
5725         BWN_WRITE_2(mac, 0x0568, 0x0826);
5726         BWN_WRITE_2(mac, 0x0500, 0x0000);
5727         if (phy->type == BWN_PHYTYPE_LP)
5728                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5729         else
5730                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5731
5732         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5733                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5734         for (i = 0x00; i < max_loop; i++) {
5735                 value = BWN_READ_2(mac, 0x050e);
5736                 if (value & 0x0080)
5737                         break;
5738                 DELAY(10);
5739         }
5740         for (i = 0x00; i < 0x0a; i++) {
5741                 value = BWN_READ_2(mac, 0x050e);
5742                 if (value & 0x0400)
5743                         break;
5744                 DELAY(10);
5745         }
5746         for (i = 0x00; i < 0x19; i++) {
5747                 value = BWN_READ_2(mac, 0x0690);
5748                 if (!(value & 0x0100))
5749                         break;
5750                 DELAY(10);
5751         }
5752         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5753                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5754 }
5755
5756 static void
5757 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5758 {
5759         uint32_t macctl;
5760
5761         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5762
5763         macctl = BWN_READ_4(mac, BWN_MACCTL);
5764         if (macctl & BWN_MACCTL_BIGENDIAN)
5765                 printf("TODO: need swap\n");
5766
5767         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5768         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5769         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5770 }
5771
5772 static void
5773 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5774 {
5775         uint16_t value;
5776
5777         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5778             ("%s:%d: fail", __func__, __LINE__));
5779
5780         value = (uint8_t) (ctl->q);
5781         value |= ((uint8_t) (ctl->i)) << 8;
5782         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5783 }
5784
5785 static uint16_t
5786 bwn_lo_calcfeed(struct bwn_mac *mac,
5787     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5788 {
5789         struct bwn_phy *phy = &mac->mac_phy;
5790         struct bwn_softc *sc = mac->mac_sc;
5791         uint16_t rfover;
5792         uint16_t feedthrough;
5793
5794         if (phy->gmode) {
5795                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5796                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5797
5798                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5799                     ("%s:%d: fail", __func__, __LINE__));
5800                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5801                     ("%s:%d: fail", __func__, __LINE__));
5802
5803                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5804
5805                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5806                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5807                     phy->rev > 6)
5808                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5809
5810                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5811                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5812                 DELAY(10);
5813                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5814                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5815                 DELAY(10);
5816                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5817                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5818                 DELAY(10);
5819                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5820         } else {
5821                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5822                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5823                 DELAY(10);
5824                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5825                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5826                 DELAY(10);
5827                 pga |= BWN_PHY_PGACTL_LPF;
5828                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5829         }
5830         DELAY(21);
5831         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5832
5833         return (feedthrough);
5834 }
5835
5836 static uint16_t
5837 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5838     uint16_t *value, uint16_t *pad_mix_gain)
5839 {
5840         struct bwn_phy *phy = &mac->mac_phy;
5841         uint16_t reg, v, padmix;
5842
5843         if (phy->type == BWN_PHYTYPE_B) {
5844                 v = 0x30;
5845                 if (phy->rf_rev <= 5) {
5846                         reg = 0x43;
5847                         padmix = 0;
5848                 } else {
5849                         reg = 0x52;
5850                         padmix = 5;
5851                 }
5852         } else {
5853                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5854                         reg = 0x43;
5855                         v = 0x10;
5856                         padmix = 2;
5857                 } else {
5858                         reg = 0x52;
5859                         v = 0x30;
5860                         padmix = 5;
5861                 }
5862         }
5863         if (value)
5864                 *value = v;
5865         if (pad_mix_gain)
5866                 *pad_mix_gain = padmix;
5867
5868         return (reg);
5869 }
5870
5871 static void
5872 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5873 {
5874         struct bwn_phy *phy = &mac->mac_phy;
5875         struct bwn_phy_g *pg = &phy->phy_g;
5876         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5877         uint16_t reg, mask;
5878         uint16_t trsw_rx, pga;
5879         uint16_t rf_pctl_reg;
5880
5881         static const uint8_t tx_bias_values[] = {
5882                 0x09, 0x08, 0x0a, 0x01, 0x00,
5883                 0x02, 0x05, 0x04, 0x06,
5884         };
5885         static const uint8_t tx_magn_values[] = {
5886                 0x70, 0x40,
5887         };
5888
5889         if (!BWN_HAS_LOOPBACK(phy)) {
5890                 rf_pctl_reg = 6;
5891                 trsw_rx = 2;
5892                 pga = 0;
5893         } else {
5894                 int lb_gain;
5895
5896                 trsw_rx = 0;
5897                 lb_gain = pg->pg_max_lb_gain / 2;
5898                 if (lb_gain > 10) {
5899                         rf_pctl_reg = 0;
5900                         pga = abs(10 - lb_gain) / 6;
5901                         pga = MIN(MAX(pga, 0), 15);
5902                 } else {
5903                         int cmp_val;
5904                         int tmp;
5905
5906                         pga = 0;
5907                         cmp_val = 0x24;
5908                         if ((phy->rev >= 2) &&
5909                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5910                                 cmp_val = 0x3c;
5911                         tmp = lb_gain;
5912                         if ((10 - lb_gain) < cmp_val)
5913                                 tmp = (10 - lb_gain);
5914                         if (tmp < 0)
5915                                 tmp += 6;
5916                         else
5917                                 tmp += 3;
5918                         cmp_val /= 4;
5919                         tmp /= 4;
5920                         if (tmp >= cmp_val)
5921                                 rf_pctl_reg = cmp_val;
5922                         else
5923                                 rf_pctl_reg = tmp;
5924                 }
5925         }
5926         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5927         bwn_phy_g_set_bbatt(mac, 2);
5928
5929         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5930         mask = ~mask;
5931         BWN_RF_MASK(mac, reg, mask);
5932
5933         if (BWN_HAS_TXMAG(phy)) {
5934                 int i, j;
5935                 int feedthrough;
5936                 int min_feedth = 0xffff;
5937                 uint8_t tx_magn, tx_bias;
5938
5939                 for (i = 0; i < N(tx_magn_values); i++) {
5940                         tx_magn = tx_magn_values[i];
5941                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5942                         for (j = 0; j < N(tx_bias_values); j++) {
5943                                 tx_bias = tx_bias_values[j];
5944                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5945                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5946                                     trsw_rx);
5947                                 if (feedthrough < min_feedth) {
5948                                         lo->tx_bias = tx_bias;
5949                                         lo->tx_magn = tx_magn;
5950                                         min_feedth = feedthrough;
5951                                 }
5952                                 if (lo->tx_bias == 0)
5953                                         break;
5954                         }
5955                         BWN_RF_WRITE(mac, 0x52,
5956                                           (BWN_RF_READ(mac, 0x52)
5957                                            & 0xff00) | lo->tx_bias | lo->
5958                                           tx_magn);
5959                 }
5960         } else {
5961                 lo->tx_magn = 0;
5962                 lo->tx_bias = 0;
5963                 BWN_RF_MASK(mac, 0x52, 0xfff0);
5964         }
5965
5966         BWN_GETTIME(lo->txctl_measured_time);
5967 }
5968
5969 static void
5970 bwn_lo_get_powervector(struct bwn_mac *mac)
5971 {
5972         struct bwn_phy *phy = &mac->mac_phy;
5973         struct bwn_phy_g *pg = &phy->phy_g;
5974         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5975         int i;
5976         uint64_t tmp;
5977         uint64_t power_vector = 0;
5978
5979         for (i = 0; i < 8; i += 2) {
5980                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5981                 power_vector |= (tmp << (i * 8));
5982                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5983         }
5984         if (power_vector)
5985                 lo->power_vector = power_vector;
5986
5987         BWN_GETTIME(lo->pwr_vec_read_time);
5988 }
5989
5990 static void
5991 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5992     int use_trsw_rx)
5993 {
5994         struct bwn_phy *phy = &mac->mac_phy;
5995         struct bwn_phy_g *pg = &phy->phy_g;
5996         uint16_t tmp;
5997
5998         if (max_rx_gain < 0)
5999                 max_rx_gain = 0;
6000
6001         if (BWN_HAS_LOOPBACK(phy)) {
6002                 int trsw_rx = 0;
6003                 int trsw_rx_gain;
6004
6005                 if (use_trsw_rx) {
6006                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6007                         if (max_rx_gain >= trsw_rx_gain) {
6008                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6009                                 trsw_rx = 0x20;
6010                         }
6011                 } else
6012                         trsw_rx_gain = max_rx_gain;
6013                 if (trsw_rx_gain < 9) {
6014                         pg->pg_lna_lod_gain = 0;
6015                 } else {
6016                         pg->pg_lna_lod_gain = 1;
6017                         trsw_rx_gain -= 8;
6018                 }
6019                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6020                 pg->pg_pga_gain = trsw_rx_gain / 3;
6021                 if (pg->pg_pga_gain >= 5) {
6022                         pg->pg_pga_gain -= 5;
6023                         pg->pg_lna_gain = 2;
6024                 } else
6025                         pg->pg_lna_gain = 0;
6026         } else {
6027                 pg->pg_lna_gain = 0;
6028                 pg->pg_trsw_rx_gain = 0x20;
6029                 if (max_rx_gain >= 0x14) {
6030                         pg->pg_lna_lod_gain = 1;
6031                         pg->pg_pga_gain = 2;
6032                 } else if (max_rx_gain >= 0x12) {
6033                         pg->pg_lna_lod_gain = 1;
6034                         pg->pg_pga_gain = 1;
6035                 } else if (max_rx_gain >= 0xf) {
6036                         pg->pg_lna_lod_gain = 1;
6037                         pg->pg_pga_gain = 0;
6038                 } else {
6039                         pg->pg_lna_lod_gain = 0;
6040                         pg->pg_pga_gain = 0;
6041                 }
6042         }
6043
6044         tmp = BWN_RF_READ(mac, 0x7a);
6045         if (pg->pg_lna_lod_gain == 0)
6046                 tmp &= ~0x0008;
6047         else
6048                 tmp |= 0x0008;
6049         BWN_RF_WRITE(mac, 0x7a, tmp);
6050 }
6051
6052 static void
6053 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6054 {
6055         struct bwn_phy *phy = &mac->mac_phy;
6056         struct bwn_phy_g *pg = &phy->phy_g;
6057         struct bwn_softc *sc = mac->mac_sc;
6058         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6059         struct timespec ts;
6060         uint16_t tmp;
6061
6062         if (bwn_has_hwpctl(mac)) {
6063                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6064                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6065                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6066                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6067                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6068
6069                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6070                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6071                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6072                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6073         }
6074         if (phy->type == BWN_PHYTYPE_B &&
6075             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6076                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6077                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6078         }
6079         if (phy->rev >= 2) {
6080                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6081                 sav->phy_analogoverval =
6082                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6083                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6084                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6085                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6086                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6087                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6088
6089                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6090                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6091                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6092                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6093                 if (phy->type == BWN_PHYTYPE_G) {
6094                         if ((phy->rev >= 7) &&
6095                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6096                              BWN_BFL_EXTLNA)) {
6097                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6098                         } else {
6099                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6100                         }
6101                 } else {
6102                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6103                 }
6104                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6105         }
6106         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6107         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6108         sav->rf0 = BWN_RF_READ(mac, 0x43);
6109         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6110         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6111         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6112         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6113         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6114
6115         if (!BWN_HAS_TXMAG(phy)) {
6116                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6117                 sav->rf2 &= 0x00f0;
6118         }
6119         if (phy->type == BWN_PHYTYPE_B) {
6120                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6121                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6122                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6123                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6124         } else {
6125                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6126                             | 0x8000);
6127         }
6128         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6129                     & 0xf000);
6130
6131         tmp =
6132             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6133         BWN_PHY_WRITE(mac, tmp, 0x007f);
6134
6135         tmp = sav->phy_syncctl;
6136         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6137         tmp = sav->rf1;
6138         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6139
6140         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6141         if (phy->type == BWN_PHYTYPE_G ||
6142             (phy->type == BWN_PHYTYPE_B &&
6143              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6144                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6145         } else
6146                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6147         if (phy->rev >= 2)
6148                 bwn_dummy_transmission(mac, 0, 1);
6149         bwn_phy_g_switch_chan(mac, 6, 0);
6150         BWN_RF_READ(mac, 0x51);
6151         if (phy->type == BWN_PHYTYPE_G)
6152                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6153
6154         nanouptime(&ts);
6155         if (time_before(lo->txctl_measured_time,
6156             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6157                 bwn_lo_measure_txctl_values(mac);
6158
6159         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6160                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6161         else {
6162                 if (phy->type == BWN_PHYTYPE_B)
6163                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6164                 else
6165                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6166         }
6167 }
6168
6169 static void
6170 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6171 {
6172         struct bwn_phy *phy = &mac->mac_phy;
6173         struct bwn_phy_g *pg = &phy->phy_g;
6174         uint16_t tmp;
6175
6176         if (phy->rev >= 2) {
6177                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6178                 tmp = (pg->pg_pga_gain << 8);
6179                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6180                 DELAY(5);
6181                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6182                 DELAY(2);
6183                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6184         } else {
6185                 tmp = (pg->pg_pga_gain | 0xefa0);
6186                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6187         }
6188         if (phy->type == BWN_PHYTYPE_G) {
6189                 if (phy->rev >= 3)
6190                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6191                 else
6192                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6193                 if (phy->rev >= 2)
6194                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6195                 else
6196                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6197         }
6198         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6199         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6200         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6201         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6202         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6203         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6204         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6205         if (!BWN_HAS_TXMAG(phy)) {
6206                 tmp = sav->rf2;
6207                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6208         }
6209         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6210         if (phy->type == BWN_PHYTYPE_B &&
6211             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6212                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6213                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6214         }
6215         if (phy->rev >= 2) {
6216                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6217                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6218                               sav->phy_analogoverval);
6219                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6220                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6221                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6222                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6223                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6224         }
6225         if (bwn_has_hwpctl(mac)) {
6226                 tmp = (sav->phy_lomask & 0xbfff);
6227                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6228                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6229                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6230                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6231                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6232         }
6233         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6234 }
6235
6236 static int
6237 bwn_lo_probe_loctl(struct bwn_mac *mac,
6238     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6239 {
6240         struct bwn_phy *phy = &mac->mac_phy;
6241         struct bwn_phy_g *pg = &phy->phy_g;
6242         struct bwn_loctl orig, test;
6243         struct bwn_loctl prev = { -100, -100 };
6244         static const struct bwn_loctl modifiers[] = {
6245                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6246                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6247         };
6248         int begin, end, lower = 0, i;
6249         uint16_t feedth;
6250
6251         if (d->curstate == 0) {
6252                 begin = 1;
6253                 end = 8;
6254         } else if (d->curstate % 2 == 0) {
6255                 begin = d->curstate - 1;
6256                 end = d->curstate + 1;
6257         } else {
6258                 begin = d->curstate - 2;
6259                 end = d->curstate + 2;
6260         }
6261         if (begin < 1)
6262                 begin += 8;
6263         if (end > 8)
6264                 end -= 8;
6265
6266         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6267         i = begin;
6268         d->curstate = i;
6269         while (1) {
6270                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6271                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6272                 test.i += modifiers[i - 1].i * d->multipler;
6273                 test.q += modifiers[i - 1].q * d->multipler;
6274                 if ((test.i != prev.i || test.q != prev.q) &&
6275                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6276                         bwn_lo_write(mac, &test);
6277                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6278                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6279                         if (feedth < d->feedth) {
6280                                 memcpy(probe, &test,
6281                                     sizeof(struct bwn_loctl));
6282                                 lower = 1;
6283                                 d->feedth = feedth;
6284                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6285                                         break;
6286                         }
6287                 }
6288                 memcpy(&prev, &test, sizeof(prev));
6289                 if (i == end)
6290                         break;
6291                 if (i == 8)
6292                         i = 1;
6293                 else
6294                         i++;
6295                 d->curstate = i;
6296         }
6297
6298         return (lower);
6299 }
6300
6301 static void
6302 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6303 {
6304         struct bwn_phy *phy = &mac->mac_phy;
6305         struct bwn_phy_g *pg = &phy->phy_g;
6306         struct bwn_lo_g_sm d;
6307         struct bwn_loctl probe;
6308         int lower, repeat, cnt = 0;
6309         uint16_t feedth;
6310
6311         d.nmeasure = 0;
6312         d.multipler = 1;
6313         if (BWN_HAS_LOOPBACK(phy))
6314                 d.multipler = 3;
6315
6316         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6317         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6318
6319         do {
6320                 bwn_lo_write(mac, &d.loctl);
6321                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6322                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6323                 if (feedth < 0x258) {
6324                         if (feedth >= 0x12c)
6325                                 *rxgain += 6;
6326                         else
6327                                 *rxgain += 3;
6328                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6329                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6330                 }
6331                 d.feedth = feedth;
6332                 d.curstate = 0;
6333                 do {
6334                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6335                             ("%s:%d: fail", __func__, __LINE__));
6336                         memcpy(&probe, &d.loctl,
6337                                sizeof(struct bwn_loctl));
6338                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6339                         if (!lower)
6340                                 break;
6341                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6342                                 break;
6343                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6344                         d.nmeasure++;
6345                 } while (d.nmeasure < 24);
6346                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6347
6348                 if (BWN_HAS_LOOPBACK(phy)) {
6349                         if (d.feedth > 0x1194)
6350                                 *rxgain -= 6;
6351                         else if (d.feedth < 0x5dc)
6352                                 *rxgain += 3;
6353                         if (cnt == 0) {
6354                                 if (d.feedth <= 0x5dc) {
6355                                         d.multipler = 1;
6356                                         cnt++;
6357                                 } else
6358                                         d.multipler = 2;
6359                         } else if (cnt == 2)
6360                                 d.multipler = 1;
6361                 }
6362                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6363         } while (++cnt < repeat);
6364 }
6365
6366 static struct bwn_lo_calib *
6367 bwn_lo_calibset(struct bwn_mac *mac,
6368     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6369 {
6370         struct bwn_phy *phy = &mac->mac_phy;
6371         struct bwn_phy_g *pg = &phy->phy_g;
6372         struct bwn_loctl loctl = { 0, 0 };
6373         struct bwn_lo_calib *cal;
6374         struct bwn_lo_g_value sval = { 0 };
6375         int rxgain;
6376         uint16_t pad, reg, value;
6377
6378         sval.old_channel = phy->chan;
6379         bwn_mac_suspend(mac);
6380         bwn_lo_save(mac, &sval);
6381
6382         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6383         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6384         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6385
6386         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6387         if (rfatt->padmix)
6388                 rxgain -= pad;
6389         if (BWN_HAS_LOOPBACK(phy))
6390                 rxgain += pg->pg_max_lb_gain;
6391         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6392         bwn_phy_g_set_bbatt(mac, bbatt->att);
6393         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6394
6395         bwn_lo_restore(mac, &sval);
6396         bwn_mac_enable(mac);
6397
6398         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6399         if (!cal) {
6400                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6401                 return (NULL);
6402         }
6403         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6404         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6405         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6406
6407         BWN_GETTIME(cal->calib_time);
6408
6409         return (cal);
6410 }
6411
6412 static struct bwn_lo_calib *
6413 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6414     const struct bwn_rfatt *rfatt)
6415 {
6416         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6417         struct bwn_lo_calib *c;
6418
6419         TAILQ_FOREACH(c, &lo->calib_list, list) {
6420                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6421                         continue;
6422                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6423                         continue;
6424                 return (c);
6425         }
6426
6427         c = bwn_lo_calibset(mac, bbatt, rfatt);
6428         if (!c)
6429                 return (NULL);
6430         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6431
6432         return (c);
6433 }
6434
6435 static void
6436 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6437 {
6438         struct bwn_phy *phy = &mac->mac_phy;
6439         struct bwn_phy_g *pg = &phy->phy_g;
6440         struct bwn_softc *sc = mac->mac_sc;
6441         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6442         const struct bwn_rfatt *rfatt;
6443         const struct bwn_bbatt *bbatt;
6444         uint64_t pvector;
6445         int i;
6446         int rf_offset, bb_offset;
6447         uint8_t changed = 0;
6448
6449         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6450         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6451             ("%s:%d: fail", __func__, __LINE__));
6452
6453         pvector = lo->power_vector;
6454         if (!update && !pvector)
6455                 return;
6456
6457         bwn_mac_suspend(mac);
6458
6459         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6460                 struct bwn_lo_calib *cal;
6461                 int idx;
6462                 uint16_t val;
6463
6464                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6465                         continue;
6466                 bb_offset = i / lo->rfatt.len;
6467                 rf_offset = i % lo->rfatt.len;
6468                 bbatt = &(lo->bbatt.array[bb_offset]);
6469                 rfatt = &(lo->rfatt.array[rf_offset]);
6470
6471                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6472                 if (!cal) {
6473                         device_printf(sc->sc_dev, "LO: Could not "
6474                             "calibrate DC table entry\n");
6475                         continue;
6476                 }
6477                 val = (uint8_t)(cal->ctl.q);
6478                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6479                 free(cal, M_DEVBUF);
6480
6481                 idx = i / 2;
6482                 if (i % 2)
6483                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6484                             | ((val & 0x00ff) << 8);
6485                 else
6486                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6487                             | (val & 0x00ff);
6488                 changed = 1;
6489         }
6490         if (changed) {
6491                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6492                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6493         }
6494         bwn_mac_enable(mac);
6495 }
6496
6497 static void
6498 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6499 {
6500
6501         if (!rf->padmix)
6502                 return;
6503         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6504                 rf->att = 4;
6505 }
6506
6507 static void
6508 bwn_lo_g_adjust(struct bwn_mac *mac)
6509 {
6510         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6511         struct bwn_lo_calib *cal;
6512         struct bwn_rfatt rf;
6513
6514         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6515         bwn_lo_fixup_rfatt(&rf);
6516
6517         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6518         if (!cal)
6519                 return;
6520         bwn_lo_write(mac, &cal->ctl);
6521 }
6522
6523 static void
6524 bwn_lo_g_init(struct bwn_mac *mac)
6525 {
6526
6527         if (!bwn_has_hwpctl(mac))
6528                 return;
6529
6530         bwn_lo_get_powervector(mac);
6531         bwn_phy_g_dc_lookup_init(mac, 1);
6532 }
6533
6534 static void
6535 bwn_mac_suspend(struct bwn_mac *mac)
6536 {
6537         struct bwn_softc *sc = mac->mac_sc;
6538         int i;
6539         uint32_t tmp;
6540
6541         KASSERT(mac->mac_suspended >= 0,
6542             ("%s:%d: fail", __func__, __LINE__));
6543
6544         if (mac->mac_suspended == 0) {
6545                 bwn_psctl(mac, BWN_PS_AWAKE);
6546                 BWN_WRITE_4(mac, BWN_MACCTL,
6547                             BWN_READ_4(mac, BWN_MACCTL)
6548                             & ~BWN_MACCTL_ON);
6549                 BWN_READ_4(mac, BWN_MACCTL);
6550                 for (i = 35; i; i--) {
6551                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6552                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6553                                 goto out;
6554                         DELAY(10);
6555                 }
6556                 for (i = 40; i; i--) {
6557                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6558                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6559                                 goto out;
6560                         DELAY(1000);
6561                 }
6562                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6563         }
6564 out:
6565         mac->mac_suspended++;
6566 }
6567
6568 static void
6569 bwn_mac_enable(struct bwn_mac *mac)
6570 {
6571         struct bwn_softc *sc = mac->mac_sc;
6572         uint16_t state;
6573
6574         state = bwn_shm_read_2(mac, BWN_SHARED,
6575             BWN_SHARED_UCODESTAT);
6576         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6577             state != BWN_SHARED_UCODESTAT_SLEEP)
6578                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6579
6580         mac->mac_suspended--;
6581         KASSERT(mac->mac_suspended >= 0,
6582             ("%s:%d: fail", __func__, __LINE__));
6583         if (mac->mac_suspended == 0) {
6584                 BWN_WRITE_4(mac, BWN_MACCTL,
6585                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6586                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6587                 BWN_READ_4(mac, BWN_MACCTL);
6588                 BWN_READ_4(mac, BWN_INTR_REASON);
6589                 bwn_psctl(mac, 0);
6590         }
6591 }
6592
6593 static void
6594 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6595 {
6596         struct bwn_softc *sc = mac->mac_sc;
6597         int i;
6598         uint16_t ucstat;
6599
6600         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6601             ("%s:%d: fail", __func__, __LINE__));
6602         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6603             ("%s:%d: fail", __func__, __LINE__));
6604
6605         /* XXX forcibly awake and hwps-off */
6606
6607         BWN_WRITE_4(mac, BWN_MACCTL,
6608             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6609             ~BWN_MACCTL_HWPS);
6610         BWN_READ_4(mac, BWN_MACCTL);
6611         if (siba_get_revid(sc->sc_dev) >= 5) {
6612                 for (i = 0; i < 100; i++) {
6613                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6614                             BWN_SHARED_UCODESTAT);
6615                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6616                                 break;
6617                         DELAY(10);
6618                 }
6619         }
6620 }
6621
6622 static int16_t
6623 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6624 {
6625
6626         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6627         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6628 }
6629
6630 static void
6631 bwn_nrssi_threshold(struct bwn_mac *mac)
6632 {
6633         struct bwn_phy *phy = &mac->mac_phy;
6634         struct bwn_phy_g *pg = &phy->phy_g;
6635         struct bwn_softc *sc = mac->mac_sc;
6636         int32_t a, b;
6637         int16_t tmp16;
6638         uint16_t tmpu16;
6639
6640         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6641
6642         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6643                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6644                         a = 0x13;
6645                         b = 0x12;
6646                 } else {
6647                         a = 0xe;
6648                         b = 0x11;
6649                 }
6650
6651                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6652                 a += (pg->pg_nrssi[0] << 6);
6653                 a += (a < 32) ? 31 : 32;
6654                 a = a >> 6;
6655                 a = MIN(MAX(a, -31), 31);
6656
6657                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6658                 b += (pg->pg_nrssi[0] << 6);
6659                 if (b < 32)
6660                         b += 31;
6661                 else
6662                         b += 32;
6663                 b = b >> 6;
6664                 b = MIN(MAX(b, -31), 31);
6665
6666                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6667                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6668                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6669                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6670                 return;
6671         }
6672
6673         tmp16 = bwn_nrssi_read(mac, 0x20);
6674         if (tmp16 >= 0x20)
6675                 tmp16 -= 0x40;
6676         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6677 }
6678
6679 static void
6680 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6681 {
6682 #define SAVE_RF_MAX             3
6683 #define SAVE_PHY_COMM_MAX       4
6684 #define SAVE_PHY3_MAX           8
6685         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6686                 { 0x7a, 0x52, 0x43 };
6687         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6688                 { 0x15, 0x5a, 0x59, 0x58 };
6689         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6690                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6691                 0x0801, 0x0060, 0x0014, 0x0478
6692         };
6693         struct bwn_phy *phy = &mac->mac_phy;
6694         struct bwn_phy_g *pg = &phy->phy_g;
6695         int32_t i, tmp32, phy3_idx = 0;
6696         uint16_t delta, tmp;
6697         uint16_t save_rf[SAVE_RF_MAX];
6698         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6699         uint16_t save_phy3[SAVE_PHY3_MAX];
6700         uint16_t ant_div, phy0, chan_ex;
6701         int16_t nrssi0, nrssi1;
6702
6703         KASSERT(phy->type == BWN_PHYTYPE_G,
6704             ("%s:%d: fail", __func__, __LINE__));
6705
6706         if (phy->rf_rev >= 9)
6707                 return;
6708         if (phy->rf_rev == 8)
6709                 bwn_nrssi_offset(mac);
6710
6711         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6712         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6713
6714         /*
6715          * Save RF/PHY registers for later restoration
6716          */
6717         ant_div = BWN_READ_2(mac, 0x03e2);
6718         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6719         for (i = 0; i < SAVE_RF_MAX; ++i)
6720                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6721         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6722                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6723
6724         phy0 = BWN_READ_2(mac, BWN_PHY0);
6725         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6726         if (phy->rev >= 3) {
6727                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6728                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6729                 BWN_PHY_WRITE(mac, 0x002e, 0);
6730                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6731                 switch (phy->rev) {
6732                 case 4:
6733                 case 6:
6734                 case 7:
6735                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6736                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6737                         break;
6738                 case 3:
6739                 case 5:
6740                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6741                         break;
6742                 }
6743                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6744                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6745         }
6746         /*
6747          * Calculate nrssi0
6748          */
6749         BWN_RF_SET(mac, 0x007a, 0x0070);
6750         bwn_set_all_gains(mac, 0, 8, 0);
6751         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6752         if (phy->rev >= 2) {
6753                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6754                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6755         }
6756         BWN_RF_SET(mac, 0x007a, 0x0080);
6757         DELAY(20);
6758
6759         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6760         if (nrssi0 >= 0x0020)
6761                 nrssi0 -= 0x0040;
6762
6763         /*
6764          * Calculate nrssi1
6765          */
6766         BWN_RF_MASK(mac, 0x007a, 0x007f);
6767         if (phy->rev >= 2)
6768                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6769
6770         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6771             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6772         BWN_RF_SET(mac, 0x007a, 0x000f);
6773         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6774         if (phy->rev >= 2) {
6775                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6776                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6777         }
6778
6779         bwn_set_all_gains(mac, 3, 0, 1);
6780         if (phy->rf_rev == 8) {
6781                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6782         } else {
6783                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6784                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6785                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6786                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6787         }
6788         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6789         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6790         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6791         DELAY(20);
6792         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6793
6794         /*
6795          * Install calculated narrow RSSI values
6796          */
6797         if (nrssi1 >= 0x0020)
6798                 nrssi1 -= 0x0040;
6799         if (nrssi0 == nrssi1)
6800                 pg->pg_nrssi_slope = 0x00010000;
6801         else
6802                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6803         if (nrssi0 >= -4) {
6804                 pg->pg_nrssi[0] = nrssi1;
6805                 pg->pg_nrssi[1] = nrssi0;
6806         }
6807
6808         /*
6809          * Restore saved RF/PHY registers
6810          */
6811         if (phy->rev >= 3) {
6812                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6813                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6814                             save_phy3[phy3_idx]);
6815                 }
6816         }
6817         if (phy->rev >= 2) {
6818                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6819                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6820         }
6821
6822         for (i = 0; i < SAVE_RF_MAX; ++i)
6823                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6824
6825         BWN_WRITE_2(mac, 0x03e2, ant_div);
6826         BWN_WRITE_2(mac, 0x03e6, phy0);
6827         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6828
6829         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6830                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6831
6832         bwn_spu_workaround(mac, phy->chan);
6833         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6834         bwn_set_original_gains(mac);
6835         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6836         if (phy->rev >= 3) {
6837                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6838                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6839                             save_phy3[phy3_idx]);
6840                 }
6841         }
6842
6843         delta = 0x1f - pg->pg_nrssi[0];
6844         for (i = 0; i < 64; i++) {
6845                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6846                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6847                 pg->pg_nrssi_lt[i] = tmp32;
6848         }
6849
6850         bwn_nrssi_threshold(mac);
6851 #undef SAVE_RF_MAX
6852 #undef SAVE_PHY_COMM_MAX
6853 #undef SAVE_PHY3_MAX
6854 }
6855
6856 static void
6857 bwn_nrssi_offset(struct bwn_mac *mac)
6858 {
6859 #define SAVE_RF_MAX             2
6860 #define SAVE_PHY_COMM_MAX       10
6861 #define SAVE_PHY6_MAX           8
6862         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6863                 { 0x7a, 0x43 };
6864         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6865                 0x0001, 0x0811, 0x0812, 0x0814,
6866                 0x0815, 0x005a, 0x0059, 0x0058,
6867                 0x000a, 0x0003
6868         };
6869         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6870                 0x002e, 0x002f, 0x080f, 0x0810,
6871                 0x0801, 0x0060, 0x0014, 0x0478
6872         };
6873         struct bwn_phy *phy = &mac->mac_phy;
6874         int i, phy6_idx = 0;
6875         uint16_t save_rf[SAVE_RF_MAX];
6876         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6877         uint16_t save_phy6[SAVE_PHY6_MAX];
6878         int16_t nrssi;
6879         uint16_t saved = 0xffff;
6880
6881         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6882                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6883         for (i = 0; i < SAVE_RF_MAX; ++i)
6884                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6885
6886         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6887         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6888         BWN_PHY_SET(mac, 0x0811, 0x000c);
6889         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6890         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6891         if (phy->rev >= 6) {
6892                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6893                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6894
6895                 BWN_PHY_WRITE(mac, 0x002e, 0);
6896                 BWN_PHY_WRITE(mac, 0x002f, 0);
6897                 BWN_PHY_WRITE(mac, 0x080f, 0);
6898                 BWN_PHY_WRITE(mac, 0x0810, 0);
6899                 BWN_PHY_SET(mac, 0x0478, 0x0100);
6900                 BWN_PHY_SET(mac, 0x0801, 0x0040);
6901                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6902                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6903         }
6904         BWN_RF_SET(mac, 0x007a, 0x0070);
6905         BWN_RF_SET(mac, 0x007a, 0x0080);
6906         DELAY(30);
6907
6908         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6909         if (nrssi >= 0x20)
6910                 nrssi -= 0x40;
6911         if (nrssi == 31) {
6912                 for (i = 7; i >= 4; i--) {
6913                         BWN_RF_WRITE(mac, 0x007b, i);
6914                         DELAY(20);
6915                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6916                             0x003f);
6917                         if (nrssi >= 0x20)
6918                                 nrssi -= 0x40;
6919                         if (nrssi < 31 && saved == 0xffff)
6920                                 saved = i;
6921                 }
6922                 if (saved == 0xffff)
6923                         saved = 4;
6924         } else {
6925                 BWN_RF_MASK(mac, 0x007a, 0x007f);
6926                 if (phy->rev != 1) {
6927                         BWN_PHY_SET(mac, 0x0814, 0x0001);
6928                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6929                 }
6930                 BWN_PHY_SET(mac, 0x0811, 0x000c);
6931                 BWN_PHY_SET(mac, 0x0812, 0x000c);
6932                 BWN_PHY_SET(mac, 0x0811, 0x0030);
6933                 BWN_PHY_SET(mac, 0x0812, 0x0030);
6934                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6935                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6936                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6937                 if (phy->rev == 0)
6938                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6939                 else
6940                         BWN_PHY_SET(mac, 0x000a, 0x2000);
6941                 if (phy->rev != 1) {
6942                         BWN_PHY_SET(mac, 0x0814, 0x0004);
6943                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6944                 }
6945                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6946                 BWN_RF_SET(mac, 0x007a, 0x000f);
6947                 bwn_set_all_gains(mac, 3, 0, 1);
6948                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6949                 DELAY(30);
6950                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6951                 if (nrssi >= 0x20)
6952                         nrssi -= 0x40;
6953                 if (nrssi == -32) {
6954                         for (i = 0; i < 4; i++) {
6955                                 BWN_RF_WRITE(mac, 0x007b, i);
6956                                 DELAY(20);
6957                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
6958                                     0x047f) >> 8) & 0x003f);
6959                                 if (nrssi >= 0x20)
6960                                         nrssi -= 0x40;
6961                                 if (nrssi > -31 && saved == 0xffff)
6962                                         saved = i;
6963                         }
6964                         if (saved == 0xffff)
6965                                 saved = 3;
6966                 } else
6967                         saved = 0;
6968         }
6969         BWN_RF_WRITE(mac, 0x007b, saved);
6970
6971         /*
6972          * Restore saved RF/PHY registers
6973          */
6974         if (phy->rev >= 6) {
6975                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6976                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6977                             save_phy6[phy6_idx]);
6978                 }
6979         }
6980         if (phy->rev != 1) {
6981                 for (i = 3; i < 5; i++)
6982                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6983                             save_phy_comm[i]);
6984         }
6985         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6986                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6987
6988         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6989                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6990
6991         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6992         BWN_PHY_SET(mac, 0x0429, 0x8000);
6993         bwn_set_original_gains(mac);
6994         if (phy->rev >= 6) {
6995                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6996                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6997                             save_phy6[phy6_idx]);
6998                 }
6999         }
7000
7001         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7002         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7003         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7004 }
7005
7006 static void
7007 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7008     int16_t third)
7009 {
7010         struct bwn_phy *phy = &mac->mac_phy;
7011         uint16_t i;
7012         uint16_t start = 0x08, end = 0x18;
7013         uint16_t tmp;
7014         uint16_t table;
7015
7016         if (phy->rev <= 1) {
7017                 start = 0x10;
7018                 end = 0x20;
7019         }
7020
7021         table = BWN_OFDMTAB_GAINX;
7022         if (phy->rev <= 1)
7023                 table = BWN_OFDMTAB_GAINX_R1;
7024         for (i = 0; i < 4; i++)
7025                 bwn_ofdmtab_write_2(mac, table, i, first);
7026
7027         for (i = start; i < end; i++)
7028                 bwn_ofdmtab_write_2(mac, table, i, second);
7029
7030         if (third != -1) {
7031                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7032                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7033                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7034                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7035         }
7036         bwn_dummy_transmission(mac, 0, 1);
7037 }
7038
7039 static void
7040 bwn_set_original_gains(struct bwn_mac *mac)
7041 {
7042         struct bwn_phy *phy = &mac->mac_phy;
7043         uint16_t i, tmp;
7044         uint16_t table;
7045         uint16_t start = 0x0008, end = 0x0018;
7046
7047         if (phy->rev <= 1) {
7048                 start = 0x0010;
7049                 end = 0x0020;
7050         }
7051
7052         table = BWN_OFDMTAB_GAINX;
7053         if (phy->rev <= 1)
7054                 table = BWN_OFDMTAB_GAINX_R1;
7055         for (i = 0; i < 4; i++) {
7056                 tmp = (i & 0xfffc);
7057                 tmp |= (i & 0x0001) << 1;
7058                 tmp |= (i & 0x0002) >> 1;
7059
7060                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7061         }
7062
7063         for (i = start; i < end; i++)
7064                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7065
7066         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7067         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7068         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7069         bwn_dummy_transmission(mac, 0, 1);
7070 }
7071
7072 static void
7073 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7074 {
7075         struct bwn_phy *phy = &mac->mac_phy;
7076         struct bwn_phy_g *pg = &phy->phy_g;
7077         struct bwn_rfatt old_rfatt, rfatt;
7078         struct bwn_bbatt old_bbatt, bbatt;
7079         struct bwn_softc *sc = mac->mac_sc;
7080         uint8_t old_txctl = 0;
7081
7082         KASSERT(phy->type == BWN_PHYTYPE_G,
7083             ("%s:%d: fail", __func__, __LINE__));
7084
7085         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7086             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7087                 return;
7088
7089         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7090
7091         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7092
7093         if (!phy->gmode)
7094                 return;
7095         bwn_hwpctl_early_init(mac);
7096         if (pg->pg_curtssi == 0) {
7097                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7098                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7099                 } else {
7100                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7101                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7102                         old_txctl = pg->pg_txctl;
7103
7104                         bbatt.att = 11;
7105                         if (phy->rf_rev == 8) {
7106                                 rfatt.att = 15;
7107                                 rfatt.padmix = 1;
7108                         } else {
7109                                 rfatt.att = 9;
7110                                 rfatt.padmix = 0;
7111                         }
7112                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7113                 }
7114                 bwn_dummy_transmission(mac, 0, 1);
7115                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7116                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7117                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7118                 else
7119                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7120                             &old_rfatt, old_txctl);
7121         }
7122         bwn_hwpctl_init_gphy(mac);
7123
7124         /* clear TSSI */
7125         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7126         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7127         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7128         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7129 }
7130
7131 static void
7132 bwn_hwpctl_early_init(struct bwn_mac *mac)
7133 {
7134         struct bwn_phy *phy = &mac->mac_phy;
7135
7136         if (!bwn_has_hwpctl(mac)) {
7137                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7138                 return;
7139         }
7140
7141         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7142         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7143         BWN_PHY_SET(mac, 0x047c, 0x0002);
7144         BWN_PHY_SET(mac, 0x047a, 0xf000);
7145         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7146                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7147                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7148                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7149                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7150                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7151         } else {
7152                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7153                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7154                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7155                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7156                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7157                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7158                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7159         }
7160 }
7161
7162 static void
7163 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7164 {
7165         struct bwn_phy *phy = &mac->mac_phy;
7166         struct bwn_phy_g *pg = &phy->phy_g;
7167         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7168         int i;
7169         uint16_t nr_written = 0, tmp, value;
7170         uint8_t rf, bb;
7171
7172         if (!bwn_has_hwpctl(mac)) {
7173                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7174                 return;
7175         }
7176
7177         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7178             (pg->pg_idletssi - pg->pg_curtssi));
7179         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7180             (pg->pg_idletssi - pg->pg_curtssi));
7181
7182         for (i = 0; i < 32; i++)
7183                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7184         for (i = 32; i < 64; i++)
7185                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7186         for (i = 0; i < 64; i += 2) {
7187                 value = (uint16_t) pg->pg_tssi2dbm[i];
7188                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7189                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7190         }
7191
7192         for (rf = 0; rf < lo->rfatt.len; rf++) {
7193                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7194                         if (nr_written >= 0x40)
7195                                 return;
7196                         tmp = lo->bbatt.array[bb].att;
7197                         tmp <<= 8;
7198                         if (phy->rf_rev == 8)
7199                                 tmp |= 0x50;
7200                         else
7201                                 tmp |= 0x40;
7202                         tmp |= lo->rfatt.array[rf].att;
7203                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7204                         nr_written++;
7205                 }
7206         }
7207
7208         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7209         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7210
7211         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7212         BWN_PHY_SET(mac, 0x0478, 0x0800);
7213         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7214         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7215
7216         bwn_phy_g_dc_lookup_init(mac, 1);
7217         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7218 }
7219
7220 static void
7221 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7222 {
7223         struct bwn_softc *sc = mac->mac_sc;
7224
7225         if (spu != 0)
7226                 bwn_spu_workaround(mac, channel);
7227
7228         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7229
7230         if (channel == 14) {
7231                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7232                         bwn_hf_write(mac,
7233                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7234                 else
7235                         bwn_hf_write(mac,
7236                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7237                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7238                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7239                 return;
7240         }
7241
7242         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7243             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7244 }
7245
7246 static uint16_t
7247 bwn_phy_g_chan2freq(uint8_t channel)
7248 {
7249         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7250
7251         KASSERT(channel >= 1 && channel <= 14,
7252             ("%s:%d: fail", __func__, __LINE__));
7253
7254         return (bwn_phy_g_rf_channels[channel - 1]);
7255 }
7256
7257 static void
7258 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7259     const struct bwn_rfatt *rfatt, uint8_t txctl)
7260 {
7261         struct bwn_phy *phy = &mac->mac_phy;
7262         struct bwn_phy_g *pg = &phy->phy_g;
7263         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7264         uint16_t bb, rf;
7265         uint16_t tx_bias, tx_magn;
7266
7267         bb = bbatt->att;
7268         rf = rfatt->att;
7269         tx_bias = lo->tx_bias;
7270         tx_magn = lo->tx_magn;
7271         if (tx_bias == 0xff)
7272                 tx_bias = 0;
7273
7274         pg->pg_txctl = txctl;
7275         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7276         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7277         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7278         bwn_phy_g_set_bbatt(mac, bb);
7279         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7280         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7281                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7282         else {
7283                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7284                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7285         }
7286         if (BWN_HAS_TXMAG(phy))
7287                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7288         else
7289                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7290         bwn_lo_g_adjust(mac);
7291 }
7292
7293 static void
7294 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7295     uint16_t bbatt)
7296 {
7297         struct bwn_phy *phy = &mac->mac_phy;
7298
7299         if (phy->analog == 0) {
7300                 BWN_WRITE_2(mac, BWN_PHY0,
7301                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7302                 return;
7303         }
7304         if (phy->analog > 1) {
7305                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7306                 return;
7307         }
7308         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7309 }
7310
7311 static uint16_t
7312 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7313 {
7314         struct bwn_phy *phy = &mac->mac_phy;
7315         struct bwn_phy_g *pg = &phy->phy_g;
7316         struct bwn_softc *sc = mac->mac_sc;
7317         int max_lb_gain;
7318         uint16_t extlna;
7319         uint16_t i;
7320
7321         if (phy->gmode == 0)
7322                 return (0);
7323
7324         if (BWN_HAS_LOOPBACK(phy)) {
7325                 max_lb_gain = pg->pg_max_lb_gain;
7326                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7327                 if (max_lb_gain >= 0x46) {
7328                         extlna = 0x3000;
7329                         max_lb_gain -= 0x46;
7330                 } else if (max_lb_gain >= 0x3a) {
7331                         extlna = 0x1000;
7332                         max_lb_gain -= 0x3a;
7333                 } else if (max_lb_gain >= 0x2e) {
7334                         extlna = 0x2000;
7335                         max_lb_gain -= 0x2e;
7336                 } else {
7337                         extlna = 0;
7338                         max_lb_gain -= 0x10;
7339                 }
7340
7341                 for (i = 0; i < 16; i++) {
7342                         max_lb_gain -= (i * 6);
7343                         if (max_lb_gain < 6)
7344                                 break;
7345                 }
7346
7347                 if ((phy->rev < 7) ||
7348                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7349                         if (reg == BWN_PHY_RFOVER) {
7350                                 return (0x1b3);
7351                         } else if (reg == BWN_PHY_RFOVERVAL) {
7352                                 extlna |= (i << 8);
7353                                 switch (lpd) {
7354                                 case BWN_LPD(0, 1, 1):
7355                                         return (0x0f92);
7356                                 case BWN_LPD(0, 0, 1):
7357                                 case BWN_LPD(1, 0, 1):
7358                                         return (0x0092 | extlna);
7359                                 case BWN_LPD(1, 0, 0):
7360                                         return (0x0093 | extlna);
7361                                 }
7362                                 KASSERT(0 == 1,
7363                                     ("%s:%d: fail", __func__, __LINE__));
7364                         }
7365                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7366                 } else {
7367                         if (reg == BWN_PHY_RFOVER)
7368                                 return (0x9b3);
7369                         if (reg == BWN_PHY_RFOVERVAL) {
7370                                 if (extlna)
7371                                         extlna |= 0x8000;
7372                                 extlna |= (i << 8);
7373                                 switch (lpd) {
7374                                 case BWN_LPD(0, 1, 1):
7375                                         return (0x8f92);
7376                                 case BWN_LPD(0, 0, 1):
7377                                         return (0x8092 | extlna);
7378                                 case BWN_LPD(1, 0, 1):
7379                                         return (0x2092 | extlna);
7380                                 case BWN_LPD(1, 0, 0):
7381                                         return (0x2093 | extlna);
7382                                 }
7383                                 KASSERT(0 == 1,
7384                                     ("%s:%d: fail", __func__, __LINE__));
7385                         }
7386                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7387                 }
7388                 return (0);
7389         }
7390
7391         if ((phy->rev < 7) ||
7392             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7393                 if (reg == BWN_PHY_RFOVER) {
7394                         return (0x1b3);
7395                 } else if (reg == BWN_PHY_RFOVERVAL) {
7396                         switch (lpd) {
7397                         case BWN_LPD(0, 1, 1):
7398                                 return (0x0fb2);
7399                         case BWN_LPD(0, 0, 1):
7400                                 return (0x00b2);
7401                         case BWN_LPD(1, 0, 1):
7402                                 return (0x30b2);
7403                         case BWN_LPD(1, 0, 0):
7404                                 return (0x30b3);
7405                         }
7406                         KASSERT(0 == 1,
7407                             ("%s:%d: fail", __func__, __LINE__));
7408                 }
7409                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7410         } else {
7411                 if (reg == BWN_PHY_RFOVER) {
7412                         return (0x9b3);
7413                 } else if (reg == BWN_PHY_RFOVERVAL) {
7414                         switch (lpd) {
7415                         case BWN_LPD(0, 1, 1):
7416                                 return (0x8fb2);
7417                         case BWN_LPD(0, 0, 1):
7418                                 return (0x80b2);
7419                         case BWN_LPD(1, 0, 1):
7420                                 return (0x20b2);
7421                         case BWN_LPD(1, 0, 0):
7422                                 return (0x20b3);
7423                         }
7424                         KASSERT(0 == 1,
7425                             ("%s:%d: fail", __func__, __LINE__));
7426                 }
7427                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7428         }
7429         return (0);
7430 }
7431
7432 static void
7433 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7434 {
7435
7436         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7437                 return;
7438         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7439             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7440         DELAY(1000);
7441         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7442 }
7443
7444 static int
7445 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7446 {
7447         struct bwn_softc *sc = mac->mac_sc;
7448         struct bwn_fw *fw = &mac->mac_fw;
7449         const uint8_t rev = siba_get_revid(sc->sc_dev);
7450         const char *filename;
7451         uint32_t high;
7452         int error;
7453
7454         /* microcode */
7455         if (rev >= 5 && rev <= 10)
7456                 filename = "ucode5";
7457         else if (rev >= 11 && rev <= 12)
7458                 filename = "ucode11";
7459         else if (rev == 13)
7460                 filename = "ucode13";
7461         else if (rev == 14)
7462                 filename = "ucode14";
7463         else if (rev >= 15)
7464                 filename = "ucode15";
7465         else {
7466                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7467                 bwn_release_firmware(mac);
7468                 return (EOPNOTSUPP);
7469         }
7470         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7471         if (error) {
7472                 bwn_release_firmware(mac);
7473                 return (error);
7474         }
7475
7476         /* PCM */
7477         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7478         if (rev >= 5 && rev <= 10) {
7479                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7480                 if (error == ENOENT)
7481                         fw->no_pcmfile = 1;
7482                 else if (error) {
7483                         bwn_release_firmware(mac);
7484                         return (error);
7485                 }
7486         } else if (rev < 11) {
7487                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7488                 return (EOPNOTSUPP);
7489         }
7490
7491         /* initvals */
7492         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7493         switch (mac->mac_phy.type) {
7494         case BWN_PHYTYPE_A:
7495                 if (rev < 5 || rev > 10)
7496                         goto fail1;
7497                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7498                         filename = "a0g1initvals5";
7499                 else
7500                         filename = "a0g0initvals5";
7501                 break;
7502         case BWN_PHYTYPE_G:
7503                 if (rev >= 5 && rev <= 10)
7504                         filename = "b0g0initvals5";
7505                 else if (rev >= 13)
7506                         filename = "b0g0initvals13";
7507                 else
7508                         goto fail1;
7509                 break;
7510         case BWN_PHYTYPE_LP:
7511                 if (rev == 13)
7512                         filename = "lp0initvals13";
7513                 else if (rev == 14)
7514                         filename = "lp0initvals14";
7515                 else if (rev >= 15)
7516                         filename = "lp0initvals15";
7517                 else
7518                         goto fail1;
7519                 break;
7520         case BWN_PHYTYPE_N:
7521                 if (rev >= 11 && rev <= 12)
7522                         filename = "n0initvals11";
7523                 else
7524                         goto fail1;
7525                 break;
7526         default:
7527                 goto fail1;
7528         }
7529         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7530         if (error) {
7531                 bwn_release_firmware(mac);
7532                 return (error);
7533         }
7534
7535         /* bandswitch initvals */
7536         switch (mac->mac_phy.type) {
7537         case BWN_PHYTYPE_A:
7538                 if (rev >= 5 && rev <= 10) {
7539                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7540                                 filename = "a0g1bsinitvals5";
7541                         else
7542                                 filename = "a0g0bsinitvals5";
7543                 } else if (rev >= 11)
7544                         filename = NULL;
7545                 else
7546                         goto fail1;
7547                 break;
7548         case BWN_PHYTYPE_G:
7549                 if (rev >= 5 && rev <= 10)
7550                         filename = "b0g0bsinitvals5";
7551                 else if (rev >= 11)
7552                         filename = NULL;
7553                 else
7554                         goto fail1;
7555                 break;
7556         case BWN_PHYTYPE_LP:
7557                 if (rev == 13)
7558                         filename = "lp0bsinitvals13";
7559                 else if (rev == 14)
7560                         filename = "lp0bsinitvals14";
7561                 else if (rev >= 15)
7562                         filename = "lp0bsinitvals15";
7563                 else
7564                         goto fail1;
7565                 break;
7566         case BWN_PHYTYPE_N:
7567                 if (rev >= 11 && rev <= 12)
7568                         filename = "n0bsinitvals11";
7569                 else
7570                         goto fail1;
7571                 break;
7572         default:
7573                 goto fail1;
7574         }
7575         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7576         if (error) {
7577                 bwn_release_firmware(mac);
7578                 return (error);
7579         }
7580         return (0);
7581 fail1:
7582         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7583         bwn_release_firmware(mac);
7584         return (EOPNOTSUPP);
7585 }
7586
7587 static int
7588 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7589     const char *name, struct bwn_fwfile *bfw)
7590 {
7591         const struct bwn_fwhdr *hdr;
7592         struct bwn_softc *sc = mac->mac_sc;
7593         const struct firmware *fw;
7594         char namebuf[64];
7595
7596         if (name == NULL) {
7597                 bwn_do_release_fw(bfw);
7598                 return (0);
7599         }
7600         if (bfw->filename != NULL) {
7601                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7602                         return (0);
7603                 bwn_do_release_fw(bfw);
7604         }
7605
7606         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7607             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7608             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7609         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7610         fw = firmware_get(namebuf);
7611         if (fw == NULL) {
7612                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7613                     namebuf);
7614                 return (ENOENT);
7615         }
7616         if (fw->datasize < sizeof(struct bwn_fwhdr))
7617                 goto fail;
7618         hdr = (const struct bwn_fwhdr *)(fw->data);
7619         switch (hdr->type) {
7620         case BWN_FWTYPE_UCODE:
7621         case BWN_FWTYPE_PCM:
7622                 if (be32toh(hdr->size) !=
7623                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7624                         goto fail;
7625                 /* FALLTHROUGH */
7626         case BWN_FWTYPE_IV:
7627                 if (hdr->ver != 1)
7628                         goto fail;
7629                 break;
7630         default:
7631                 goto fail;
7632         }
7633         bfw->filename = name;
7634         bfw->fw = fw;
7635         bfw->type = type;
7636         return (0);
7637 fail:
7638         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7639         if (fw != NULL)
7640                 firmware_put(fw, FIRMWARE_UNLOAD);
7641         return (EPROTO);
7642 }
7643
7644 static void
7645 bwn_release_firmware(struct bwn_mac *mac)
7646 {
7647
7648         bwn_do_release_fw(&mac->mac_fw.ucode);
7649         bwn_do_release_fw(&mac->mac_fw.pcm);
7650         bwn_do_release_fw(&mac->mac_fw.initvals);
7651         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7652 }
7653
7654 static void
7655 bwn_do_release_fw(struct bwn_fwfile *bfw)
7656 {
7657
7658         if (bfw->fw != NULL)
7659                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7660         bfw->fw = NULL;
7661         bfw->filename = NULL;
7662 }
7663
7664 static int
7665 bwn_fw_loaducode(struct bwn_mac *mac)
7666 {
7667 #define GETFWOFFSET(fwp, offset)        \
7668         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7669 #define GETFWSIZE(fwp, offset)  \
7670         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7671         struct bwn_softc *sc = mac->mac_sc;
7672         const uint32_t *data;
7673         unsigned int i;
7674         uint32_t ctl;
7675         uint16_t date, fwcaps, time;
7676         int error = 0;
7677
7678         ctl = BWN_READ_4(mac, BWN_MACCTL);
7679         ctl |= BWN_MACCTL_MCODE_JMP0;
7680         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7681             __LINE__));
7682         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7683         for (i = 0; i < 64; i++)
7684                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7685         for (i = 0; i < 4096; i += 2)
7686                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7687
7688         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7689         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7690         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7691              i++) {
7692                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7693                 DELAY(10);
7694         }
7695
7696         if (mac->mac_fw.pcm.fw) {
7697                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7698                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7699                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7700                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7701                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7702                     sizeof(struct bwn_fwhdr)); i++) {
7703                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7704                         DELAY(10);
7705                 }
7706         }
7707
7708         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7709         BWN_WRITE_4(mac, BWN_MACCTL,
7710             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7711             BWN_MACCTL_MCODE_RUN);
7712
7713         for (i = 0; i < 21; i++) {
7714                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7715                         break;
7716                 if (i >= 20) {
7717                         device_printf(sc->sc_dev, "ucode timeout\n");
7718                         error = ENXIO;
7719                         goto error;
7720                 }
7721                 DELAY(50000);
7722         }
7723         BWN_READ_4(mac, BWN_INTR_REASON);
7724
7725         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7726         if (mac->mac_fw.rev <= 0x128) {
7727                 device_printf(sc->sc_dev, "the firmware is too old\n");
7728                 error = EOPNOTSUPP;
7729                 goto error;
7730         }
7731         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7732             BWN_SHARED_UCODE_PATCH);
7733         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7734         mac->mac_fw.opensource = (date == 0xffff);
7735         if (bwn_wme != 0)
7736                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7737         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7738
7739         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7740         if (mac->mac_fw.opensource == 0) {
7741                 device_printf(sc->sc_dev,
7742                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7743                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7744                 if (mac->mac_fw.no_pcmfile)
7745                         device_printf(sc->sc_dev,
7746                             "no HW crypto acceleration due to pcm5\n");
7747         } else {
7748                 mac->mac_fw.patch = time;
7749                 fwcaps = bwn_fwcaps_read(mac);
7750                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7751                         device_printf(sc->sc_dev,
7752                             "disabling HW crypto acceleration\n");
7753                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7754                 }
7755                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7756                         device_printf(sc->sc_dev, "disabling WME support\n");
7757                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7758                 }
7759         }
7760
7761         if (BWN_ISOLDFMT(mac))
7762                 device_printf(sc->sc_dev, "using old firmware image\n");
7763
7764         return (0);
7765
7766 error:
7767         BWN_WRITE_4(mac, BWN_MACCTL,
7768             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7769             BWN_MACCTL_MCODE_JMP0);
7770
7771         return (error);
7772 #undef GETFWSIZE
7773 #undef GETFWOFFSET
7774 }
7775
7776 /* OpenFirmware only */
7777 static uint16_t
7778 bwn_fwcaps_read(struct bwn_mac *mac)
7779 {
7780
7781         KASSERT(mac->mac_fw.opensource == 1,
7782             ("%s:%d: fail", __func__, __LINE__));
7783         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7784 }
7785
7786 static int
7787 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7788     size_t count, size_t array_size)
7789 {
7790 #define GET_NEXTIV16(iv)                                                \
7791         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7792             sizeof(uint16_t) + sizeof(uint16_t)))
7793 #define GET_NEXTIV32(iv)                                                \
7794         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7795             sizeof(uint16_t) + sizeof(uint32_t)))
7796         struct bwn_softc *sc = mac->mac_sc;
7797         const struct bwn_fwinitvals *iv;
7798         uint16_t offset;
7799         size_t i;
7800         uint8_t bit32;
7801
7802         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7803             ("%s:%d: fail", __func__, __LINE__));
7804         iv = ivals;
7805         for (i = 0; i < count; i++) {
7806                 if (array_size < sizeof(iv->offset_size))
7807                         goto fail;
7808                 array_size -= sizeof(iv->offset_size);
7809                 offset = be16toh(iv->offset_size);
7810                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7811                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7812                 if (offset >= 0x1000)
7813                         goto fail;
7814                 if (bit32) {
7815                         if (array_size < sizeof(iv->data.d32))
7816                                 goto fail;
7817                         array_size -= sizeof(iv->data.d32);
7818                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7819                         iv = GET_NEXTIV32(iv);
7820                 } else {
7821
7822                         if (array_size < sizeof(iv->data.d16))
7823                                 goto fail;
7824                         array_size -= sizeof(iv->data.d16);
7825                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7826
7827                         iv = GET_NEXTIV16(iv);
7828                 }
7829         }
7830         if (array_size != 0)
7831                 goto fail;
7832         return (0);
7833 fail:
7834         device_printf(sc->sc_dev, "initvals: invalid format\n");
7835         return (EPROTO);
7836 #undef GET_NEXTIV16
7837 #undef GET_NEXTIV32
7838 }
7839
7840 static int
7841 bwn_switch_channel(struct bwn_mac *mac, int chan)
7842 {
7843         struct bwn_phy *phy = &(mac->mac_phy);
7844         struct bwn_softc *sc = mac->mac_sc;
7845         struct ieee80211com *ic = &sc->sc_ic;
7846         uint16_t channelcookie, savedcookie;
7847         int error;
7848
7849         if (chan == 0xffff)
7850                 chan = phy->get_default_chan(mac);
7851
7852         channelcookie = chan;
7853         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7854                 channelcookie |= 0x100;
7855         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7856         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7857         error = phy->switch_channel(mac, chan);
7858         if (error)
7859                 goto fail;
7860
7861         mac->mac_phy.chan = chan;
7862         DELAY(8000);
7863         return (0);
7864 fail:
7865         device_printf(sc->sc_dev, "failed to switch channel\n");
7866         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7867         return (error);
7868 }
7869
7870 static uint16_t
7871 bwn_ant2phy(int antenna)
7872 {
7873
7874         switch (antenna) {
7875         case BWN_ANT0:
7876                 return (BWN_TX_PHY_ANT0);
7877         case BWN_ANT1:
7878                 return (BWN_TX_PHY_ANT1);
7879         case BWN_ANT2:
7880                 return (BWN_TX_PHY_ANT2);
7881         case BWN_ANT3:
7882                 return (BWN_TX_PHY_ANT3);
7883         case BWN_ANTAUTO:
7884                 return (BWN_TX_PHY_ANT01AUTO);
7885         }
7886         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7887         return (0);
7888 }
7889
7890 static void
7891 bwn_wme_load(struct bwn_mac *mac)
7892 {
7893         struct bwn_softc *sc = mac->mac_sc;
7894         int i;
7895
7896         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7897             ("%s:%d: fail", __func__, __LINE__));
7898
7899         bwn_mac_suspend(mac);
7900         for (i = 0; i < N(sc->sc_wmeParams); i++)
7901                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7902                     bwn_wme_shm_offsets[i]);
7903         bwn_mac_enable(mac);
7904 }
7905
7906 static void
7907 bwn_wme_loadparams(struct bwn_mac *mac,
7908     const struct wmeParams *p, uint16_t shm_offset)
7909 {
7910 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
7911         struct bwn_softc *sc = mac->mac_sc;
7912         uint16_t params[BWN_NR_WMEPARAMS];
7913         int slot, tmp;
7914         unsigned int i;
7915
7916         slot = BWN_READ_2(mac, BWN_RNG) &
7917             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7918
7919         memset(&params, 0, sizeof(params));
7920
7921         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7922             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7923             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7924
7925         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7926         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7927         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7928         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7929         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7930         params[BWN_WMEPARAM_BSLOTS] = slot;
7931         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7932
7933         for (i = 0; i < N(params); i++) {
7934                 if (i == BWN_WMEPARAM_STATUS) {
7935                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
7936                             shm_offset + (i * 2));
7937                         tmp |= 0x100;
7938                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7939                             tmp);
7940                 } else {
7941                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7942                             params[i]);
7943                 }
7944         }
7945 }
7946
7947 static void
7948 bwn_mac_write_bssid(struct bwn_mac *mac)
7949 {
7950         struct bwn_softc *sc = mac->mac_sc;
7951         uint32_t tmp;
7952         int i;
7953         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7954
7955         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7956         memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
7957         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7958             IEEE80211_ADDR_LEN);
7959
7960         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7961                 tmp = (uint32_t) (mac_bssid[i + 0]);
7962                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7963                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7964                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7965                 bwn_ram_write(mac, 0x20 + i, tmp);
7966         }
7967 }
7968
7969 static void
7970 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7971     const uint8_t *macaddr)
7972 {
7973         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7974         uint16_t data;
7975
7976         if (!mac)
7977                 macaddr = zero;
7978
7979         offset |= 0x0020;
7980         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7981
7982         data = macaddr[0];
7983         data |= macaddr[1] << 8;
7984         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7985         data = macaddr[2];
7986         data |= macaddr[3] << 8;
7987         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7988         data = macaddr[4];
7989         data |= macaddr[5] << 8;
7990         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7991 }
7992
7993 static void
7994 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7995     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
7996 {
7997         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
7998         uint8_t per_sta_keys_start = 8;
7999
8000         if (BWN_SEC_NEWAPI(mac))
8001                 per_sta_keys_start = 4;
8002
8003         KASSERT(index < mac->mac_max_nr_keys,
8004             ("%s:%d: fail", __func__, __LINE__));
8005         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8006             ("%s:%d: fail", __func__, __LINE__));
8007
8008         if (index >= per_sta_keys_start)
8009                 bwn_key_macwrite(mac, index, NULL);
8010         if (key)
8011                 memcpy(buf, key, key_len);
8012         bwn_key_write(mac, index, algorithm, buf);
8013         if (index >= per_sta_keys_start)
8014                 bwn_key_macwrite(mac, index, mac_addr);
8015
8016         mac->mac_key[index].algorithm = algorithm;
8017 }
8018
8019 static void
8020 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8021 {
8022         struct bwn_softc *sc = mac->mac_sc;
8023         uint32_t addrtmp[2] = { 0, 0 };
8024         uint8_t start = 8;
8025
8026         if (BWN_SEC_NEWAPI(mac))
8027                 start = 4;
8028
8029         KASSERT(index >= start,
8030             ("%s:%d: fail", __func__, __LINE__));
8031         index -= start;
8032
8033         if (addr) {
8034                 addrtmp[0] = addr[0];
8035                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8036                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8037                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8038                 addrtmp[1] = addr[4];
8039                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8040         }
8041
8042         if (siba_get_revid(sc->sc_dev) >= 5) {
8043                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8044                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8045         } else {
8046                 if (index >= 8) {
8047                         bwn_shm_write_4(mac, BWN_SHARED,
8048                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8049                         bwn_shm_write_2(mac, BWN_SHARED,
8050                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8051                 }
8052         }
8053 }
8054
8055 static void
8056 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8057     const uint8_t *key)
8058 {
8059         unsigned int i;
8060         uint32_t offset;
8061         uint16_t kidx, value;
8062
8063         kidx = BWN_SEC_KEY2FW(mac, index);
8064         bwn_shm_write_2(mac, BWN_SHARED,
8065             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8066
8067         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8068         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8069                 value = key[i];
8070                 value |= (uint16_t)(key[i + 1]) << 8;
8071                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8072         }
8073 }
8074
8075 static void
8076 bwn_phy_exit(struct bwn_mac *mac)
8077 {
8078
8079         mac->mac_phy.rf_onoff(mac, 0);
8080         if (mac->mac_phy.exit != NULL)
8081                 mac->mac_phy.exit(mac);
8082 }
8083
8084 static void
8085 bwn_dma_free(struct bwn_mac *mac)
8086 {
8087         struct bwn_dma *dma;
8088
8089         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8090                 return;
8091         dma = &mac->mac_method.dma;
8092
8093         bwn_dma_ringfree(&dma->rx);
8094         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8095         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8096         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8097         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8098         bwn_dma_ringfree(&dma->mcast);
8099 }
8100
8101 static void
8102 bwn_core_stop(struct bwn_mac *mac)
8103 {
8104         struct bwn_softc *sc = mac->mac_sc;
8105
8106         BWN_ASSERT_LOCKED(sc);
8107
8108         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8109                 return;
8110
8111         callout_stop(&sc->sc_rfswitch_ch);
8112         callout_stop(&sc->sc_task_ch);
8113         callout_stop(&sc->sc_watchdog_ch);
8114         sc->sc_watchdog_timer = 0;
8115         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8116         BWN_READ_4(mac, BWN_INTR_MASK);
8117         bwn_mac_suspend(mac);
8118
8119         mac->mac_status = BWN_MAC_STATUS_INITED;
8120 }
8121
8122 static int
8123 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8124 {
8125         struct bwn_mac *up_dev = NULL;
8126         struct bwn_mac *down_dev;
8127         struct bwn_mac *mac;
8128         int err, status;
8129         uint8_t gmode;
8130
8131         BWN_ASSERT_LOCKED(sc);
8132
8133         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8134                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8135                     mac->mac_phy.supports_2ghz) {
8136                         up_dev = mac;
8137                         gmode = 1;
8138                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8139                     mac->mac_phy.supports_5ghz) {
8140                         up_dev = mac;
8141                         gmode = 0;
8142                 } else {
8143                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8144                         return (EINVAL);
8145                 }
8146                 if (up_dev != NULL)
8147                         break;
8148         }
8149         if (up_dev == NULL) {
8150                 device_printf(sc->sc_dev, "Could not find a device\n");
8151                 return (ENODEV);
8152         }
8153         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8154                 return (0);
8155
8156         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8157             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8158
8159         down_dev = sc->sc_curmac;
8160         status = down_dev->mac_status;
8161         if (status >= BWN_MAC_STATUS_STARTED)
8162                 bwn_core_stop(down_dev);
8163         if (status >= BWN_MAC_STATUS_INITED)
8164                 bwn_core_exit(down_dev);
8165
8166         if (down_dev != up_dev)
8167                 bwn_phy_reset(down_dev);
8168
8169         up_dev->mac_phy.gmode = gmode;
8170         if (status >= BWN_MAC_STATUS_INITED) {
8171                 err = bwn_core_init(up_dev);
8172                 if (err) {
8173                         device_printf(sc->sc_dev,
8174                             "fatal: failed to initialize for %s-GHz\n",
8175                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8176                         goto fail;
8177                 }
8178         }
8179         if (status >= BWN_MAC_STATUS_STARTED)
8180                 bwn_core_start(up_dev);
8181         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8182         sc->sc_curmac = up_dev;
8183
8184         return (0);
8185 fail:
8186         sc->sc_curmac = NULL;
8187         return (err);
8188 }
8189
8190 static void
8191 bwn_rf_turnon(struct bwn_mac *mac)
8192 {
8193
8194         bwn_mac_suspend(mac);
8195         mac->mac_phy.rf_onoff(mac, 1);
8196         mac->mac_phy.rf_on = 1;
8197         bwn_mac_enable(mac);
8198 }
8199
8200 static void
8201 bwn_rf_turnoff(struct bwn_mac *mac)
8202 {
8203
8204         bwn_mac_suspend(mac);
8205         mac->mac_phy.rf_onoff(mac, 0);
8206         mac->mac_phy.rf_on = 0;
8207         bwn_mac_enable(mac);
8208 }
8209
8210 static void
8211 bwn_phy_reset(struct bwn_mac *mac)
8212 {
8213         struct bwn_softc *sc = mac->mac_sc;
8214
8215         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8216             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8217              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8218         DELAY(1000);
8219         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8220             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8221             BWN_TGSLOW_PHYRESET);
8222         DELAY(1000);
8223 }
8224
8225 static int
8226 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8227 {
8228         struct bwn_vap *bvp = BWN_VAP(vap);
8229         struct ieee80211com *ic= vap->iv_ic;
8230         enum ieee80211_state ostate = vap->iv_state;
8231         struct bwn_softc *sc = ic->ic_softc;
8232         struct bwn_mac *mac = sc->sc_curmac;
8233         int error;
8234
8235         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8236             ieee80211_state_name[vap->iv_state],
8237             ieee80211_state_name[nstate]);
8238
8239         error = bvp->bv_newstate(vap, nstate, arg);
8240         if (error != 0)
8241                 return (error);
8242
8243         BWN_LOCK(sc);
8244
8245         bwn_led_newstate(mac, nstate);
8246
8247         /*
8248          * Clear the BSSID when we stop a STA
8249          */
8250         if (vap->iv_opmode == IEEE80211_M_STA) {
8251                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8252                         /*
8253                          * Clear out the BSSID.  If we reassociate to
8254                          * the same AP, this will reinialize things
8255                          * correctly...
8256                          */
8257                         if (ic->ic_opmode == IEEE80211_M_STA &&
8258                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8259                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8260                                 bwn_set_macaddr(mac);
8261                         }
8262                 }
8263         }
8264
8265         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8266             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8267                 /* XXX nothing to do? */
8268         } else if (nstate == IEEE80211_S_RUN) {
8269                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8270                 bwn_set_opmode(mac);
8271                 bwn_set_pretbtt(mac);
8272                 bwn_spu_setdelay(mac, 0);
8273                 bwn_set_macaddr(mac);
8274         }
8275
8276         BWN_UNLOCK(sc);
8277
8278         return (error);
8279 }
8280
8281 static void
8282 bwn_set_pretbtt(struct bwn_mac *mac)
8283 {
8284         struct bwn_softc *sc = mac->mac_sc;
8285         struct ieee80211com *ic = &sc->sc_ic;
8286         uint16_t pretbtt;
8287
8288         if (ic->ic_opmode == IEEE80211_M_IBSS)
8289                 pretbtt = 2;
8290         else
8291                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8292         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8293         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8294 }
8295
8296 static int
8297 bwn_intr(void *arg)
8298 {
8299         struct bwn_mac *mac = arg;
8300         struct bwn_softc *sc = mac->mac_sc;
8301         uint32_t reason;
8302
8303         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8304             (sc->sc_flags & BWN_FLAG_INVALID))
8305                 return (FILTER_STRAY);
8306
8307         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8308         if (reason == 0xffffffff)       /* shared IRQ */
8309                 return (FILTER_STRAY);
8310         reason &= mac->mac_intr_mask;
8311         if (reason == 0)
8312                 return (FILTER_HANDLED);
8313
8314         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8315         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8316         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8317         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8318         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8319         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8320         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8321         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8322         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8323         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8324         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8325
8326         /* Disable interrupts. */
8327         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8328
8329         mac->mac_reason_intr = reason;
8330
8331         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8332         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8333
8334         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8335         return (FILTER_HANDLED);
8336 }
8337
8338 static void
8339 bwn_intrtask(void *arg, int npending)
8340 {
8341         struct bwn_mac *mac = arg;
8342         struct bwn_softc *sc = mac->mac_sc;
8343         uint32_t merged = 0;
8344         int i, tx = 0, rx = 0;
8345
8346         BWN_LOCK(sc);
8347         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8348             (sc->sc_flags & BWN_FLAG_INVALID)) {
8349                 BWN_UNLOCK(sc);
8350                 return;
8351         }
8352
8353         for (i = 0; i < N(mac->mac_reason); i++)
8354                 merged |= mac->mac_reason[i];
8355
8356         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8357                 device_printf(sc->sc_dev, "MAC trans error\n");
8358
8359         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8360                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8361                 mac->mac_phy.txerrors--;
8362                 if (mac->mac_phy.txerrors == 0) {
8363                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8364                         bwn_restart(mac, "PHY TX errors");
8365                 }
8366         }
8367
8368         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8369                 if (merged & BWN_DMAINTR_FATALMASK) {
8370                         device_printf(sc->sc_dev,
8371                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8372                             mac->mac_reason[0], mac->mac_reason[1],
8373                             mac->mac_reason[2], mac->mac_reason[3],
8374                             mac->mac_reason[4], mac->mac_reason[5]);
8375                         bwn_restart(mac, "DMA error");
8376                         BWN_UNLOCK(sc);
8377                         return;
8378                 }
8379                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8380                         device_printf(sc->sc_dev,
8381                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8382                             mac->mac_reason[0], mac->mac_reason[1],
8383                             mac->mac_reason[2], mac->mac_reason[3],
8384                             mac->mac_reason[4], mac->mac_reason[5]);
8385                 }
8386         }
8387
8388         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8389                 bwn_intr_ucode_debug(mac);
8390         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8391                 bwn_intr_tbtt_indication(mac);
8392         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8393                 bwn_intr_atim_end(mac);
8394         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8395                 bwn_intr_beacon(mac);
8396         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8397                 bwn_intr_pmq(mac);
8398         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8399                 bwn_intr_noise(mac);
8400
8401         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8402                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8403                         bwn_dma_rx(mac->mac_method.dma.rx);
8404                         rx = 1;
8405                 }
8406         } else
8407                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8408
8409         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8410         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8411         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8412         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8413         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8414
8415         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8416                 bwn_intr_txeof(mac);
8417                 tx = 1;
8418         }
8419
8420         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8421
8422         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8423                 int evt = BWN_LED_EVENT_NONE;
8424
8425                 if (tx && rx) {
8426                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8427                                 evt = BWN_LED_EVENT_RX;
8428                         else
8429                                 evt = BWN_LED_EVENT_TX;
8430                 } else if (tx) {
8431                         evt = BWN_LED_EVENT_TX;
8432                 } else if (rx) {
8433                         evt = BWN_LED_EVENT_RX;
8434                 } else if (rx == 0) {
8435                         evt = BWN_LED_EVENT_POLL;
8436                 }
8437
8438                 if (evt != BWN_LED_EVENT_NONE)
8439                         bwn_led_event(mac, evt);
8440        }
8441
8442         if (mbufq_first(&sc->sc_snd) != NULL)
8443                 bwn_start(sc);
8444
8445         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8446         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8447
8448         BWN_UNLOCK(sc);
8449 }
8450
8451 static void
8452 bwn_restart(struct bwn_mac *mac, const char *msg)
8453 {
8454         struct bwn_softc *sc = mac->mac_sc;
8455         struct ieee80211com *ic = &sc->sc_ic;
8456
8457         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8458                 return;
8459
8460         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8461         ieee80211_runtask(ic, &mac->mac_hwreset);
8462 }
8463
8464 static void
8465 bwn_intr_ucode_debug(struct bwn_mac *mac)
8466 {
8467         struct bwn_softc *sc = mac->mac_sc;
8468         uint16_t reason;
8469
8470         if (mac->mac_fw.opensource == 0)
8471                 return;
8472
8473         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8474         switch (reason) {
8475         case BWN_DEBUGINTR_PANIC:
8476                 bwn_handle_fwpanic(mac);
8477                 break;
8478         case BWN_DEBUGINTR_DUMP_SHM:
8479                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8480                 break;
8481         case BWN_DEBUGINTR_DUMP_REGS:
8482                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8483                 break;
8484         case BWN_DEBUGINTR_MARKER:
8485                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8486                 break;
8487         default:
8488                 device_printf(sc->sc_dev,
8489                     "ucode debug unknown reason: %#x\n", reason);
8490         }
8491
8492         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8493             BWN_DEBUGINTR_ACK);
8494 }
8495
8496 static void
8497 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8498 {
8499         struct bwn_softc *sc = mac->mac_sc;
8500         struct ieee80211com *ic = &sc->sc_ic;
8501
8502         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8503                 bwn_psctl(mac, 0);
8504         if (ic->ic_opmode == IEEE80211_M_IBSS)
8505                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8506 }
8507
8508 static void
8509 bwn_intr_atim_end(struct bwn_mac *mac)
8510 {
8511
8512         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8513                 BWN_WRITE_4(mac, BWN_MACCMD,
8514                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8515                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8516         }
8517 }
8518
8519 static void
8520 bwn_intr_beacon(struct bwn_mac *mac)
8521 {
8522         struct bwn_softc *sc = mac->mac_sc;
8523         struct ieee80211com *ic = &sc->sc_ic;
8524         uint32_t cmd, beacon0, beacon1;
8525
8526         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8527             ic->ic_opmode == IEEE80211_M_MBSS)
8528                 return;
8529
8530         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8531
8532         cmd = BWN_READ_4(mac, BWN_MACCMD);
8533         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8534         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8535
8536         if (beacon0 && beacon1) {
8537                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8538                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8539                 return;
8540         }
8541
8542         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8543                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8544                 bwn_load_beacon0(mac);
8545                 bwn_load_beacon1(mac);
8546                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8547                 cmd |= BWN_MACCMD_BEACON0_VALID;
8548                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8549         } else {
8550                 if (!beacon0) {
8551                         bwn_load_beacon0(mac);
8552                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8553                         cmd |= BWN_MACCMD_BEACON0_VALID;
8554                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8555                 } else if (!beacon1) {
8556                         bwn_load_beacon1(mac);
8557                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8558                         cmd |= BWN_MACCMD_BEACON1_VALID;
8559                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8560                 }
8561         }
8562 }
8563
8564 static void
8565 bwn_intr_pmq(struct bwn_mac *mac)
8566 {
8567         uint32_t tmp;
8568
8569         while (1) {
8570                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8571                 if (!(tmp & 0x00000008))
8572                         break;
8573         }
8574         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8575 }
8576
8577 static void
8578 bwn_intr_noise(struct bwn_mac *mac)
8579 {
8580         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8581         uint16_t tmp;
8582         uint8_t noise[4];
8583         uint8_t i, j;
8584         int32_t average;
8585
8586         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8587                 return;
8588
8589         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8590         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8591         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8592             noise[3] == 0x7f)
8593                 goto new;
8594
8595         KASSERT(mac->mac_noise.noi_nsamples < 8,
8596             ("%s:%d: fail", __func__, __LINE__));
8597         i = mac->mac_noise.noi_nsamples;
8598         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8599         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8600         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8601         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8602         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8603         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8604         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8605         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8606         mac->mac_noise.noi_nsamples++;
8607         if (mac->mac_noise.noi_nsamples == 8) {
8608                 average = 0;
8609                 for (i = 0; i < 8; i++) {
8610                         for (j = 0; j < 4; j++)
8611                                 average += mac->mac_noise.noi_samples[i][j];
8612                 }
8613                 average = (((average / 32) * 125) + 64) / 128;
8614                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8615                 if (tmp >= 8)
8616                         average += 2;
8617                 else
8618                         average -= 25;
8619                 average -= (tmp == 8) ? 72 : 48;
8620
8621                 mac->mac_stats.link_noise = average;
8622                 mac->mac_noise.noi_running = 0;
8623                 return;
8624         }
8625 new:
8626         bwn_noise_gensample(mac);
8627 }
8628
8629 static int
8630 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8631 {
8632         struct bwn_mac *mac = prq->prq_mac;
8633         struct bwn_softc *sc = mac->mac_sc;
8634         unsigned int i;
8635
8636         BWN_ASSERT_LOCKED(sc);
8637
8638         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8639                 return (0);
8640
8641         for (i = 0; i < 5000; i++) {
8642                 if (bwn_pio_rxeof(prq) == 0)
8643                         break;
8644         }
8645         if (i >= 5000)
8646                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8647         return ((i > 0) ? 1 : 0);
8648 }
8649
8650 static void
8651 bwn_dma_rx(struct bwn_dma_ring *dr)
8652 {
8653         int slot, curslot;
8654
8655         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8656         curslot = dr->get_curslot(dr);
8657         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8658             ("%s:%d: fail", __func__, __LINE__));
8659
8660         slot = dr->dr_curslot;
8661         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8662                 bwn_dma_rxeof(dr, &slot);
8663
8664         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8665             BUS_DMASYNC_PREWRITE);
8666
8667         dr->set_curslot(dr, slot);
8668         dr->dr_curslot = slot;
8669 }
8670
8671 static void
8672 bwn_intr_txeof(struct bwn_mac *mac)
8673 {
8674         struct bwn_txstatus stat;
8675         uint32_t stat0, stat1;
8676         uint16_t tmp;
8677
8678         BWN_ASSERT_LOCKED(mac->mac_sc);
8679
8680         while (1) {
8681                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8682                 if (!(stat0 & 0x00000001))
8683                         break;
8684                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8685
8686                 stat.cookie = (stat0 >> 16);
8687                 stat.seq = (stat1 & 0x0000ffff);
8688                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8689                 tmp = (stat0 & 0x0000ffff);
8690                 stat.framecnt = ((tmp & 0xf000) >> 12);
8691                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8692                 stat.sreason = ((tmp & 0x001c) >> 2);
8693                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8694                 stat.im = (tmp & 0x0040) ? 1 : 0;
8695                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8696                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8697
8698                 bwn_handle_txeof(mac, &stat);
8699         }
8700 }
8701
8702 static void
8703 bwn_hwreset(void *arg, int npending)
8704 {
8705         struct bwn_mac *mac = arg;
8706         struct bwn_softc *sc = mac->mac_sc;
8707         int error = 0;
8708         int prev_status;
8709
8710         BWN_LOCK(sc);
8711
8712         prev_status = mac->mac_status;
8713         if (prev_status >= BWN_MAC_STATUS_STARTED)
8714                 bwn_core_stop(mac);
8715         if (prev_status >= BWN_MAC_STATUS_INITED)
8716                 bwn_core_exit(mac);
8717
8718         if (prev_status >= BWN_MAC_STATUS_INITED) {
8719                 error = bwn_core_init(mac);
8720                 if (error)
8721                         goto out;
8722         }
8723         if (prev_status >= BWN_MAC_STATUS_STARTED)
8724                 bwn_core_start(mac);
8725 out:
8726         if (error) {
8727                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8728                 sc->sc_curmac = NULL;
8729         }
8730         BWN_UNLOCK(sc);
8731 }
8732
8733 static void
8734 bwn_handle_fwpanic(struct bwn_mac *mac)
8735 {
8736         struct bwn_softc *sc = mac->mac_sc;
8737         uint16_t reason;
8738
8739         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8740         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8741
8742         if (reason == BWN_FWPANIC_RESTART)
8743                 bwn_restart(mac, "ucode panic");
8744 }
8745
8746 static void
8747 bwn_load_beacon0(struct bwn_mac *mac)
8748 {
8749
8750         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8751 }
8752
8753 static void
8754 bwn_load_beacon1(struct bwn_mac *mac)
8755 {
8756
8757         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8758 }
8759
8760 static uint32_t
8761 bwn_jssi_read(struct bwn_mac *mac)
8762 {
8763         uint32_t val = 0;
8764
8765         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8766         val <<= 16;
8767         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8768
8769         return (val);
8770 }
8771
8772 static void
8773 bwn_noise_gensample(struct bwn_mac *mac)
8774 {
8775         uint32_t jssi = 0x7f7f7f7f;
8776
8777         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8778         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8779         BWN_WRITE_4(mac, BWN_MACCMD,
8780             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8781 }
8782
8783 static int
8784 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8785 {
8786         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8787
8788         return (dr->dr_numslots - dr->dr_usedslot);
8789 }
8790
8791 static int
8792 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8793 {
8794         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8795
8796         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8797             ("%s:%d: fail", __func__, __LINE__));
8798         if (slot == dr->dr_numslots - 1)
8799                 return (0);
8800         return (slot + 1);
8801 }
8802
8803 static void
8804 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8805 {
8806         struct bwn_mac *mac = dr->dr_mac;
8807         struct bwn_softc *sc = mac->mac_sc;
8808         struct bwn_dma *dma = &mac->mac_method.dma;
8809         struct bwn_dmadesc_generic *desc;
8810         struct bwn_dmadesc_meta *meta;
8811         struct bwn_rxhdr4 *rxhdr;
8812         struct mbuf *m;
8813         uint32_t macstat;
8814         int32_t tmp;
8815         int cnt = 0;
8816         uint16_t len;
8817
8818         dr->getdesc(dr, *slot, &desc, &meta);
8819
8820         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8821         m = meta->mt_m;
8822
8823         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8824                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8825                 return;
8826         }
8827
8828         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8829         len = le16toh(rxhdr->frame_len);
8830         if (len <= 0) {
8831                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8832                 return;
8833         }
8834         if (bwn_dma_check_redzone(dr, m)) {
8835                 device_printf(sc->sc_dev, "redzone error.\n");
8836                 bwn_dma_set_redzone(dr, m);
8837                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8838                     BUS_DMASYNC_PREWRITE);
8839                 return;
8840         }
8841         if (len > dr->dr_rx_bufsize) {
8842                 tmp = len;
8843                 while (1) {
8844                         dr->getdesc(dr, *slot, &desc, &meta);
8845                         bwn_dma_set_redzone(dr, meta->mt_m);
8846                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8847                             BUS_DMASYNC_PREWRITE);
8848                         *slot = bwn_dma_nextslot(dr, *slot);
8849                         cnt++;
8850                         tmp -= dr->dr_rx_bufsize;
8851                         if (tmp <= 0)
8852                                 break;
8853                 }
8854                 device_printf(sc->sc_dev, "too small buffer "
8855                        "(len %u buffer %u dropped %d)\n",
8856                        len, dr->dr_rx_bufsize, cnt);
8857                 return;
8858         }
8859         macstat = le32toh(rxhdr->mac_status);
8860         if (macstat & BWN_RX_MAC_FCSERR) {
8861                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8862                         device_printf(sc->sc_dev, "RX drop\n");
8863                         return;
8864                 }
8865         }
8866
8867         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8868         m_adj(m, dr->dr_frameoffset);
8869
8870         bwn_rxeof(dr->dr_mac, m, rxhdr);
8871 }
8872
8873 static void
8874 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8875 {
8876         struct bwn_dma_ring *dr;
8877         struct bwn_dmadesc_generic *desc;
8878         struct bwn_dmadesc_meta *meta;
8879         struct bwn_pio_txqueue *tq;
8880         struct bwn_pio_txpkt *tp = NULL;
8881         struct bwn_softc *sc = mac->mac_sc;
8882         struct bwn_stats *stats = &mac->mac_stats;
8883         struct ieee80211_node *ni;
8884         struct ieee80211vap *vap;
8885         int retrycnt = 0, slot;
8886
8887         BWN_ASSERT_LOCKED(mac->mac_sc);
8888
8889         if (status->im)
8890                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8891         if (status->ampdu)
8892                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8893         if (status->rtscnt) {
8894                 if (status->rtscnt == 0xf)
8895                         stats->rtsfail++;
8896                 else
8897                         stats->rts++;
8898         }
8899
8900         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8901                 if (status->ack) {
8902                         dr = bwn_dma_parse_cookie(mac, status,
8903                             status->cookie, &slot);
8904                         if (dr == NULL) {
8905                                 device_printf(sc->sc_dev,
8906                                     "failed to parse cookie\n");
8907                                 return;
8908                         }
8909                         while (1) {
8910                                 dr->getdesc(dr, slot, &desc, &meta);
8911                                 if (meta->mt_islast) {
8912                                         ni = meta->mt_ni;
8913                                         vap = ni->ni_vap;
8914                                         ieee80211_ratectl_tx_complete(vap, ni,
8915                                             status->ack ?
8916                                               IEEE80211_RATECTL_TX_SUCCESS :
8917                                               IEEE80211_RATECTL_TX_FAILURE,
8918                                             &retrycnt, 0);
8919                                         break;
8920                                 }
8921                                 slot = bwn_dma_nextslot(dr, slot);
8922                         }
8923                 }
8924                 bwn_dma_handle_txeof(mac, status);
8925         } else {
8926                 if (status->ack) {
8927                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8928                         if (tq == NULL) {
8929                                 device_printf(sc->sc_dev,
8930                                     "failed to parse cookie\n");
8931                                 return;
8932                         }
8933                         ni = tp->tp_ni;
8934                         vap = ni->ni_vap;
8935                         ieee80211_ratectl_tx_complete(vap, ni,
8936                             status->ack ?
8937                               IEEE80211_RATECTL_TX_SUCCESS :
8938                               IEEE80211_RATECTL_TX_FAILURE,
8939                             &retrycnt, 0);
8940                 }
8941                 bwn_pio_handle_txeof(mac, status);
8942         }
8943
8944         bwn_phy_txpower_check(mac, 0);
8945 }
8946
8947 static uint8_t
8948 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8949 {
8950         struct bwn_mac *mac = prq->prq_mac;
8951         struct bwn_softc *sc = mac->mac_sc;
8952         struct bwn_rxhdr4 rxhdr;
8953         struct mbuf *m;
8954         uint32_t ctl32, macstat, v32;
8955         unsigned int i, padding;
8956         uint16_t ctl16, len, totlen, v16;
8957         unsigned char *mp;
8958         char *data;
8959
8960         memset(&rxhdr, 0, sizeof(rxhdr));
8961
8962         if (prq->prq_rev >= 8) {
8963                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8964                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8965                         return (0);
8966                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8967                     BWN_PIO8_RXCTL_FRAMEREADY);
8968                 for (i = 0; i < 10; i++) {
8969                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8970                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8971                                 goto ready;
8972                         DELAY(10);
8973                 }
8974         } else {
8975                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8976                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8977                         return (0);
8978                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8979                     BWN_PIO_RXCTL_FRAMEREADY);
8980                 for (i = 0; i < 10; i++) {
8981                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8982                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8983                                 goto ready;
8984                         DELAY(10);
8985                 }
8986         }
8987         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8988         return (1);
8989 ready:
8990         if (prq->prq_rev >= 8)
8991                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8992                     prq->prq_base + BWN_PIO8_RXDATA);
8993         else
8994                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8995                     prq->prq_base + BWN_PIO_RXDATA);
8996         len = le16toh(rxhdr.frame_len);
8997         if (len > 0x700) {
8998                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
8999                 goto error;
9000         }
9001         if (len == 0) {
9002                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9003                 goto error;
9004         }
9005
9006         macstat = le32toh(rxhdr.mac_status);
9007         if (macstat & BWN_RX_MAC_FCSERR) {
9008                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9009                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9010                         goto error;
9011                 }
9012         }
9013
9014         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9015         totlen = len + padding;
9016         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9017         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9018         if (m == NULL) {
9019                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9020                 goto error;
9021         }
9022         mp = mtod(m, unsigned char *);
9023         if (prq->prq_rev >= 8) {
9024                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9025                     prq->prq_base + BWN_PIO8_RXDATA);
9026                 if (totlen & 3) {
9027                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9028                         data = &(mp[totlen - 1]);
9029                         switch (totlen & 3) {
9030                         case 3:
9031                                 *data = (v32 >> 16);
9032                                 data--;
9033                         case 2:
9034                                 *data = (v32 >> 8);
9035                                 data--;
9036                         case 1:
9037                                 *data = v32;
9038                         }
9039                 }
9040         } else {
9041                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9042                     prq->prq_base + BWN_PIO_RXDATA);
9043                 if (totlen & 1) {
9044                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9045                         mp[totlen - 1] = v16;
9046                 }
9047         }
9048
9049         m->m_len = m->m_pkthdr.len = totlen;
9050
9051         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9052
9053         return (1);
9054 error:
9055         if (prq->prq_rev >= 8)
9056                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9057                     BWN_PIO8_RXCTL_DATAREADY);
9058         else
9059                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9060         return (1);
9061 }
9062
9063 static int
9064 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9065     struct bwn_dmadesc_meta *meta, int init)
9066 {
9067         struct bwn_mac *mac = dr->dr_mac;
9068         struct bwn_dma *dma = &mac->mac_method.dma;
9069         struct bwn_rxhdr4 *hdr;
9070         bus_dmamap_t map;
9071         bus_addr_t paddr;
9072         struct mbuf *m;
9073         int error;
9074
9075         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9076         if (m == NULL) {
9077                 error = ENOBUFS;
9078
9079                 /*
9080                  * If the NIC is up and running, we need to:
9081                  * - Clear RX buffer's header.
9082                  * - Restore RX descriptor settings.
9083                  */
9084                 if (init)
9085                         return (error);
9086                 else
9087                         goto back;
9088         }
9089         m->m_len = m->m_pkthdr.len = MCLBYTES;
9090
9091         bwn_dma_set_redzone(dr, m);
9092
9093         /*
9094          * Try to load RX buf into temporary DMA map
9095          */
9096         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9097             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9098         if (error) {
9099                 m_freem(m);
9100
9101                 /*
9102                  * See the comment above
9103                  */
9104                 if (init)
9105                         return (error);
9106                 else
9107                         goto back;
9108         }
9109
9110         if (!init)
9111                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9112         meta->mt_m = m;
9113         meta->mt_paddr = paddr;
9114
9115         /*
9116          * Swap RX buf's DMA map with the loaded temporary one
9117          */
9118         map = meta->mt_dmap;
9119         meta->mt_dmap = dr->dr_spare_dmap;
9120         dr->dr_spare_dmap = map;
9121
9122 back:
9123         /*
9124          * Clear RX buf header
9125          */
9126         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9127         bzero(hdr, sizeof(*hdr));
9128         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9129             BUS_DMASYNC_PREWRITE);
9130
9131         /*
9132          * Setup RX buf descriptor
9133          */
9134         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9135             sizeof(*hdr), 0, 0, 0);
9136         return (error);
9137 }
9138
9139 static void
9140 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9141                  bus_size_t mapsz __unused, int error)
9142 {
9143
9144         if (!error) {
9145                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9146                 *((bus_addr_t *)arg) = seg->ds_addr;
9147         }
9148 }
9149
9150 static int
9151 bwn_hwrate2ieeerate(int rate)
9152 {
9153
9154         switch (rate) {
9155         case BWN_CCK_RATE_1MB:
9156                 return (2);
9157         case BWN_CCK_RATE_2MB:
9158                 return (4);
9159         case BWN_CCK_RATE_5MB:
9160                 return (11);
9161         case BWN_CCK_RATE_11MB:
9162                 return (22);
9163         case BWN_OFDM_RATE_6MB:
9164                 return (12);
9165         case BWN_OFDM_RATE_9MB:
9166                 return (18);
9167         case BWN_OFDM_RATE_12MB:
9168                 return (24);
9169         case BWN_OFDM_RATE_18MB:
9170                 return (36);
9171         case BWN_OFDM_RATE_24MB:
9172                 return (48);
9173         case BWN_OFDM_RATE_36MB:
9174                 return (72);
9175         case BWN_OFDM_RATE_48MB:
9176                 return (96);
9177         case BWN_OFDM_RATE_54MB:
9178                 return (108);
9179         default:
9180                 printf("Ooops\n");
9181                 return (0);
9182         }
9183 }
9184
9185 static void
9186 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9187 {
9188         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9189         struct bwn_plcp6 *plcp;
9190         struct bwn_softc *sc = mac->mac_sc;
9191         struct ieee80211_frame_min *wh;
9192         struct ieee80211_node *ni;
9193         struct ieee80211com *ic = &sc->sc_ic;
9194         uint32_t macstat;
9195         int padding, rate, rssi = 0, noise = 0, type;
9196         uint16_t phytype, phystat0, phystat3, chanstat;
9197         unsigned char *mp = mtod(m, unsigned char *);
9198         static int rx_mac_dec_rpt = 0;
9199
9200         BWN_ASSERT_LOCKED(sc);
9201
9202         phystat0 = le16toh(rxhdr->phy_status0);
9203         phystat3 = le16toh(rxhdr->phy_status3);
9204         macstat = le32toh(rxhdr->mac_status);
9205         chanstat = le16toh(rxhdr->channel);
9206         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9207
9208         if (macstat & BWN_RX_MAC_FCSERR)
9209                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9210         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9211                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9212         if (macstat & BWN_RX_MAC_DECERR)
9213                 goto drop;
9214
9215         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9216         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9217                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9218                     m->m_pkthdr.len);
9219                 goto drop;
9220         }
9221         plcp = (struct bwn_plcp6 *)(mp + padding);
9222         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9223         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9224                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9225                     m->m_pkthdr.len);
9226                 goto drop;
9227         }
9228         wh = mtod(m, struct ieee80211_frame_min *);
9229
9230         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9231                 device_printf(sc->sc_dev,
9232                     "RX decryption attempted (old %d keyidx %#x)\n",
9233                     BWN_ISOLDFMT(mac),
9234                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9235
9236         /* XXX calculating RSSI & noise & antenna */
9237
9238         if (phystat0 & BWN_RX_PHYST0_OFDM)
9239                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9240                     phytype == BWN_PHYTYPE_A);
9241         else
9242                 rate = bwn_plcp_get_cckrate(mac, plcp);
9243         if (rate == -1) {
9244                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9245                         goto drop;
9246         }
9247         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9248
9249         /* RX radio tap */
9250         if (ieee80211_radiotap_active(ic))
9251                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9252         m_adj(m, -IEEE80211_CRC_LEN);
9253
9254         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9255         noise = mac->mac_stats.link_noise;
9256
9257         BWN_UNLOCK(sc);
9258
9259         ni = ieee80211_find_rxnode(ic, wh);
9260         if (ni != NULL) {
9261                 type = ieee80211_input(ni, m, rssi, noise);
9262                 ieee80211_free_node(ni);
9263         } else
9264                 type = ieee80211_input_all(ic, m, rssi, noise);
9265
9266         BWN_LOCK(sc);
9267         return;
9268 drop:
9269         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9270 }
9271
9272 static void
9273 bwn_dma_handle_txeof(struct bwn_mac *mac,
9274     const struct bwn_txstatus *status)
9275 {
9276         struct bwn_dma *dma = &mac->mac_method.dma;
9277         struct bwn_dma_ring *dr;
9278         struct bwn_dmadesc_generic *desc;
9279         struct bwn_dmadesc_meta *meta;
9280         struct bwn_softc *sc = mac->mac_sc;
9281         int slot;
9282
9283         BWN_ASSERT_LOCKED(sc);
9284
9285         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9286         if (dr == NULL) {
9287                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9288                 return;
9289         }
9290         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9291
9292         while (1) {
9293                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9294                     ("%s:%d: fail", __func__, __LINE__));
9295                 dr->getdesc(dr, slot, &desc, &meta);
9296
9297                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9298                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9299                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9300                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9301
9302                 if (meta->mt_islast) {
9303                         KASSERT(meta->mt_m != NULL,
9304                             ("%s:%d: fail", __func__, __LINE__));
9305
9306                         ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
9307                         meta->mt_ni = NULL;
9308                         meta->mt_m = NULL;
9309                 } else
9310                         KASSERT(meta->mt_m == NULL,
9311                             ("%s:%d: fail", __func__, __LINE__));
9312
9313                 dr->dr_usedslot--;
9314                 if (meta->mt_islast)
9315                         break;
9316                 slot = bwn_dma_nextslot(dr, slot);
9317         }
9318         sc->sc_watchdog_timer = 0;
9319         if (dr->dr_stop) {
9320                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9321                     ("%s:%d: fail", __func__, __LINE__));
9322                 dr->dr_stop = 0;
9323         }
9324 }
9325
9326 static void
9327 bwn_pio_handle_txeof(struct bwn_mac *mac,
9328     const struct bwn_txstatus *status)
9329 {
9330         struct bwn_pio_txqueue *tq;
9331         struct bwn_pio_txpkt *tp = NULL;
9332         struct bwn_softc *sc = mac->mac_sc;
9333
9334         BWN_ASSERT_LOCKED(sc);
9335
9336         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9337         if (tq == NULL)
9338                 return;
9339
9340         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9341         tq->tq_free++;
9342
9343         if (tp->tp_ni != NULL) {
9344                 /*
9345                  * Do any tx complete callback.  Note this must
9346                  * be done before releasing the node reference.
9347                  */
9348                 if (tp->tp_m->m_flags & M_TXCB)
9349                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9350                 ieee80211_free_node(tp->tp_ni);
9351                 tp->tp_ni = NULL;
9352         }
9353         m_freem(tp->tp_m);
9354         tp->tp_m = NULL;
9355         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9356
9357         sc->sc_watchdog_timer = 0;
9358 }
9359
9360 static void
9361 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9362 {
9363         struct bwn_softc *sc = mac->mac_sc;
9364         struct bwn_phy *phy = &mac->mac_phy;
9365         struct ieee80211com *ic = &sc->sc_ic;
9366         unsigned long now;
9367         int result;
9368
9369         BWN_GETTIME(now);
9370
9371         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9372                 return;
9373         phy->nexttime = now + 2 * 1000;
9374
9375         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9376             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9377                 return;
9378
9379         if (phy->recalc_txpwr != NULL) {
9380                 result = phy->recalc_txpwr(mac,
9381                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9382                 if (result == BWN_TXPWR_RES_DONE)
9383                         return;
9384                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9385                     ("%s: fail", __func__));
9386                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9387
9388                 ieee80211_runtask(ic, &mac->mac_txpower);
9389         }
9390 }
9391
9392 static uint16_t
9393 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9394 {
9395
9396         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9397 }
9398
9399 static uint32_t
9400 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9401 {
9402
9403         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9404 }
9405
9406 static void
9407 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9408 {
9409
9410         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9411 }
9412
9413 static void
9414 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9415 {
9416
9417         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9418 }
9419
9420 static int
9421 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9422 {
9423
9424         switch (rate) {
9425         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9426         case 12:
9427                 return (BWN_OFDM_RATE_6MB);
9428         case 18:
9429                 return (BWN_OFDM_RATE_9MB);
9430         case 24:
9431                 return (BWN_OFDM_RATE_12MB);
9432         case 36:
9433                 return (BWN_OFDM_RATE_18MB);
9434         case 48:
9435                 return (BWN_OFDM_RATE_24MB);
9436         case 72:
9437                 return (BWN_OFDM_RATE_36MB);
9438         case 96:
9439                 return (BWN_OFDM_RATE_48MB);
9440         case 108:
9441                 return (BWN_OFDM_RATE_54MB);
9442         /* CCK rates (NB: not IEEE std, device-specific) */
9443         case 2:
9444                 return (BWN_CCK_RATE_1MB);
9445         case 4:
9446                 return (BWN_CCK_RATE_2MB);
9447         case 11:
9448                 return (BWN_CCK_RATE_5MB);
9449         case 22:
9450                 return (BWN_CCK_RATE_11MB);
9451         }
9452
9453         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9454         return (BWN_CCK_RATE_1MB);
9455 }
9456
9457 static int
9458 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9459     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9460 {
9461         const struct bwn_phy *phy = &mac->mac_phy;
9462         struct bwn_softc *sc = mac->mac_sc;
9463         struct ieee80211_frame *wh;
9464         struct ieee80211_frame *protwh;
9465         struct ieee80211_frame_cts *cts;
9466         struct ieee80211_frame_rts *rts;
9467         const struct ieee80211_txparam *tp;
9468         struct ieee80211vap *vap = ni->ni_vap;
9469         struct ieee80211com *ic = &sc->sc_ic;
9470         struct mbuf *mprot;
9471         unsigned int len;
9472         uint32_t macctl = 0;
9473         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9474         uint16_t phyctl = 0;
9475         uint8_t rate, rate_fb;
9476
9477         wh = mtod(m, struct ieee80211_frame *);
9478         memset(txhdr, 0, sizeof(*txhdr));
9479
9480         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9481         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9482         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9483
9484         /*
9485          * Find TX rate
9486          */
9487         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9488         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9489                 rate = rate_fb = tp->mgmtrate;
9490         else if (ismcast)
9491                 rate = rate_fb = tp->mcastrate;
9492         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9493                 rate = rate_fb = tp->ucastrate;
9494         else {
9495                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9496                 rate = ni->ni_txrate;
9497
9498                 if (rix > 0)
9499                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9500                             IEEE80211_RATE_VAL;
9501                 else
9502                         rate_fb = rate;
9503         }
9504
9505         sc->sc_tx_rate = rate;
9506
9507         rate = bwn_ieeerate2hwrate(sc, rate);
9508         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9509
9510         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9511             bwn_plcp_getcck(rate);
9512         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9513         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9514
9515         if ((rate_fb == rate) ||
9516             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9517             (*(u_int16_t *)wh->i_dur == htole16(0)))
9518                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9519         else
9520                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9521                     m->m_pkthdr.len, rate, isshort);
9522
9523         /* XXX TX encryption */
9524         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9525             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9526             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9527             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9528         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9529             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9530
9531         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9532             BWN_TX_EFT_FB_CCK;
9533         txhdr->chan = phy->chan;
9534         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9535             BWN_TX_PHY_ENC_CCK;
9536         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9537              rate == BWN_CCK_RATE_11MB))
9538                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9539
9540         /* XXX TX antenna selection */
9541
9542         switch (bwn_antenna_sanitize(mac, 0)) {
9543         case 0:
9544                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9545                 break;
9546         case 1:
9547                 phyctl |= BWN_TX_PHY_ANT0;
9548                 break;
9549         case 2:
9550                 phyctl |= BWN_TX_PHY_ANT1;
9551                 break;
9552         case 3:
9553                 phyctl |= BWN_TX_PHY_ANT2;
9554                 break;
9555         case 4:
9556                 phyctl |= BWN_TX_PHY_ANT3;
9557                 break;
9558         default:
9559                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9560         }
9561
9562         if (!ismcast)
9563                 macctl |= BWN_TX_MAC_ACK;
9564
9565         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9566         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9567             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9568                 macctl |= BWN_TX_MAC_LONGFRAME;
9569
9570         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9571                 /* XXX RTS rate is always 1MB??? */
9572                 rts_rate = BWN_CCK_RATE_1MB;
9573                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9574
9575                 protdur = ieee80211_compute_duration(ic->ic_rt,
9576                     m->m_pkthdr.len, rate, isshort) +
9577                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9578
9579                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9580                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9581                             (txhdr->body.old.rts_frame) :
9582                             (txhdr->body.new.rts_frame));
9583                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9584                             protdur);
9585                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9586                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9587                             mprot->m_pkthdr.len);
9588                         m_freem(mprot);
9589                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9590                         len = sizeof(struct ieee80211_frame_cts);
9591                 } else {
9592                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9593                             (txhdr->body.old.rts_frame) :
9594                             (txhdr->body.new.rts_frame));
9595                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9596                             isshort);
9597                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9598                             wh->i_addr2, protdur);
9599                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9600                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9601                             mprot->m_pkthdr.len);
9602                         m_freem(mprot);
9603                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9604                         len = sizeof(struct ieee80211_frame_rts);
9605                 }
9606                 len += IEEE80211_CRC_LEN;
9607                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9608                     &txhdr->body.old.rts_plcp :
9609                     &txhdr->body.new.rts_plcp), len, rts_rate);
9610                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9611                     rts_rate_fb);
9612
9613                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9614                     (&txhdr->body.old.rts_frame) :
9615                     (&txhdr->body.new.rts_frame));
9616                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9617
9618                 if (BWN_ISOFDMRATE(rts_rate)) {
9619                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9620                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9621                 } else {
9622                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9623                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9624                 }
9625                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9626                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9627         }
9628
9629         if (BWN_ISOLDFMT(mac))
9630                 txhdr->body.old.cookie = htole16(cookie);
9631         else
9632                 txhdr->body.new.cookie = htole16(cookie);
9633
9634         txhdr->macctl = htole32(macctl);
9635         txhdr->phyctl = htole16(phyctl);
9636
9637         /*
9638          * TX radio tap
9639          */
9640         if (ieee80211_radiotap_active_vap(vap)) {
9641                 sc->sc_tx_th.wt_flags = 0;
9642                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9643                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9644                 if (isshort &&
9645                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9646                      rate == BWN_CCK_RATE_11MB))
9647                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9648                 sc->sc_tx_th.wt_rate = rate;
9649
9650                 ieee80211_radiotap_tx(vap, m);
9651         }
9652
9653         return (0);
9654 }
9655
9656 static void
9657 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9658     const uint8_t rate)
9659 {
9660         uint32_t d, plen;
9661         uint8_t *raw = plcp->o.raw;
9662
9663         if (BWN_ISOFDMRATE(rate)) {
9664                 d = bwn_plcp_getofdm(rate);
9665                 KASSERT(!(octets & 0xf000),
9666                     ("%s:%d: fail", __func__, __LINE__));
9667                 d |= (octets << 5);
9668                 plcp->o.data = htole32(d);
9669         } else {
9670                 plen = octets * 16 / rate;
9671                 if ((octets * 16 % rate) > 0) {
9672                         plen++;
9673                         if ((rate == BWN_CCK_RATE_11MB)
9674                             && ((octets * 8 % 11) < 4)) {
9675                                 raw[1] = 0x84;
9676                         } else
9677                                 raw[1] = 0x04;
9678                 } else
9679                         raw[1] = 0x04;
9680                 plcp->o.data |= htole32(plen << 16);
9681                 raw[0] = bwn_plcp_getcck(rate);
9682         }
9683 }
9684
9685 static uint8_t
9686 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9687 {
9688         struct bwn_softc *sc = mac->mac_sc;
9689         uint8_t mask;
9690
9691         if (n == 0)
9692                 return (0);
9693         if (mac->mac_phy.gmode)
9694                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9695         else
9696                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9697         if (!(mask & (1 << (n - 1))))
9698                 return (0);
9699         return (n);
9700 }
9701
9702 static uint8_t
9703 bwn_get_fbrate(uint8_t bitrate)
9704 {
9705         switch (bitrate) {
9706         case BWN_CCK_RATE_1MB:
9707                 return (BWN_CCK_RATE_1MB);
9708         case BWN_CCK_RATE_2MB:
9709                 return (BWN_CCK_RATE_1MB);
9710         case BWN_CCK_RATE_5MB:
9711                 return (BWN_CCK_RATE_2MB);
9712         case BWN_CCK_RATE_11MB:
9713                 return (BWN_CCK_RATE_5MB);
9714         case BWN_OFDM_RATE_6MB:
9715                 return (BWN_CCK_RATE_5MB);
9716         case BWN_OFDM_RATE_9MB:
9717                 return (BWN_OFDM_RATE_6MB);
9718         case BWN_OFDM_RATE_12MB:
9719                 return (BWN_OFDM_RATE_9MB);
9720         case BWN_OFDM_RATE_18MB:
9721                 return (BWN_OFDM_RATE_12MB);
9722         case BWN_OFDM_RATE_24MB:
9723                 return (BWN_OFDM_RATE_18MB);
9724         case BWN_OFDM_RATE_36MB:
9725                 return (BWN_OFDM_RATE_24MB);
9726         case BWN_OFDM_RATE_48MB:
9727                 return (BWN_OFDM_RATE_36MB);
9728         case BWN_OFDM_RATE_54MB:
9729                 return (BWN_OFDM_RATE_48MB);
9730         }
9731         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9732         return (0);
9733 }
9734
9735 static uint32_t
9736 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9737     uint32_t ctl, const void *_data, int len)
9738 {
9739         struct bwn_softc *sc = mac->mac_sc;
9740         uint32_t value = 0;
9741         const uint8_t *data = _data;
9742
9743         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9744             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9745         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9746
9747         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9748             tq->tq_base + BWN_PIO8_TXDATA);
9749         if (len & 3) {
9750                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9751                     BWN_PIO8_TXCTL_24_31);
9752                 data = &(data[len - 1]);
9753                 switch (len & 3) {
9754                 case 3:
9755                         ctl |= BWN_PIO8_TXCTL_16_23;
9756                         value |= (uint32_t)(*data) << 16;
9757                         data--;
9758                 case 2:
9759                         ctl |= BWN_PIO8_TXCTL_8_15;
9760                         value |= (uint32_t)(*data) << 8;
9761                         data--;
9762                 case 1:
9763                         value |= (uint32_t)(*data);
9764                 }
9765                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9766                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9767         }
9768
9769         return (ctl);
9770 }
9771
9772 static void
9773 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9774     uint16_t offset, uint32_t value)
9775 {
9776
9777         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9778 }
9779
9780 static uint16_t
9781 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9782     uint16_t ctl, const void *_data, int len)
9783 {
9784         struct bwn_softc *sc = mac->mac_sc;
9785         const uint8_t *data = _data;
9786
9787         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9788         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9789
9790         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9791             tq->tq_base + BWN_PIO_TXDATA);
9792         if (len & 1) {
9793                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9794                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9795                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9796         }
9797
9798         return (ctl);
9799 }
9800
9801 static uint16_t
9802 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9803     uint16_t ctl, struct mbuf *m0)
9804 {
9805         int i, j = 0;
9806         uint16_t data = 0;
9807         const uint8_t *buf;
9808         struct mbuf *m = m0;
9809
9810         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9811         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9812
9813         for (; m != NULL; m = m->m_next) {
9814                 buf = mtod(m, const uint8_t *);
9815                 for (i = 0; i < m->m_len; i++) {
9816                         if (!((j++) % 2))
9817                                 data |= buf[i];
9818                         else {
9819                                 data |= (buf[i] << 8);
9820                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9821                                 data = 0;
9822                         }
9823                 }
9824         }
9825         if (m0->m_pkthdr.len % 2) {
9826                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9827                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9828                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9829         }
9830
9831         return (ctl);
9832 }
9833
9834 static void
9835 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9836 {
9837
9838         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9839                 return;
9840         BWN_WRITE_2(mac, 0x684, 510 + time);
9841         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9842 }
9843
9844 static struct bwn_dma_ring *
9845 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9846 {
9847
9848         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9849                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9850
9851         switch (prio) {
9852         case 3:
9853                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9854         case 2:
9855                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9856         case 0:
9857                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9858         case 1:
9859                 return (mac->mac_method.dma.wme[WME_AC_BK]);
9860         }
9861         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9862         return (NULL);
9863 }
9864
9865 static int
9866 bwn_dma_getslot(struct bwn_dma_ring *dr)
9867 {
9868         int slot;
9869
9870         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
9871
9872         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9873         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9874         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9875
9876         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9877         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9878         dr->dr_curslot = slot;
9879         dr->dr_usedslot++;
9880
9881         return (slot);
9882 }
9883
9884 static int
9885 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9886 {
9887         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9888         unsigned int a, b, c, d;
9889         unsigned int avg;
9890         uint32_t tmp;
9891
9892         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9893         a = tmp & 0xff;
9894         b = (tmp >> 8) & 0xff;
9895         c = (tmp >> 16) & 0xff;
9896         d = (tmp >> 24) & 0xff;
9897         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9898             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9899                 return (ENOENT);
9900         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9901             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9902             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9903
9904         if (ofdm) {
9905                 a = (a + 32) & 0x3f;
9906                 b = (b + 32) & 0x3f;
9907                 c = (c + 32) & 0x3f;
9908                 d = (d + 32) & 0x3f;
9909         }
9910
9911         avg = (a + b + c + d + 2) / 4;
9912         if (ofdm) {
9913                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9914                     & BWN_HF_4DB_CCK_POWERBOOST)
9915                         avg = (avg >= 13) ? (avg - 13) : 0;
9916         }
9917         return (avg);
9918 }
9919
9920 static void
9921 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9922 {
9923         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9924         int rfatt = *rfattp;
9925         int bbatt = *bbattp;
9926
9927         while (1) {
9928                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9929                         break;
9930                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9931                         break;
9932                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9933                         break;
9934                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9935                         break;
9936                 if (bbatt > lo->bbatt.max) {
9937                         bbatt -= 4;
9938                         rfatt += 1;
9939                         continue;
9940                 }
9941                 if (bbatt < lo->bbatt.min) {
9942                         bbatt += 4;
9943                         rfatt -= 1;
9944                         continue;
9945                 }
9946                 if (rfatt > lo->rfatt.max) {
9947                         rfatt -= 1;
9948                         bbatt += 4;
9949                         continue;
9950                 }
9951                 if (rfatt < lo->rfatt.min) {
9952                         rfatt += 1;
9953                         bbatt -= 4;
9954                         continue;
9955                 }
9956                 break;
9957         }
9958
9959         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9960         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9961 }
9962
9963 static void
9964 bwn_phy_lock(struct bwn_mac *mac)
9965 {
9966         struct bwn_softc *sc = mac->mac_sc;
9967         struct ieee80211com *ic = &sc->sc_ic;
9968
9969         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9970             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9971
9972         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9973                 bwn_psctl(mac, BWN_PS_AWAKE);
9974 }
9975
9976 static void
9977 bwn_phy_unlock(struct bwn_mac *mac)
9978 {
9979         struct bwn_softc *sc = mac->mac_sc;
9980         struct ieee80211com *ic = &sc->sc_ic;
9981
9982         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9983             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9984
9985         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9986                 bwn_psctl(mac, 0);
9987 }
9988
9989 static void
9990 bwn_rf_lock(struct bwn_mac *mac)
9991 {
9992
9993         BWN_WRITE_4(mac, BWN_MACCTL,
9994             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
9995         BWN_READ_4(mac, BWN_MACCTL);
9996         DELAY(10);
9997 }
9998
9999 static void
10000 bwn_rf_unlock(struct bwn_mac *mac)
10001 {
10002
10003         BWN_READ_2(mac, BWN_PHYVER);
10004         BWN_WRITE_4(mac, BWN_MACCTL,
10005             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10006 }
10007
10008 static struct bwn_pio_txqueue *
10009 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10010     struct bwn_pio_txpkt **pack)
10011 {
10012         struct bwn_pio *pio = &mac->mac_method.pio;
10013         struct bwn_pio_txqueue *tq = NULL;
10014         unsigned int index;
10015
10016         switch (cookie & 0xf000) {
10017         case 0x1000:
10018                 tq = &pio->wme[WME_AC_BK];
10019                 break;
10020         case 0x2000:
10021                 tq = &pio->wme[WME_AC_BE];
10022                 break;
10023         case 0x3000:
10024                 tq = &pio->wme[WME_AC_VI];
10025                 break;
10026         case 0x4000:
10027                 tq = &pio->wme[WME_AC_VO];
10028                 break;
10029         case 0x5000:
10030                 tq = &pio->mcast;
10031                 break;
10032         }
10033         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10034         if (tq == NULL)
10035                 return (NULL);
10036         index = (cookie & 0x0fff);
10037         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10038         if (index >= N(tq->tq_pkts))
10039                 return (NULL);
10040         *pack = &tq->tq_pkts[index];
10041         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10042         return (tq);
10043 }
10044
10045 static void
10046 bwn_txpwr(void *arg, int npending)
10047 {
10048         struct bwn_mac *mac = arg;
10049         struct bwn_softc *sc = mac->mac_sc;
10050
10051         BWN_LOCK(sc);
10052         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10053             mac->mac_phy.set_txpwr != NULL)
10054                 mac->mac_phy.set_txpwr(mac);
10055         BWN_UNLOCK(sc);
10056 }
10057
10058 static void
10059 bwn_task_15s(struct bwn_mac *mac)
10060 {
10061         uint16_t reg;
10062
10063         if (mac->mac_fw.opensource) {
10064                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10065                 if (reg) {
10066                         bwn_restart(mac, "fw watchdog");
10067                         return;
10068                 }
10069                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10070         }
10071         if (mac->mac_phy.task_15s)
10072                 mac->mac_phy.task_15s(mac);
10073
10074         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10075 }
10076
10077 static void
10078 bwn_task_30s(struct bwn_mac *mac)
10079 {
10080
10081         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10082                 return;
10083         mac->mac_noise.noi_running = 1;
10084         mac->mac_noise.noi_nsamples = 0;
10085
10086         bwn_noise_gensample(mac);
10087 }
10088
10089 static void
10090 bwn_task_60s(struct bwn_mac *mac)
10091 {
10092
10093         if (mac->mac_phy.task_60s)
10094                 mac->mac_phy.task_60s(mac);
10095         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10096 }
10097
10098 static void
10099 bwn_tasks(void *arg)
10100 {
10101         struct bwn_mac *mac = arg;
10102         struct bwn_softc *sc = mac->mac_sc;
10103
10104         BWN_ASSERT_LOCKED(sc);
10105         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10106                 return;
10107
10108         if (mac->mac_task_state % 4 == 0)
10109                 bwn_task_60s(mac);
10110         if (mac->mac_task_state % 2 == 0)
10111                 bwn_task_30s(mac);
10112         bwn_task_15s(mac);
10113
10114         mac->mac_task_state++;
10115         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10116 }
10117
10118 static int
10119 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10120 {
10121         struct bwn_softc *sc = mac->mac_sc;
10122
10123         KASSERT(a == 0, ("not support APHY\n"));
10124
10125         switch (plcp->o.raw[0] & 0xf) {
10126         case 0xb:
10127                 return (BWN_OFDM_RATE_6MB);
10128         case 0xf:
10129                 return (BWN_OFDM_RATE_9MB);
10130         case 0xa:
10131                 return (BWN_OFDM_RATE_12MB);
10132         case 0xe:
10133                 return (BWN_OFDM_RATE_18MB);
10134         case 0x9:
10135                 return (BWN_OFDM_RATE_24MB);
10136         case 0xd:
10137                 return (BWN_OFDM_RATE_36MB);
10138         case 0x8:
10139                 return (BWN_OFDM_RATE_48MB);
10140         case 0xc:
10141                 return (BWN_OFDM_RATE_54MB);
10142         }
10143         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10144             plcp->o.raw[0] & 0xf);
10145         return (-1);
10146 }
10147
10148 static int
10149 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10150 {
10151         struct bwn_softc *sc = mac->mac_sc;
10152
10153         switch (plcp->o.raw[0]) {
10154         case 0x0a:
10155                 return (BWN_CCK_RATE_1MB);
10156         case 0x14:
10157                 return (BWN_CCK_RATE_2MB);
10158         case 0x37:
10159                 return (BWN_CCK_RATE_5MB);
10160         case 0x6e:
10161                 return (BWN_CCK_RATE_11MB);
10162         }
10163         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10164         return (-1);
10165 }
10166
10167 static void
10168 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10169     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10170     int rssi, int noise)
10171 {
10172         struct bwn_softc *sc = mac->mac_sc;
10173         const struct ieee80211_frame_min *wh;
10174         uint64_t tsf;
10175         uint16_t low_mactime_now;
10176
10177         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10178                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10179
10180         wh = mtod(m, const struct ieee80211_frame_min *);
10181         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10182                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10183
10184         bwn_tsf_read(mac, &tsf);
10185         low_mactime_now = tsf;
10186         tsf = tsf & ~0xffffULL;
10187         tsf += le16toh(rxhdr->mac_time);
10188         if (low_mactime_now < le16toh(rxhdr->mac_time))
10189                 tsf -= 0x10000;
10190
10191         sc->sc_rx_th.wr_tsf = tsf;
10192         sc->sc_rx_th.wr_rate = rate;
10193         sc->sc_rx_th.wr_antsignal = rssi;
10194         sc->sc_rx_th.wr_antnoise = noise;
10195 }
10196
10197 static void
10198 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10199 {
10200         uint32_t low, high;
10201
10202         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10203             ("%s:%d: fail", __func__, __LINE__));
10204
10205         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10206         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10207         *tsf = high;
10208         *tsf <<= 32;
10209         *tsf |= low;
10210 }
10211
10212 static int
10213 bwn_dma_attach(struct bwn_mac *mac)
10214 {
10215         struct bwn_dma *dma = &mac->mac_method.dma;
10216         struct bwn_softc *sc = mac->mac_sc;
10217         bus_addr_t lowaddr = 0;
10218         int error;
10219
10220         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10221                 return (0);
10222
10223         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10224
10225         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10226
10227         dma->dmatype = bwn_dma_gettype(mac);
10228         if (dma->dmatype == BWN_DMA_30BIT)
10229                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10230         else if (dma->dmatype == BWN_DMA_32BIT)
10231                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10232         else
10233                 lowaddr = BUS_SPACE_MAXADDR;
10234
10235         /*
10236          * Create top level DMA tag
10237          */
10238         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10239                                BWN_ALIGN, 0,            /* alignment, bounds */
10240                                lowaddr,                 /* lowaddr */
10241                                BUS_SPACE_MAXADDR,       /* highaddr */
10242                                NULL, NULL,              /* filter, filterarg */
10243                                BUS_SPACE_MAXSIZE,       /* maxsize */
10244                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10245                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10246                                0,                       /* flags */
10247                                NULL, NULL,              /* lockfunc, lockarg */
10248                                &dma->parent_dtag);
10249         if (error) {
10250                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10251                 return (error);
10252         }
10253
10254         /*
10255          * Create TX/RX mbuf DMA tag
10256          */
10257         error = bus_dma_tag_create(dma->parent_dtag,
10258                                 1,
10259                                 0,
10260                                 BUS_SPACE_MAXADDR,
10261                                 BUS_SPACE_MAXADDR,
10262                                 NULL, NULL,
10263                                 MCLBYTES,
10264                                 1,
10265                                 BUS_SPACE_MAXSIZE_32BIT,
10266                                 0,
10267                                 NULL, NULL,
10268                                 &dma->rxbuf_dtag);
10269         if (error) {
10270                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10271                 goto fail0;
10272         }
10273         error = bus_dma_tag_create(dma->parent_dtag,
10274                                 1,
10275                                 0,
10276                                 BUS_SPACE_MAXADDR,
10277                                 BUS_SPACE_MAXADDR,
10278                                 NULL, NULL,
10279                                 MCLBYTES,
10280                                 1,
10281                                 BUS_SPACE_MAXSIZE_32BIT,
10282                                 0,
10283                                 NULL, NULL,
10284                                 &dma->txbuf_dtag);
10285         if (error) {
10286                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10287                 goto fail1;
10288         }
10289
10290         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10291         if (!dma->wme[WME_AC_BK])
10292                 goto fail2;
10293
10294         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10295         if (!dma->wme[WME_AC_BE])
10296                 goto fail3;
10297
10298         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10299         if (!dma->wme[WME_AC_VI])
10300                 goto fail4;
10301
10302         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10303         if (!dma->wme[WME_AC_VO])
10304                 goto fail5;
10305
10306         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10307         if (!dma->mcast)
10308                 goto fail6;
10309         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10310         if (!dma->rx)
10311                 goto fail7;
10312
10313         return (error);
10314
10315 fail7:  bwn_dma_ringfree(&dma->mcast);
10316 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10317 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10318 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10319 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10320 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10321 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10322 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10323         return (error);
10324 }
10325
10326 static struct bwn_dma_ring *
10327 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10328     uint16_t cookie, int *slot)
10329 {
10330         struct bwn_dma *dma = &mac->mac_method.dma;
10331         struct bwn_dma_ring *dr;
10332         struct bwn_softc *sc = mac->mac_sc;
10333
10334         BWN_ASSERT_LOCKED(mac->mac_sc);
10335
10336         switch (cookie & 0xf000) {
10337         case 0x1000:
10338                 dr = dma->wme[WME_AC_BK];
10339                 break;
10340         case 0x2000:
10341                 dr = dma->wme[WME_AC_BE];
10342                 break;
10343         case 0x3000:
10344                 dr = dma->wme[WME_AC_VI];
10345                 break;
10346         case 0x4000:
10347                 dr = dma->wme[WME_AC_VO];
10348                 break;
10349         case 0x5000:
10350                 dr = dma->mcast;
10351                 break;
10352         default:
10353                 dr = NULL;
10354                 KASSERT(0 == 1,
10355                     ("invalid cookie value %d", cookie & 0xf000));
10356         }
10357         *slot = (cookie & 0x0fff);
10358         if (*slot < 0 || *slot >= dr->dr_numslots) {
10359                 /*
10360                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10361                  * that it occurs events which have same H/W sequence numbers.
10362                  * When it's occurred just prints a WARNING msgs and ignores.
10363                  */
10364                 KASSERT(status->seq == dma->lastseq,
10365                     ("%s:%d: fail", __func__, __LINE__));
10366                 device_printf(sc->sc_dev,
10367                     "out of slot ranges (0 < %d < %d)\n", *slot,
10368                     dr->dr_numslots);
10369                 return (NULL);
10370         }
10371         dma->lastseq = status->seq;
10372         return (dr);
10373 }
10374
10375 static void
10376 bwn_dma_stop(struct bwn_mac *mac)
10377 {
10378         struct bwn_dma *dma;
10379
10380         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10381                 return;
10382         dma = &mac->mac_method.dma;
10383
10384         bwn_dma_ringstop(&dma->rx);
10385         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10386         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10387         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10388         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10389         bwn_dma_ringstop(&dma->mcast);
10390 }
10391
10392 static void
10393 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10394 {
10395
10396         if (dr == NULL)
10397                 return;
10398
10399         bwn_dma_cleanup(*dr);
10400 }
10401
10402 static void
10403 bwn_pio_stop(struct bwn_mac *mac)
10404 {
10405         struct bwn_pio *pio;
10406
10407         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10408                 return;
10409         pio = &mac->mac_method.pio;
10410
10411         bwn_destroy_queue_tx(&pio->mcast);
10412         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10413         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10414         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10415         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10416 }
10417
10418 static void
10419 bwn_led_attach(struct bwn_mac *mac)
10420 {
10421         struct bwn_softc *sc = mac->mac_sc;
10422         const uint8_t *led_act = NULL;
10423         uint16_t val[BWN_LED_MAX];
10424         int i;
10425
10426         sc->sc_led_idle = (2350 * hz) / 1000;
10427         sc->sc_led_blink = 1;
10428
10429         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10430                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10431                     bwn_vendor_led_act[i].vid) {
10432                         led_act = bwn_vendor_led_act[i].led_act;
10433                         break;
10434                 }
10435         }
10436         if (led_act == NULL)
10437                 led_act = bwn_default_led_act;
10438
10439         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10440         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10441         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10442         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10443
10444         for (i = 0; i < BWN_LED_MAX; ++i) {
10445                 struct bwn_led *led = &sc->sc_leds[i];
10446
10447                 if (val[i] == 0xff) {
10448                         led->led_act = led_act[i];
10449                 } else {
10450                         if (val[i] & BWN_LED_ACT_LOW)
10451                                 led->led_flags |= BWN_LED_F_ACTLOW;
10452                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10453                 }
10454                 led->led_mask = (1 << i);
10455
10456                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10457                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10458                     led->led_act == BWN_LED_ACT_BLINK) {
10459                         led->led_flags |= BWN_LED_F_BLINK;
10460                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10461                                 led->led_flags |= BWN_LED_F_POLLABLE;
10462                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10463                                 led->led_flags |= BWN_LED_F_SLOW;
10464
10465                         if (sc->sc_blink_led == NULL) {
10466                                 sc->sc_blink_led = led;
10467                                 if (led->led_flags & BWN_LED_F_SLOW)
10468                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10469                         }
10470                 }
10471
10472                 DPRINTF(sc, BWN_DEBUG_LED,
10473                     "%dth led, act %d, lowact %d\n", i,
10474                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10475         }
10476         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10477 }
10478
10479 static __inline uint16_t
10480 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10481 {
10482
10483         if (led->led_flags & BWN_LED_F_ACTLOW)
10484                 on = !on;
10485         if (on)
10486                 val |= led->led_mask;
10487         else
10488                 val &= ~led->led_mask;
10489         return val;
10490 }
10491
10492 static void
10493 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10494 {
10495         struct bwn_softc *sc = mac->mac_sc;
10496         struct ieee80211com *ic = &sc->sc_ic;
10497         uint16_t val;
10498         int i;
10499
10500         if (nstate == IEEE80211_S_INIT) {
10501                 callout_stop(&sc->sc_led_blink_ch);
10502                 sc->sc_led_blinking = 0;
10503         }
10504
10505         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
10506                 return;
10507
10508         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10509         for (i = 0; i < BWN_LED_MAX; ++i) {
10510                 struct bwn_led *led = &sc->sc_leds[i];
10511                 int on;
10512
10513                 if (led->led_act == BWN_LED_ACT_UNKN ||
10514                     led->led_act == BWN_LED_ACT_NULL)
10515                         continue;
10516
10517                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10518                     nstate != IEEE80211_S_INIT)
10519                         continue;
10520
10521                 switch (led->led_act) {
10522                 case BWN_LED_ACT_ON:    /* Always on */
10523                         on = 1;
10524                         break;
10525                 case BWN_LED_ACT_OFF:   /* Always off */
10526                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10527                         on = 0;
10528                         break;
10529                 default:
10530                         on = 1;
10531                         switch (nstate) {
10532                         case IEEE80211_S_INIT:
10533                                 on = 0;
10534                                 break;
10535                         case IEEE80211_S_RUN:
10536                                 if (led->led_act == BWN_LED_ACT_11G &&
10537                                     ic->ic_curmode != IEEE80211_MODE_11G)
10538                                         on = 0;
10539                                 break;
10540                         default:
10541                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10542                                         on = 0;
10543                                 break;
10544                         }
10545                         break;
10546                 }
10547
10548                 val = bwn_led_onoff(led, val, on);
10549         }
10550         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10551 }
10552
10553 static void
10554 bwn_led_event(struct bwn_mac *mac, int event)
10555 {
10556         struct bwn_softc *sc = mac->mac_sc;
10557         struct bwn_led *led = sc->sc_blink_led;
10558         int rate;
10559
10560         if (event == BWN_LED_EVENT_POLL) {
10561                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10562                         return;
10563                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10564                         return;
10565         }
10566
10567         sc->sc_led_ticks = ticks;
10568         if (sc->sc_led_blinking)
10569                 return;
10570
10571         switch (event) {
10572         case BWN_LED_EVENT_RX:
10573                 rate = sc->sc_rx_rate;
10574                 break;
10575         case BWN_LED_EVENT_TX:
10576                 rate = sc->sc_tx_rate;
10577                 break;
10578         case BWN_LED_EVENT_POLL:
10579                 rate = 0;
10580                 break;
10581         default:
10582                 panic("unknown LED event %d\n", event);
10583                 break;
10584         }
10585         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10586             bwn_led_duration[rate].off_dur);
10587 }
10588
10589 static void
10590 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10591 {
10592         struct bwn_softc *sc = mac->mac_sc;
10593         struct bwn_led *led = sc->sc_blink_led;
10594         uint16_t val;
10595
10596         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10597         val = bwn_led_onoff(led, val, 1);
10598         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10599
10600         if (led->led_flags & BWN_LED_F_SLOW) {
10601                 BWN_LED_SLOWDOWN(on_dur);
10602                 BWN_LED_SLOWDOWN(off_dur);
10603         }
10604
10605         sc->sc_led_blinking = 1;
10606         sc->sc_led_blink_offdur = off_dur;
10607
10608         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10609 }
10610
10611 static void
10612 bwn_led_blink_next(void *arg)
10613 {
10614         struct bwn_mac *mac = arg;
10615         struct bwn_softc *sc = mac->mac_sc;
10616         uint16_t val;
10617
10618         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10619         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10620         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10621
10622         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10623             bwn_led_blink_end, mac);
10624 }
10625
10626 static void
10627 bwn_led_blink_end(void *arg)
10628 {
10629         struct bwn_mac *mac = arg;
10630         struct bwn_softc *sc = mac->mac_sc;
10631
10632         sc->sc_led_blinking = 0;
10633 }
10634
10635 static int
10636 bwn_suspend(device_t dev)
10637 {
10638         struct bwn_softc *sc = device_get_softc(dev);
10639
10640         BWN_LOCK(sc);
10641         bwn_stop(sc);
10642         BWN_UNLOCK(sc);
10643         return (0);
10644 }
10645
10646 static int
10647 bwn_resume(device_t dev)
10648 {
10649         struct bwn_softc *sc = device_get_softc(dev);
10650         int error = EDOOFUS;
10651
10652         BWN_LOCK(sc);
10653         if (sc->sc_ic.ic_nrunning > 0)
10654                 error = bwn_init(sc);
10655         BWN_UNLOCK(sc);
10656         if (error == 0)
10657                 ieee80211_start_all(&sc->sc_ic);
10658         return (0);
10659 }
10660
10661 static void
10662 bwn_rfswitch(void *arg)
10663 {
10664         struct bwn_softc *sc = arg;
10665         struct bwn_mac *mac = sc->sc_curmac;
10666         int cur = 0, prev = 0;
10667
10668         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10669             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10670
10671         if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10672                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10673                         & BWN_RF_HWENABLED_HI_MASK))
10674                         cur = 1;
10675         } else {
10676                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10677                     & BWN_RF_HWENABLED_LO_MASK)
10678                         cur = 1;
10679         }
10680
10681         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10682                 prev = 1;
10683
10684         if (cur != prev) {
10685                 if (cur)
10686                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10687                 else
10688                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10689
10690                 device_printf(sc->sc_dev,
10691                     "status of RF switch is changed to %s\n",
10692                     cur ? "ON" : "OFF");
10693                 if (cur != mac->mac_phy.rf_on) {
10694                         if (cur)
10695                                 bwn_rf_turnon(mac);
10696                         else
10697                                 bwn_rf_turnoff(mac);
10698                 }
10699         }
10700
10701         callout_schedule(&sc->sc_rfswitch_ch, hz);
10702 }
10703
10704 static void
10705 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10706 {
10707         struct bwn_phy *phy = &mac->mac_phy;
10708         struct bwn_phy_lp *plp = &phy->phy_lp;
10709
10710         plp->plp_antenna = BWN_ANT_DEFAULT;
10711 }
10712
10713 static int
10714 bwn_phy_lp_init(struct bwn_mac *mac)
10715 {
10716         static const struct bwn_stxtable tables[] = {
10717                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10718                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10719                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10720                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10721                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10722                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10723                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10724                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10725                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10726                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10727                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10728                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10729                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10730                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10731                 { 2, 11, 0x40, 0, 0x0f }
10732         };
10733         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10734         struct bwn_softc *sc = mac->mac_sc;
10735         const struct bwn_stxtable *st;
10736         struct ieee80211com *ic = &sc->sc_ic;
10737         int i, error;
10738         uint16_t tmp;
10739
10740         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10741         bwn_phy_lp_bbinit(mac);
10742
10743         /* initialize RF */
10744         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10745         DELAY(1);
10746         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10747         DELAY(1);
10748
10749         if (mac->mac_phy.rf_ver == 0x2062)
10750                 bwn_phy_lp_b2062_init(mac);
10751         else {
10752                 bwn_phy_lp_b2063_init(mac);
10753
10754                 /* synchronize stx table. */
10755                 for (i = 0; i < N(tables); i++) {
10756                         st = &tables[i];
10757                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10758                         tmp >>= st->st_rfshift;
10759                         tmp <<= st->st_physhift;
10760                         BWN_PHY_SETMASK(mac,
10761                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10762                             ~(st->st_mask << st->st_physhift), tmp);
10763                 }
10764
10765                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10766                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10767         }
10768
10769         /* calibrate RC */
10770         if (mac->mac_phy.rev >= 2)
10771                 bwn_phy_lp_rxcal_r2(mac);
10772         else if (!plp->plp_rccap) {
10773                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10774                         bwn_phy_lp_rccal_r12(mac);
10775         } else
10776                 bwn_phy_lp_set_rccap(mac);
10777
10778         error = bwn_phy_lp_switch_channel(mac, 7);
10779         if (error)
10780                 device_printf(sc->sc_dev,
10781                     "failed to change channel 7 (%d)\n", error);
10782         bwn_phy_lp_txpctl_init(mac);
10783         bwn_phy_lp_calib(mac);
10784         return (0);
10785 }
10786
10787 static uint16_t
10788 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10789 {
10790
10791         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10792         return (BWN_READ_2(mac, BWN_PHYDATA));
10793 }
10794
10795 static void
10796 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10797 {
10798
10799         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10800         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10801 }
10802
10803 static void
10804 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10805     uint16_t set)
10806 {
10807
10808         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10809         BWN_WRITE_2(mac, BWN_PHYDATA,
10810             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10811 }
10812
10813 static uint16_t
10814 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10815 {
10816
10817         KASSERT(reg != 1, ("unaccessible register %d", reg));
10818         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10819                 reg |= 0x100;
10820         if (mac->mac_phy.rev >= 2)
10821                 reg |= 0x200;
10822         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10823         return BWN_READ_2(mac, BWN_RFDATALO);
10824 }
10825
10826 static void
10827 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10828 {
10829
10830         KASSERT(reg != 1, ("unaccessible register %d", reg));
10831         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10832         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10833 }
10834
10835 static void
10836 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10837 {
10838
10839         if (on) {
10840                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10841                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10842                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10843                 return;
10844         }
10845
10846         if (mac->mac_phy.rev >= 2) {
10847                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10848                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10849                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10850                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10851                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10852                 return;
10853         }
10854
10855         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10856         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10857         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10858         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10859 }
10860
10861 static int
10862 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10863 {
10864         struct bwn_phy *phy = &mac->mac_phy;
10865         struct bwn_phy_lp *plp = &phy->phy_lp;
10866         int error;
10867
10868         if (phy->rf_ver == 0x2063) {
10869                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10870                 if (error)
10871                         return (error);
10872         } else {
10873                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10874                 if (error)
10875                         return (error);
10876                 bwn_phy_lp_set_anafilter(mac, chan);
10877                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10878         }
10879
10880         plp->plp_chan = chan;
10881         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10882         return (0);
10883 }
10884
10885 static uint32_t
10886 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10887 {
10888         struct bwn_softc *sc = mac->mac_sc;
10889         struct ieee80211com *ic = &sc->sc_ic;
10890
10891         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10892 }
10893
10894 static void
10895 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10896 {
10897         struct bwn_phy *phy = &mac->mac_phy;
10898         struct bwn_phy_lp *plp = &phy->phy_lp;
10899
10900         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10901                 return;
10902
10903         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10904         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10905         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10906         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10907         plp->plp_antenna = antenna;
10908 }
10909
10910 static void
10911 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10912 {
10913
10914         bwn_phy_lp_calib(mac);
10915 }
10916
10917 static void
10918 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10919 {
10920         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10921         struct bwn_softc *sc = mac->mac_sc;
10922         struct ieee80211com *ic = &sc->sc_ic;
10923
10924         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10925                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10926                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10927                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10928                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10929                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10930                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10931                 return;
10932         }
10933
10934         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10935         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10936         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10937         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10938         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10939         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10940         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10941         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10942 }
10943
10944 static void
10945 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10946 {
10947
10948         bwn_phy_lp_tblinit(mac);
10949         if (mac->mac_phy.rev >= 2)
10950                 bwn_phy_lp_bbinit_r2(mac);
10951         else
10952                 bwn_phy_lp_bbinit_r01(mac);
10953 }
10954
10955 static void
10956 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10957 {
10958         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
10959         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
10960         struct bwn_softc *sc = mac->mac_sc;
10961         struct ieee80211com *ic = &sc->sc_ic;
10962
10963         bwn_phy_lp_set_txgain(mac,
10964             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
10965         bwn_phy_lp_set_bbmult(mac, 150);
10966 }
10967
10968 static void
10969 bwn_phy_lp_calib(struct bwn_mac *mac)
10970 {
10971         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10972         struct bwn_softc *sc = mac->mac_sc;
10973         struct ieee80211com *ic = &sc->sc_ic;
10974         const struct bwn_rxcompco *rc = NULL;
10975         struct bwn_txgain ogain;
10976         int i, omode, oafeovr, orf, obbmult;
10977         uint8_t mode, fc = 0;
10978
10979         if (plp->plp_chanfullcal != plp->plp_chan) {
10980                 plp->plp_chanfullcal = plp->plp_chan;
10981                 fc = 1;
10982         }
10983
10984         bwn_mac_suspend(mac);
10985
10986         /* BlueTooth Coexistance Override */
10987         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
10988         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
10989
10990         if (mac->mac_phy.rev >= 2)
10991                 bwn_phy_lp_digflt_save(mac);
10992         bwn_phy_lp_get_txpctlmode(mac);
10993         mode = plp->plp_txpctlmode;
10994         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
10995         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
10996                 bwn_phy_lp_bugfix(mac);
10997         if (mac->mac_phy.rev >= 2 && fc == 1) {
10998                 bwn_phy_lp_get_txpctlmode(mac);
10999                 omode = plp->plp_txpctlmode;
11000                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11001                 if (oafeovr)
11002                         ogain = bwn_phy_lp_get_txgain(mac);
11003                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11004                 obbmult = bwn_phy_lp_get_bbmult(mac);
11005                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11006                 if (oafeovr)
11007                         bwn_phy_lp_set_txgain(mac, &ogain);
11008                 bwn_phy_lp_set_bbmult(mac, obbmult);
11009                 bwn_phy_lp_set_txpctlmode(mac, omode);
11010                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11011         }
11012         bwn_phy_lp_set_txpctlmode(mac, mode);
11013         if (mac->mac_phy.rev >= 2)
11014                 bwn_phy_lp_digflt_restore(mac);
11015
11016         /* do RX IQ Calculation; assumes that noise is true. */
11017         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11018                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11019                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11020                                 rc = &bwn_rxcompco_5354[i];
11021                 }
11022         } else if (mac->mac_phy.rev >= 2)
11023                 rc = &bwn_rxcompco_r2;
11024         else {
11025                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11026                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11027                                 rc = &bwn_rxcompco_r12[i];
11028                 }
11029         }
11030         if (rc == NULL)
11031                 goto fail;
11032
11033         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11034         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11035
11036         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11037
11038         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11039                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11040                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11041         } else {
11042                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11043                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11044         }
11045
11046         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11047         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11048         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11049         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11050         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11051         bwn_phy_lp_set_deaf(mac, 0);
11052         /* XXX no checking return value? */
11053         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11054         bwn_phy_lp_clear_deaf(mac, 0);
11055         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11056         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11057         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11058
11059         /* disable RX GAIN override. */
11060         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11061         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11062         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11063         if (mac->mac_phy.rev >= 2) {
11064                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11065                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11066                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11067                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11068                 }
11069         } else {
11070                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11071         }
11072
11073         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11074         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11075 fail:
11076         bwn_mac_enable(mac);
11077 }
11078
11079 static void
11080 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11081 {
11082
11083         if (on) {
11084                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11085                 return;
11086         }
11087
11088         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11089         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11090 }
11091
11092 static int
11093 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11094 {
11095         static const struct bwn_b206x_chan *bc = NULL;
11096         struct bwn_softc *sc = mac->mac_sc;
11097         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11098             tmp[6];
11099         uint16_t old, scale, tmp16;
11100         int i, div;
11101
11102         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11103                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11104                         bc = &bwn_b2063_chantable[i];
11105                         break;
11106                 }
11107         }
11108         if (bc == NULL)
11109                 return (EINVAL);
11110
11111         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11112         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11113         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11114         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11115         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11116         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11117         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11118         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11119         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11120         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11121         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11122         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11123
11124         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11125         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11126
11127         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11128         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11129         freqref = freqxtal * 3;
11130         div = (freqxtal <= 26000000 ? 1 : 2);
11131         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11132         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11133                 999999) / 1000000) + 1;
11134
11135         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11136         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11137             0xfff8, timeout >> 2);
11138         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11139             0xff9f,timeout << 5);
11140         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11141
11142         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11143         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11144         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11145
11146         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11147             (timeoutref + 1)) - 1;
11148         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11149             0xf0, count >> 8);
11150         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11151
11152         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11153         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11154         while (tmp[1] >= freqref) {
11155                 tmp[0]++;
11156                 tmp[1] -= freqref;
11157         }
11158         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11159         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11160         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11161         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11162         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11163
11164         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11165         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11166         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11167         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11168
11169         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11170         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11171
11172         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11173                 scale = 1;
11174                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11175         } else {
11176                 scale = 0;
11177                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11178         }
11179         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11180         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11181
11182         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11183             (scale + 1);
11184         if (tmp[5] > 150)
11185                 tmp[5] = 0;
11186
11187         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11188         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11189
11190         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11191         if (freqxtal > 26000000)
11192                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11193         else
11194                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11195
11196         if (val[0] == 45)
11197                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11198         else
11199                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11200
11201         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11202         DELAY(1);
11203         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11204
11205         /* VCO Calibration */
11206         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11207         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11208         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11209         DELAY(1);
11210         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11211         DELAY(1);
11212         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11213         DELAY(1);
11214         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11215         DELAY(300);
11216         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11217
11218         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11219         return (0);
11220 }
11221
11222 static int
11223 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11224 {
11225         struct bwn_softc *sc = mac->mac_sc;
11226         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11227         const struct bwn_b206x_chan *bc = NULL;
11228         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11229         uint32_t tmp[9];
11230         int i;
11231
11232         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11233                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11234                         bc = &bwn_b2062_chantable[i];
11235                         break;
11236                 }
11237         }
11238
11239         if (bc == NULL)
11240                 return (EINVAL);
11241
11242         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11243         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11244         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11245         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11246         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11247         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11248         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11249         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11250         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11251         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11252
11253         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11254         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11255         bwn_phy_lp_b2062_reset_pllbias(mac);
11256         tmp[0] = freqxtal / 1000;
11257         tmp[1] = plp->plp_div * 1000;
11258         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11259         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11260                 tmp[2] *= 2;
11261         tmp[3] = 48 * tmp[0];
11262         tmp[5] = tmp[2] / tmp[3];
11263         tmp[6] = tmp[2] % tmp[3];
11264         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11265         tmp[4] = tmp[6] * 0x100;
11266         tmp[5] = tmp[4] / tmp[3];
11267         tmp[6] = tmp[4] % tmp[3];
11268         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11269         tmp[4] = tmp[6] * 0x100;
11270         tmp[5] = tmp[4] / tmp[3];
11271         tmp[6] = tmp[4] % tmp[3];
11272         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11273         tmp[4] = tmp[6] * 0x100;
11274         tmp[5] = tmp[4] / tmp[3];
11275         tmp[6] = tmp[4] % tmp[3];
11276         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11277             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11278         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11279         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11280         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11281         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11282
11283         bwn_phy_lp_b2062_vco_calib(mac);
11284         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11285                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11286                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11287                 bwn_phy_lp_b2062_reset_pllbias(mac);
11288                 bwn_phy_lp_b2062_vco_calib(mac);
11289                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11290                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11291                         return (EIO);
11292                 }
11293         }
11294         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11295         return (0);
11296 }
11297
11298 static void
11299 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11300 {
11301         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11302         uint16_t tmp = (channel == 14);
11303
11304         if (mac->mac_phy.rev < 2) {
11305                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11306                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11307                         bwn_phy_lp_set_rccap(mac);
11308                 return;
11309         }
11310
11311         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11312 }
11313
11314 static void
11315 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11316 {
11317         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11318         struct bwn_softc *sc = mac->mac_sc;
11319         struct ieee80211com *ic = &sc->sc_ic;
11320         uint16_t iso, tmp[3];
11321
11322         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11323
11324         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11325                 iso = plp->plp_txisoband_m;
11326         else if (freq <= 5320)
11327                 iso = plp->plp_txisoband_l;
11328         else if (freq <= 5700)
11329                 iso = plp->plp_txisoband_m;
11330         else
11331                 iso = plp->plp_txisoband_h;
11332
11333         tmp[0] = ((iso - 26) / 12) << 12;
11334         tmp[1] = tmp[0] + 0x1000;
11335         tmp[2] = tmp[0] + 0x2000;
11336
11337         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11338         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11339 }
11340
11341 static void
11342 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11343 {
11344         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11345         int i;
11346         static const uint16_t addr[] = {
11347                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11348                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11349                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11350                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11351                 BWN_PHY_OFDM(0xcf),
11352         };
11353         static const uint16_t val[] = {
11354                 0xde5e, 0xe832, 0xe331, 0x4d26,
11355                 0x0026, 0x1420, 0x0020, 0xfe08,
11356                 0x0008,
11357         };
11358
11359         for (i = 0; i < N(addr); i++) {
11360                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11361                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11362         }
11363 }
11364
11365 static void
11366 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11367 {
11368         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11369         struct bwn_softc *sc = mac->mac_sc;
11370         uint16_t ctl;
11371
11372         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11373         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11374         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11375                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11376                 break;
11377         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11378                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11379                 break;
11380         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11381                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11382                 break;
11383         default:
11384                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11385                 device_printf(sc->sc_dev, "unknown command mode\n");
11386                 break;
11387         }
11388 }
11389
11390 static void
11391 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11392 {
11393         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11394         uint16_t ctl;
11395         uint8_t old;
11396
11397         bwn_phy_lp_get_txpctlmode(mac);
11398         old = plp->plp_txpctlmode;
11399         if (old == mode)
11400                 return;
11401         plp->plp_txpctlmode = mode;
11402
11403         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11404                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11405                     plp->plp_tssiidx);
11406                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11407                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11408
11409                 /* disable TX GAIN override */
11410                 if (mac->mac_phy.rev < 2)
11411                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11412                 else {
11413                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11414                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11415                 }
11416                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11417
11418                 plp->plp_txpwridx = -1;
11419         }
11420         if (mac->mac_phy.rev >= 2) {
11421                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11422                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11423                 else
11424                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11425         }
11426
11427         /* writes TX Power Control mode */
11428         switch (plp->plp_txpctlmode) {
11429         case BWN_PHYLP_TXPCTL_OFF:
11430                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11431                 break;
11432         case BWN_PHYLP_TXPCTL_ON_HW:
11433                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11434                 break;
11435         case BWN_PHYLP_TXPCTL_ON_SW:
11436                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11437                 break;
11438         default:
11439                 ctl = 0;
11440                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11441         }
11442         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11443             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11444 }
11445
11446 static void
11447 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11448 {
11449         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11450         struct bwn_softc *sc = mac->mac_sc;
11451         const unsigned int size = 256;
11452         struct bwn_txgain tg;
11453         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11454         uint16_t tssinpt, tssiidx, value[2];
11455         uint8_t mode;
11456         int8_t txpwridx;
11457
11458         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11459             M_NOWAIT | M_ZERO);
11460         if (tabs == NULL) {
11461                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11462                 return;
11463         }
11464
11465         bwn_phy_lp_get_txpctlmode(mac);
11466         mode = plp->plp_txpctlmode;
11467         txpwridx = plp->plp_txpwridx;
11468         tssinpt = plp->plp_tssinpt;
11469         tssiidx = plp->plp_tssiidx;
11470
11471         bwn_tab_read_multi(mac,
11472             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11473             BWN_TAB_4(7, 0x140), size, tabs);
11474
11475         bwn_phy_lp_tblinit(mac);
11476         bwn_phy_lp_bbinit(mac);
11477         bwn_phy_lp_txpctl_init(mac);
11478         bwn_phy_lp_rf_onoff(mac, 1);
11479         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11480
11481         bwn_tab_write_multi(mac,
11482             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11483             BWN_TAB_4(7, 0x140), size, tabs);
11484
11485         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11486         plp->plp_tssinpt = tssinpt;
11487         plp->plp_tssiidx = tssiidx;
11488         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11489         if (txpwridx != -1) {
11490                 /* set TX power by index */
11491                 plp->plp_txpwridx = txpwridx;
11492                 bwn_phy_lp_get_txpctlmode(mac);
11493                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11494                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11495                 if (mac->mac_phy.rev >= 2) {
11496                         rxcomp = bwn_tab_read(mac,
11497                             BWN_TAB_4(7, txpwridx + 320));
11498                         txgain = bwn_tab_read(mac,
11499                             BWN_TAB_4(7, txpwridx + 192));
11500                         tg.tg_pad = (txgain >> 16) & 0xff;
11501                         tg.tg_gm = txgain & 0xff;
11502                         tg.tg_pga = (txgain >> 8) & 0xff;
11503                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11504                         bwn_phy_lp_set_txgain(mac, &tg);
11505                 } else {
11506                         rxcomp = bwn_tab_read(mac,
11507                             BWN_TAB_4(10, txpwridx + 320));
11508                         txgain = bwn_tab_read(mac,
11509                             BWN_TAB_4(10, txpwridx + 192));
11510                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11511                             0xf800, (txgain >> 4) & 0x7fff);
11512                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11513                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11514                 }
11515                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11516
11517                 /* set TX IQCC */
11518                 value[0] = (rxcomp >> 10) & 0x3ff;
11519                 value[1] = rxcomp & 0x3ff;
11520                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11521
11522                 coeff = bwn_tab_read(mac,
11523                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11524                     BWN_TAB_4(10, txpwridx + 448));
11525                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11526                 if (mac->mac_phy.rev >= 2) {
11527                         rfpwr = bwn_tab_read(mac,
11528                             BWN_TAB_4(7, txpwridx + 576));
11529                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11530                             rfpwr & 0xffff);
11531                 }
11532                 bwn_phy_lp_set_txgain_override(mac);
11533         }
11534         if (plp->plp_rccap)
11535                 bwn_phy_lp_set_rccap(mac);
11536         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11537         bwn_phy_lp_set_txpctlmode(mac, mode);
11538         free(tabs, M_DEVBUF);
11539 }
11540
11541 static void
11542 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11543 {
11544         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11545         int i;
11546         static const uint16_t addr[] = {
11547                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11548                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11549                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11550                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11551                 BWN_PHY_OFDM(0xcf),
11552         };
11553
11554         for (i = 0; i < N(addr); i++)
11555                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11556 }
11557
11558 static void
11559 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11560 {
11561         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11562
11563         if (mac->mac_phy.rev < 2) {
11564                 bwn_phy_lp_tblinit_r01(mac);
11565                 bwn_phy_lp_tblinit_txgain(mac);
11566                 bwn_phy_lp_set_gaintbl(mac, freq);
11567                 return;
11568         }
11569
11570         bwn_phy_lp_tblinit_r2(mac);
11571         bwn_phy_lp_tblinit_txgain(mac);
11572 }
11573
11574 struct bwn_wpair {
11575         uint16_t                reg;
11576         uint16_t                value;
11577 };
11578
11579 struct bwn_smpair {
11580         uint16_t                offset;
11581         uint16_t                mask;
11582         uint16_t                set;
11583 };
11584
11585 static void
11586 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11587 {
11588         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11589         struct bwn_softc *sc = mac->mac_sc;
11590         struct ieee80211com *ic = &sc->sc_ic;
11591         static const struct bwn_wpair v1[] = {
11592                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11593                 { BWN_PHY_AFE_CTL, 0x8800 },
11594                 { BWN_PHY_AFE_CTL_OVR, 0 },
11595                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11596                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11597                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11598                 { BWN_PHY_OFDM(0xf9), 0 },
11599                 { BWN_PHY_TR_LOOKUP_1, 0 }
11600         };
11601         static const struct bwn_smpair v2[] = {
11602                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11603                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11604                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11605                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11606                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11607         };
11608         static const struct bwn_smpair v3[] = {
11609                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11610                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11611                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11612                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11613                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11614                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11615                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11616                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11617                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11618                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11619
11620         };
11621         int i;
11622
11623         for (i = 0; i < N(v1); i++)
11624                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11625         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11626         for (i = 0; i < N(v2); i++)
11627                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11628
11629         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11630         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11631         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11632         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11633                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11634                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11635         } else {
11636                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11637         }
11638         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11639         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11640         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11641         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11642         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11643         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11644         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11645         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11646         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11647         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11648         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11649         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11650             (siba_get_chiprev(sc->sc_dev) == 0)) {
11651                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11652                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11653         } else {
11654                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11655                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11656         }
11657         for (i = 0; i < N(v3); i++)
11658                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11659         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11660             (siba_get_chiprev(sc->sc_dev) == 0)) {
11661                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11662                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11663         }
11664
11665         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11666                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11667                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11668                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11669                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11670                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11671                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11672         } else
11673                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11674
11675         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11676         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11677         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11678         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11679         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11680         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11681         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11682             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11683             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11684
11685         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11686             (siba_get_chiprev(sc->sc_dev) == 0)) {
11687                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11688                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11689                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11690         }
11691
11692         bwn_phy_lp_digflt_save(mac);
11693 }
11694
11695 static void
11696 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11697 {
11698         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11699         struct bwn_softc *sc = mac->mac_sc;
11700         struct ieee80211com *ic = &sc->sc_ic;
11701         static const struct bwn_smpair v1[] = {
11702                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11703                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11704                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11705                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11706                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11707                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11708                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11709         };
11710         static const struct bwn_smpair v2[] = {
11711                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11712                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11713                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11714                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11715                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11716                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11717                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11718                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11719                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11720                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11721                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11722                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11723                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11724                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11725                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11726                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11727         };
11728         static const struct bwn_smpair v3[] = {
11729                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11730                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11731                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11732                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11733                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11734                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11735                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11736                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11737         };
11738         static const struct bwn_smpair v4[] = {
11739                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11740                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11741                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11742                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11743                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11744                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11745                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11746                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11747         };
11748         static const struct bwn_smpair v5[] = {
11749                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11750                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11751                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11752                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11753                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11754                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11755                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11756                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11757         };
11758         int i;
11759         uint16_t tmp, tmp2;
11760
11761         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11762         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11763         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11764         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11765         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11766         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11767         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11768         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11769         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11770         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11771         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11772         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11773         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11774         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11775         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11776         for (i = 0; i < N(v1); i++)
11777                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11778         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11779             0xff00, plp->plp_rxpwroffset);
11780         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11781             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11782            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11783                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11784                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11785                 if (mac->mac_phy.rev == 0)
11786                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11787                             0xffcf, 0x0010);
11788                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11789         } else {
11790                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11791                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11792                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11793         }
11794         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11795         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11796         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11797                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11798         else
11799                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11800         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11801         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11802             0xfff9, (plp->plp_bxarch << 1));
11803         if (mac->mac_phy.rev == 1 &&
11804             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11805                 for (i = 0; i < N(v2); i++)
11806                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11807                             v2[i].set);
11808         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11809             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11810             ((mac->mac_phy.rev == 0) &&
11811              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11812                 for (i = 0; i < N(v3); i++)
11813                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11814                             v3[i].set);
11815         } else if (mac->mac_phy.rev == 1 ||
11816                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11817                 for (i = 0; i < N(v4); i++)
11818                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11819                             v4[i].set);
11820         } else {
11821                 for (i = 0; i < N(v5); i++)
11822                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11823                             v5[i].set);
11824         }
11825         if (mac->mac_phy.rev == 1 &&
11826             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11827                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11828                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11829                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11830                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11831         }
11832         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11833             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11834             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11835                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11836                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11837                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11838                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11839         }
11840         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11841                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11842                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11843                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11844                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11845                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11846                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11847                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11848                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11849         } else {
11850                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11851                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11852         }
11853         if (mac->mac_phy.rev == 1) {
11854                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11855                 tmp2 = (tmp & 0x03e0) >> 5;
11856                 tmp2 |= tmp2 << 5;
11857                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11858                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11859                 tmp2 = (tmp & 0x1f00) >> 8;
11860                 tmp2 |= tmp2 << 5;
11861                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11862                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11863                 tmp2 = tmp & 0x00ff;
11864                 tmp2 |= tmp << 8;
11865                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11866         }
11867 }
11868
11869 struct bwn_b2062_freq {
11870         uint16_t                freq;
11871         uint8_t                 value[6];
11872 };
11873
11874 static void
11875 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11876 {
11877 #define CALC_CTL7(freq, div)                                            \
11878         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11879 #define CALC_CTL18(freq, div)                                           \
11880         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11881 #define CALC_CTL19(freq, div)                                           \
11882         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11883         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11884         struct bwn_softc *sc = mac->mac_sc;
11885         struct ieee80211com *ic = &sc->sc_ic;
11886         static const struct bwn_b2062_freq freqdata_tab[] = {
11887                 { 12000, { 6, 6, 6, 6, 10, 6 } },
11888                 { 13000, { 4, 4, 4, 4, 11, 7 } },
11889                 { 14400, { 3, 3, 3, 3, 12, 7 } },
11890                 { 16200, { 3, 3, 3, 3, 13, 8 } },
11891                 { 18000, { 2, 2, 2, 2, 14, 8 } },
11892                 { 19200, { 1, 1, 1, 1, 14, 9 } }
11893         };
11894         static const struct bwn_wpair v1[] = {
11895                 { BWN_B2062_N_TXCTL3, 0 },
11896                 { BWN_B2062_N_TXCTL4, 0 },
11897                 { BWN_B2062_N_TXCTL5, 0 },
11898                 { BWN_B2062_N_TXCTL6, 0 },
11899                 { BWN_B2062_N_PDNCTL0, 0x40 },
11900                 { BWN_B2062_N_PDNCTL0, 0 },
11901                 { BWN_B2062_N_CALIB_TS, 0x10 },
11902                 { BWN_B2062_N_CALIB_TS, 0 }
11903         };
11904         const struct bwn_b2062_freq *f = NULL;
11905         uint32_t xtalfreq, ref;
11906         unsigned int i;
11907
11908         bwn_phy_lp_b2062_tblinit(mac);
11909
11910         for (i = 0; i < N(v1); i++)
11911                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11912         if (mac->mac_phy.rev > 0)
11913                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11914                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11915         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11916                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11917         else
11918                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11919
11920         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11921             ("%s:%d: fail", __func__, __LINE__));
11922         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11923         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11924
11925         if (xtalfreq <= 30000000) {
11926                 plp->plp_div = 1;
11927                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11928         } else {
11929                 plp->plp_div = 2;
11930                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11931         }
11932
11933         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11934             CALC_CTL7(xtalfreq, plp->plp_div));
11935         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11936             CALC_CTL18(xtalfreq, plp->plp_div));
11937         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11938             CALC_CTL19(xtalfreq, plp->plp_div));
11939
11940         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11941         ref &= 0xffff;
11942         for (i = 0; i < N(freqdata_tab); i++) {
11943                 if (ref < freqdata_tab[i].freq) {
11944                         f = &freqdata_tab[i];
11945                         break;
11946                 }
11947         }
11948         if (f == NULL)
11949                 f = &freqdata_tab[N(freqdata_tab) - 1];
11950         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11951             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11952         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11953             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11954         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11955         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11956 #undef CALC_CTL7
11957 #undef CALC_CTL18
11958 #undef CALC_CTL19
11959 }
11960
11961 static void
11962 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
11963 {
11964
11965         bwn_phy_lp_b2063_tblinit(mac);
11966         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
11967         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
11968         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
11969         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
11970         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
11971         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
11972         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
11973         if (mac->mac_phy.rev == 2) {
11974                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
11975                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
11976                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
11977         } else {
11978                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
11979                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
11980         }
11981 }
11982
11983 static void
11984 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
11985 {
11986         struct bwn_softc *sc = mac->mac_sc;
11987         static const struct bwn_wpair v1[] = {
11988                 { BWN_B2063_RX_BB_SP8, 0x0 },
11989                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11990                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11991                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
11992                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
11993                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
11994                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
11995                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
11996         };
11997         static const struct bwn_wpair v2[] = {
11998                 { BWN_B2063_TX_BB_SP3, 0x0 },
11999                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12000                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12001                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12002                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12003         };
12004         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12005         int i;
12006         uint8_t tmp;
12007
12008         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12009
12010         for (i = 0; i < 2; i++)
12011                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12012         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12013         for (i = 2; i < N(v1); i++)
12014                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12015         for (i = 0; i < 10000; i++) {
12016                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12017                         break;
12018                 DELAY(1000);
12019         }
12020
12021         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12022                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12023
12024         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12025
12026         for (i = 0; i < N(v2); i++)
12027                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12028         if (freqxtal == 24000000) {
12029                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12030                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12031         } else {
12032                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12033                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12034         }
12035         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12036         for (i = 0; i < 10000; i++) {
12037                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12038                         break;
12039                 DELAY(1000);
12040         }
12041         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12042                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12043         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12044 }
12045
12046 static void
12047 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12048 {
12049         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12050         struct bwn_softc *sc = mac->mac_sc;
12051         struct bwn_phy_lp_iq_est ie;
12052         struct bwn_txgain tx_gains;
12053         static const uint32_t pwrtbl[21] = {
12054                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12055                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12056                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12057                 0x0004c, 0x0002c, 0x0001a,
12058         };
12059         uint32_t npwr, ipwr, sqpwr, tmp;
12060         int loopback, i, j, sum, error;
12061         uint16_t save[7];
12062         uint8_t txo, bbmult, txpctlmode;
12063
12064         error = bwn_phy_lp_switch_channel(mac, 7);
12065         if (error)
12066                 device_printf(sc->sc_dev,
12067                     "failed to change channel to 7 (%d)\n", error);
12068         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12069         bbmult = bwn_phy_lp_get_bbmult(mac);
12070         if (txo)
12071                 tx_gains = bwn_phy_lp_get_txgain(mac);
12072
12073         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12074         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12075         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12076         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12077         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12078         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12079         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12080
12081         bwn_phy_lp_get_txpctlmode(mac);
12082         txpctlmode = plp->plp_txpctlmode;
12083         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12084
12085         /* disable CRS */
12086         bwn_phy_lp_set_deaf(mac, 1);
12087         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12088         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12089         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12090         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12091         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12092         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12093         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12094         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12095         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12096         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12097         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12098         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12099         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12100         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12101         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12102         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12103         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12104         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12105         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12106         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12107         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12108         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12109         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12110         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12111
12112         loopback = bwn_phy_lp_loopback(mac);
12113         if (loopback == -1)
12114                 goto done;
12115         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12116         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12117         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12118         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12119         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12120
12121         tmp = 0;
12122         memset(&ie, 0, sizeof(ie));
12123         for (i = 128; i <= 159; i++) {
12124                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12125                 sum = 0;
12126                 for (j = 5; j <= 25; j++) {
12127                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12128                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12129                                 goto done;
12130                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12131                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12132                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12133                             12);
12134                         sum += ((ipwr - npwr) * (ipwr - npwr));
12135                         if ((i == 128) || (sum < tmp)) {
12136                                 plp->plp_rccap = i;
12137                                 tmp = sum;
12138                         }
12139                 }
12140         }
12141         bwn_phy_lp_ddfs_turnoff(mac);
12142 done:
12143         /* restore CRS */
12144         bwn_phy_lp_clear_deaf(mac, 1);
12145         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12146         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12147
12148         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12149         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12150         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12151         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12152         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12153         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12154         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12155
12156         bwn_phy_lp_set_bbmult(mac, bbmult);
12157         if (txo)
12158                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12159         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12160         if (plp->plp_rccap)
12161                 bwn_phy_lp_set_rccap(mac);
12162 }
12163
12164 static void
12165 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12166 {
12167         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12168         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12169
12170         if (mac->mac_phy.rev == 1)
12171                 rc_cap = MIN(rc_cap + 5, 15);
12172
12173         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12174             MAX(plp->plp_rccap - 4, 0x80));
12175         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12176         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12177             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12178 }
12179
12180 static uint32_t
12181 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12182 {
12183         uint32_t i, q, r;
12184
12185         if (div == 0)
12186                 return (0);
12187
12188         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12189                 q <<= 1;
12190                 if (r << 1 >= div) {
12191                         q++;
12192                         r = (r << 1) - div;
12193                 }
12194         }
12195         if (r << 1 >= div)
12196                 q++;
12197         return (q);
12198 }
12199
12200 static void
12201 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12202 {
12203         struct bwn_softc *sc = mac->mac_sc;
12204
12205         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12206         DELAY(20);
12207         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12208                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12209                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12210         } else {
12211                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12212         }
12213         DELAY(5);
12214 }
12215
12216 static void
12217 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12218 {
12219
12220         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12221         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12222         DELAY(200);
12223 }
12224
12225 static void
12226 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12227 {
12228 #define FLAG_A  0x01
12229 #define FLAG_G  0x02
12230         struct bwn_softc *sc = mac->mac_sc;
12231         struct ieee80211com *ic = &sc->sc_ic;
12232         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12233                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12234                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12235                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12236                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12237                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12238                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12239                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12240                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12241                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12242                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12243                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12244                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12245                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12246                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12247                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12248                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12249                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12250                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12251                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12252                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12253                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12254                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12255                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12256                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12257                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12258                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12259                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12260                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12261                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12262                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12263                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12264                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12265                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12266                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12267                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12268                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12269                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12270                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12271                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12272                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12273                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12274                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12275                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12276                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12277                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12278                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12279                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12280         };
12281         const struct bwn_b206x_rfinit_entry *br;
12282         unsigned int i;
12283
12284         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12285                 br = &bwn_b2062_init_tab[i];
12286                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12287                         if (br->br_flags & FLAG_G)
12288                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12289                 } else {
12290                         if (br->br_flags & FLAG_A)
12291                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12292                 }
12293         }
12294 #undef FLAG_A
12295 #undef FLAG_B
12296 }
12297
12298 static void
12299 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12300 {
12301 #define FLAG_A  0x01
12302 #define FLAG_G  0x02
12303         struct bwn_softc *sc = mac->mac_sc;
12304         struct ieee80211com *ic = &sc->sc_ic;
12305         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12306                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12307                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12308                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12309                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12310                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12311                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12312                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12313                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12314                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12315                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12316                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12317                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12318                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12319                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12320                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12321                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12322                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12323                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12324                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12325                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12326                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12327                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12328                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12329                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12330                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12331                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12332                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12333                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12334                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12335                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12336                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12337                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12338                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12339                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12340                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12341                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12342                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12343                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12344                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12345                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12346                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12347                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12348         };
12349         const struct bwn_b206x_rfinit_entry *br;
12350         unsigned int i;
12351
12352         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12353                 br = &bwn_b2063_init_tab[i];
12354                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12355                         if (br->br_flags & FLAG_G)
12356                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12357                 } else {
12358                         if (br->br_flags & FLAG_A)
12359                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12360                 }
12361         }
12362 #undef FLAG_A
12363 #undef FLAG_B
12364 }
12365
12366 static void
12367 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12368     int count, void *_data)
12369 {
12370         unsigned int i;
12371         uint32_t offset, type;
12372         uint8_t *data = _data;
12373
12374         type = BWN_TAB_GETTYPE(typenoffset);
12375         offset = BWN_TAB_GETOFFSET(typenoffset);
12376         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12377
12378         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12379
12380         for (i = 0; i < count; i++) {
12381                 switch (type) {
12382                 case BWN_TAB_8BIT:
12383                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12384                         data++;
12385                         break;
12386                 case BWN_TAB_16BIT:
12387                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12388                             BWN_PHY_TABLEDATALO);
12389                         data += 2;
12390                         break;
12391                 case BWN_TAB_32BIT:
12392                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12393                             BWN_PHY_TABLEDATAHI);
12394                         *((uint32_t *)data) <<= 16;
12395                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12396                             BWN_PHY_TABLEDATALO);
12397                         data += 4;
12398                         break;
12399                 default:
12400                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12401                 }
12402         }
12403 }
12404
12405 static void
12406 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12407     int count, const void *_data)
12408 {
12409         uint32_t offset, type, value;
12410         const uint8_t *data = _data;
12411         unsigned int i;
12412
12413         type = BWN_TAB_GETTYPE(typenoffset);
12414         offset = BWN_TAB_GETOFFSET(typenoffset);
12415         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12416
12417         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12418
12419         for (i = 0; i < count; i++) {
12420                 switch (type) {
12421                 case BWN_TAB_8BIT:
12422                         value = *data;
12423                         data++;
12424                         KASSERT(!(value & ~0xff),
12425                             ("%s:%d: fail", __func__, __LINE__));
12426                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12427                         break;
12428                 case BWN_TAB_16BIT:
12429                         value = *((const uint16_t *)data);
12430                         data += 2;
12431                         KASSERT(!(value & ~0xffff),
12432                             ("%s:%d: fail", __func__, __LINE__));
12433                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12434                         break;
12435                 case BWN_TAB_32BIT:
12436                         value = *((const uint32_t *)data);
12437                         data += 4;
12438                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12439                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12440                         break;
12441                 default:
12442                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12443                 }
12444         }
12445 }
12446
12447 static struct bwn_txgain
12448 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12449 {
12450         struct bwn_txgain tg;
12451         uint16_t tmp;
12452
12453         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12454         if (mac->mac_phy.rev < 2) {
12455                 tmp = BWN_PHY_READ(mac,
12456                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12457                 tg.tg_gm = tmp & 0x0007;
12458                 tg.tg_pga = (tmp & 0x0078) >> 3;
12459                 tg.tg_pad = (tmp & 0x780) >> 7;
12460                 return (tg);
12461         }
12462
12463         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12464         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12465         tg.tg_gm = tmp & 0xff;
12466         tg.tg_pga = (tmp >> 8) & 0xff;
12467         return (tg);
12468 }
12469
12470 static uint8_t
12471 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12472 {
12473
12474         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12475 }
12476
12477 static void
12478 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12479 {
12480         uint16_t pa;
12481
12482         if (mac->mac_phy.rev < 2) {
12483                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12484                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12485                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12486                 bwn_phy_lp_set_txgain_override(mac);
12487                 return;
12488         }
12489
12490         pa = bwn_phy_lp_get_pa_gain(mac);
12491         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12492             (tg->tg_pga << 8) | tg->tg_gm);
12493         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12494             tg->tg_pad | (pa << 6));
12495         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12496         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12497             tg->tg_pad | (pa << 8));
12498         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12499         bwn_phy_lp_set_txgain_override(mac);
12500 }
12501
12502 static void
12503 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12504 {
12505
12506         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12507 }
12508
12509 static void
12510 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12511 {
12512         uint16_t trsw = (tx << 1) | rx;
12513
12514         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12515         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12516 }
12517
12518 static void
12519 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12520 {
12521         struct bwn_softc *sc = mac->mac_sc;
12522         struct ieee80211com *ic = &sc->sc_ic;
12523         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12524
12525         if (mac->mac_phy.rev < 2) {
12526                 trsw = gain & 0x1;
12527                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12528                 ext_lna = (gain & 2) >> 1;
12529
12530                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12531                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12532                     0xfbff, ext_lna << 10);
12533                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12534                     0xf7ff, ext_lna << 11);
12535                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12536         } else {
12537                 low_gain = gain & 0xffff;
12538                 high_gain = (gain >> 16) & 0xf;
12539                 ext_lna = (gain >> 21) & 0x1;
12540                 trsw = ~(gain >> 20) & 0x1;
12541
12542                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12543                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12544                     0xfdff, ext_lna << 9);
12545                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12546                     0xfbff, ext_lna << 10);
12547                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12548                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12549                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12550                         tmp = (gain >> 2) & 0x3;
12551                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12552                             0xe7ff, tmp<<11);
12553                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12554                             tmp << 3);
12555                 }
12556         }
12557
12558         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12559         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12560         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12561         if (mac->mac_phy.rev >= 2) {
12562                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12563                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12564                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12565                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12566                 }
12567                 return;
12568         }
12569         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12570 }
12571
12572 static void
12573 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12574 {
12575         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12576
12577         if (user)
12578                 plp->plp_crsusr_off = 1;
12579         else
12580                 plp->plp_crssys_off = 1;
12581
12582         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12583 }
12584
12585 static void
12586 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12587 {
12588         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12589         struct bwn_softc *sc = mac->mac_sc;
12590         struct ieee80211com *ic = &sc->sc_ic;
12591
12592         if (user)
12593                 plp->plp_crsusr_off = 0;
12594         else
12595                 plp->plp_crssys_off = 0;
12596
12597         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12598                 return;
12599
12600         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12601                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12602         else
12603                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12604 }
12605
12606 static unsigned int
12607 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12608 {
12609         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12610         static uint8_t sqrt_table[256] = {
12611                 10, 14, 17, 20, 22, 24, 26, 28,
12612                 30, 31, 33, 34, 36, 37, 38, 40,
12613                 41, 42, 43, 44, 45, 46, 47, 48,
12614                 50, 50, 51, 52, 53, 54, 55, 56,
12615                 57, 58, 59, 60, 60, 61, 62, 63,
12616                 64, 64, 65, 66, 67, 67, 68, 69,
12617                 70, 70, 71, 72, 72, 73, 74, 74,
12618                 75, 76, 76, 77, 78, 78, 79, 80,
12619                 80, 81, 81, 82, 83, 83, 84, 84,
12620                 85, 86, 86, 87, 87, 88, 88, 89,
12621                 90, 90, 91, 91, 92, 92, 93, 93,
12622                 94, 94, 95, 95, 96, 96, 97, 97,
12623                 98, 98, 99, 100, 100, 100, 101, 101,
12624                 102, 102, 103, 103, 104, 104, 105, 105,
12625                 106, 106, 107, 107, 108, 108, 109, 109,
12626                 110, 110, 110, 111, 111, 112, 112, 113,
12627                 113, 114, 114, 114, 115, 115, 116, 116,
12628                 117, 117, 117, 118, 118, 119, 119, 120,
12629                 120, 120, 121, 121, 122, 122, 122, 123,
12630                 123, 124, 124, 124, 125, 125, 126, 126,
12631                 126, 127, 127, 128, 128, 128, 129, 129,
12632                 130, 130, 130, 131, 131, 131, 132, 132,
12633                 133, 133, 133, 134, 134, 134, 135, 135,
12634                 136, 136, 136, 137, 137, 137, 138, 138,
12635                 138, 139, 139, 140, 140, 140, 141, 141,
12636                 141, 142, 142, 142, 143, 143, 143, 144,
12637                 144, 144, 145, 145, 145, 146, 146, 146,
12638                 147, 147, 147, 148, 148, 148, 149, 149,
12639                 150, 150, 150, 150, 151, 151, 151, 152,
12640                 152, 152, 153, 153, 153, 154, 154, 154,
12641                 155, 155, 155, 156, 156, 156, 157, 157,
12642                 157, 158, 158, 158, 159, 159, 159, 160
12643         };
12644
12645         if (x == 0)
12646                 return (0);
12647         if (x >= 256) {
12648                 unsigned int tmp;
12649
12650                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12651                         /* do nothing */ ;
12652                 return (tmp);
12653         }
12654         return (sqrt_table[x - 1] / 10);
12655 }
12656
12657 static int
12658 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12659 {
12660 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12661         int _t;                                                         \
12662         _t = _x - 20;                                                   \
12663         if (_t >= 0) {                                                  \
12664                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12665         } else {                                                        \
12666                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12667         }                                                               \
12668 } while (0)
12669 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12670         int _t;                                                         \
12671         _t = _x - 11;                                                   \
12672         if (_t >= 0)                                                    \
12673                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12674         else                                                            \
12675                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12676 } while (0)
12677         struct bwn_phy_lp_iq_est ie;
12678         uint16_t v0, v1;
12679         int tmp[2], ret;
12680
12681         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12682         v0 = v1 >> 8;
12683         v1 |= 0xff;
12684
12685         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12686         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12687
12688         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12689         if (ret == 0)
12690                 goto done;
12691
12692         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12693                 ret = 0;
12694                 goto done;
12695         }
12696
12697         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12698         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12699
12700         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12701         v0 = tmp[0] >> 3;
12702         v1 = tmp[1] >> 4;
12703 done:
12704         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12705         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12706         return ret;
12707 #undef CALC_COEFF
12708 #undef CALC_COEFF2
12709 }
12710
12711 static void
12712 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12713 {
12714         static const uint16_t noisescale[] = {
12715                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12716                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12717                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12718                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12719                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12720         };
12721         static const uint16_t crsgainnft[] = {
12722                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12723                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12724                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12725                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12726                 0x013d,
12727         };
12728         static const uint16_t filterctl[] = {
12729                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12730                 0xff53, 0x0127,
12731         };
12732         static const uint32_t psctl[] = {
12733                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12734                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12735                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12736                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12737                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12738                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12739                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12740                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12741         };
12742         static const uint16_t ofdmcckgain_r0[] = {
12743                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12744                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12745                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12746                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12747                 0x755d,
12748         };
12749         static const uint16_t ofdmcckgain_r1[] = {
12750                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12751                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12752                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12753                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12754                 0x755d,
12755         };
12756         static const uint16_t gaindelta[] = {
12757                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12758                 0x0000,
12759         };
12760         static const uint32_t txpwrctl[] = {
12761                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12762                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12763                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12764                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12765                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12766                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12767                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12768                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12769                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12770                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12771                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12772                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12773                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12774                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12775                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12776                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12777                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12778                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12779                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12780                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12781                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12782                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12783                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12784                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12785                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12786                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12787                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12788                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12789                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12790                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12791                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12792                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12793                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12794                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12795                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12796                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12797                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12798                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12799                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12800                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12801                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12802                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12803                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12804                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12805                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12806                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12807                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12808                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12809                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12810                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12811                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12812                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12813                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12814                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12815                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12816                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12817                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12818                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12819                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12820                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12821                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12822                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12823                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12824                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12825                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12826                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12827                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12828                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12829                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12830                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12831                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12832                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12833                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12834                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12835                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12836                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12837                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12838                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12839                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12840                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12841                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12842                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12843                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12844                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12845                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12846                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12847                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12848                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12849                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12850                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12851                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12852                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12853                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12854                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12855                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12856                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12857                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12858                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12859                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12860                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12861                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12862                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12863                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12864                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12865                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12866                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12867                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12868                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12869                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12870                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12871                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12872                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12873                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12874                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12875                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12876                 0x00000702,
12877         };
12878
12879         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12880
12881         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12882             bwn_tab_sigsq_tbl);
12883         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12884         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12885         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12886         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12887         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12888             bwn_tab_pllfrac_tbl);
12889         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12890             bwn_tabl_iqlocal_tbl);
12891         if (mac->mac_phy.rev == 0) {
12892                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12893                     ofdmcckgain_r0);
12894                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12895                     ofdmcckgain_r0);
12896         } else {
12897                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12898                     ofdmcckgain_r1);
12899                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12900                     ofdmcckgain_r1);
12901         }
12902         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12903         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12904 }
12905
12906 static void
12907 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12908 {
12909         struct bwn_softc *sc = mac->mac_sc;
12910         int i;
12911         static const uint16_t noisescale[] = {
12912                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12913                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12914                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12915                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12916                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12917                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12918                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12919         };
12920         static const uint32_t filterctl[] = {
12921                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12922                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12923         };
12924         static const uint32_t psctl[] = {
12925                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12926                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12927                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12928                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12929         };
12930         static const uint32_t gainidx[] = {
12931                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12935                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12936                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12937                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12938                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12939                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12940                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12941                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12942                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12943                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12944                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12945                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12946                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12950                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12951                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12952                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12953                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
12954                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
12955                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
12956                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
12957                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
12958                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
12959                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
12960                 0x0000001a, 0x64ca55ad, 0x0000001a
12961         };
12962         static const uint16_t auxgainidx[] = {
12963                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12964                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
12965                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
12966                 0x0004, 0x0016
12967         };
12968         static const uint16_t swctl[] = {
12969                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12970                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12971                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12972                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
12973                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12974                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12975                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12976                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
12977         };
12978         static const uint8_t hf[] = {
12979                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
12980                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
12981         };
12982         static const uint32_t gainval[] = {
12983                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
12984                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
12985                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
12986                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
12987                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
12988                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
12989                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12990                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
12992                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
12993                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
12994                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
12995                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
12996                 0x000000f1, 0x00000000, 0x00000000
12997         };
12998         static const uint16_t gain[] = {
12999                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13000                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13001                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13002                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13003                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13004                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13005                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13006                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13007                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13008                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13009                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13010                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13011         };
13012         static const uint32_t papdeps[] = {
13013                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13014                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13015                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13016                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13017                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13018                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13019                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13020                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13021                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13022                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13023                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13024                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13025                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13026         };
13027         static const uint32_t papdmult[] = {
13028                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13029                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13030                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13031                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13032                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13033                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13034                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13035                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13036                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13037                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13038                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13039                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13040                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13041         };
13042         static const uint32_t gainidx_a0[] = {
13043                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13044                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13045                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13046                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13047                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13048                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13049                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13050                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13051                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13052                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13053                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13054                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13055                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13056         };
13057         static const uint16_t auxgainidx_a0[] = {
13058                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13059                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13060                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13061                 0x0002, 0x0014
13062         };
13063         static const uint32_t gainval_a0[] = {
13064                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13065                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13066                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13067                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13068                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13069                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13070                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13071                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13072                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13073                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13074                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13075                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13076                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13077                 0x000000f7, 0x00000000, 0x00000000
13078         };
13079         static const uint16_t gain_a0[] = {
13080                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13081                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13082                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13083                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13084                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13085                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13086                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13087                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13088                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13089                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13090                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13091                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13092         };
13093
13094         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13095
13096         for (i = 0; i < 704; i++)
13097                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13098
13099         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13100             bwn_tab_sigsq_tbl);
13101         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13102         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13103         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13104         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13105         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13106         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13107         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13108         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13109         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13110         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13111             bwn_tab_pllfrac_tbl);
13112         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13113             bwn_tabl_iqlocal_tbl);
13114         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13115         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13116
13117         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13118             (siba_get_chiprev(sc->sc_dev) == 0)) {
13119                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13120                     gainidx_a0);
13121                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13122                     auxgainidx_a0);
13123                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13124                     gainval_a0);
13125                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13126         }
13127 }
13128
13129 static void
13130 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13131 {
13132         struct bwn_softc *sc = mac->mac_sc;
13133         struct ieee80211com *ic = &sc->sc_ic;
13134         static struct bwn_txgain_entry txgain_r2[] = {
13135                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13136                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13137                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13138                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13139                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13140                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13141                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13142                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13143                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13144                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13145                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13146                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13147                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13148                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13149                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13150                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13151                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13152                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13153                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13154                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13155                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13156                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13157                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13158                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13159                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13160                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13161                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13162                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13163                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13164                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13165                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13166                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13167                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13168                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13169                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13170                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13171                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13172                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13173                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13174                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13175                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13176                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13177                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13178                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13179                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13180                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13181                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13182                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13183                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13184                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13185                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13186                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13187                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13188                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13189                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13190                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13191                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13192                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13193                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13194                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13195                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13196                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13197                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13198                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13199         };
13200         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13201                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13202                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13203                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13204                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13205                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13206                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13207                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13208                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13209                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13210                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13211                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13212                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13213                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13214                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13215                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13216                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13217                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13218                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13219                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13220                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13221                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13222                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13223                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13224                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13225                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13226                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13227                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13228                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13229                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13230                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13231                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13232                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13233                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13234                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13235                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13236                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13237                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13238                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13239                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13240                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13241                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13242                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13243                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13244                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13245                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13246                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13247                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13248                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13249                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13250                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13251                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13252                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13253                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13254                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13255                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13256                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13257                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13258                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13259                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13260                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13261                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13262                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13263                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13264                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13265         };
13266         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13267                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13268                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13269                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13270                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13271                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13272                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13273                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13274                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13275                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13276                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13277                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13278                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13279                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13280                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13281                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13282                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13283                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13284                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13285                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13286                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13287                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13288                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13289                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13290                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13291                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13292                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13293                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13294                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13295                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13296                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13297                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13298                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13299                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13300                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13301                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13302                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13303                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13304                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13305                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13306                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13307                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13308                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13309                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13310                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13311                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13312                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13313                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13314                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13315                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13316                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13317                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13318                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13319                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13320                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13321                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13322                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13323                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13324                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13325                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13326                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13327                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13328                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13329                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13330                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13331         };
13332         static struct bwn_txgain_entry txgain_r0[] = {
13333                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13334                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13335                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13336                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13337                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13338                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13339                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13340                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13341                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13342                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13343                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13344                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13345                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13346                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13347                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13348                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13349                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13350                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13351                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13352                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13353                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13354                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13355                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13356                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13357                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13358                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13359                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13360                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13361                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13362                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13363                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13364                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13365                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13366                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13367                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13368                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13369                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13370                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13371                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13372                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13373                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13374                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13375                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13376                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13377                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13378                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13379                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13380                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13381                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13382                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13383                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13384                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13385                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13386                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13387                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13388                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13389                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13390                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13391                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13392                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13393                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13394                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13395                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13396                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13397         };
13398         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13399                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13400                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13401                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13402                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13403                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13404                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13405                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13406                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13407                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13408                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13409                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13410                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13411                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13412                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13413                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13414                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13415                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13416                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13417                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13418                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13419                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13420                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13421                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13422                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13423                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13424                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13425                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13426                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13427                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13428                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13429                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13430                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13431                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13432                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13433                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13434                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13435                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13436                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13437                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13438                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13439                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13440                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13441                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13442                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13443                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13444                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13445                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13446                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13447                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13448                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13449                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13450                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13451                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13452                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13453                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13454                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13455                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13456                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13457                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13458                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13459                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13460                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13461                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13462                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13463         };
13464         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13465                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13466                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13467                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13468                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13469                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13470                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13471                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13472                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13473                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13474                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13475                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13476                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13477                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13478                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13479                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13480                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13481                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13482                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13483                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13484                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13485                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13486                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13487                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13488                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13489                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13490                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13491                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13492                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13493                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13494                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13495                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13496                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13497                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13498                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13499                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13500                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13501                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13502                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13503                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13504                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13505                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13506                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13507                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13508                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13509                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13510                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13511                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13512                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13513                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13514                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13515                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13516                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13517                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13518                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13519                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13520                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13521                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13522                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13523                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13524                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13525                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13526                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13527                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13528                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13529         };
13530         static struct bwn_txgain_entry txgain_r1[] = {
13531                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13532                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13533                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13534                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13535                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13536                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13537                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13538                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13539                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13540                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13541                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13542                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13543                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13544                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13545                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13546                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13547                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13548                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13549                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13550                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13551                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13552                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13553                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13554                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13555                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13556                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13557                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13558                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13559                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13560                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13561                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13562                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13563                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13564                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13565                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13566                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13567                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13568                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13569                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13570                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13571                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13572                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13573                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13574                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13575                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13576                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13577                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13578                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13579                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13580                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13581                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13582                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13583                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13584                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13585                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13586                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13587                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13588                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13589                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13590                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13591                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13592                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13593                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13594                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13595                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13596                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13597                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13598                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13599                 { 7, 11, 6, 0, 71 }
13600         };
13601         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13602                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13603                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13604                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13605                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13606                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13607                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13608                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13609                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13610                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13611                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13612                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13613                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13614                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13615                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13616                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13617                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13618                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13619                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13620                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13621                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13622                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13623                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13624                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13625                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13626                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13627                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13628                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13629                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13630                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13631                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13632                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13633                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13634                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13635                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13636                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13637                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13638                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13639                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13640                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13641                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13642                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13643                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13644                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13645                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13646                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13647                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13648                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13649                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13650                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13651                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13652                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13653                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13654                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13655                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13656                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13657                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13658                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13659                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13660                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13661                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13662                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13663                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13664                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13665                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13666         };
13667         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13668                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13669                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13670                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13671                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13672                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13673                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13674                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13675                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13676                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13677                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13678                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13679                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13680                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13681                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13682                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13683                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13684                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13685                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13686                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13687                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13688                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13689                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13690                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13691                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13692                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13693                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13694                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13695                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13696                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13697                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13698                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13699                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13700                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13701                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13702                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13703                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13704                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13705                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13706                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13707                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13708                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13709                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13710                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13711                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13712                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13713                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13714                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13715                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13716                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13717                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13718                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13719                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13720                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13721                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13722                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13723                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13724                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13725                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13726                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13727                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13728                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13729                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13730                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13731                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13732         };
13733
13734         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13735                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13736                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13737                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13738                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13739                             txgain_2ghz_r2);
13740                 else
13741                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13742                             txgain_5ghz_r2);
13743                 return;
13744         }
13745
13746         if (mac->mac_phy.rev == 0) {
13747                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13748                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13749                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13750                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13751                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13752                             txgain_2ghz_r0);
13753                 else
13754                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13755                             txgain_5ghz_r0);
13756                 return;
13757         }
13758
13759         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13760             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13761                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13762         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13763                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13764         else
13765                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13766 }
13767
13768 static void
13769 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13770 {
13771         uint32_t offset, type;
13772
13773         type = BWN_TAB_GETTYPE(typeoffset);
13774         offset = BWN_TAB_GETOFFSET(typeoffset);
13775         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13776
13777         switch (type) {
13778         case BWN_TAB_8BIT:
13779                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13780                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13781                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13782                 break;
13783         case BWN_TAB_16BIT:
13784                 KASSERT(!(value & ~0xffff),
13785                     ("%s:%d: fail", __func__, __LINE__));
13786                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13787                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13788                 break;
13789         case BWN_TAB_32BIT:
13790                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13791                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13792                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13793                 break;
13794         default:
13795                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13796         }
13797 }
13798
13799 static int
13800 bwn_phy_lp_loopback(struct bwn_mac *mac)
13801 {
13802         struct bwn_phy_lp_iq_est ie;
13803         int i, index = -1;
13804         uint32_t tmp;
13805
13806         memset(&ie, 0, sizeof(ie));
13807
13808         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13809         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13810         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13811         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13812         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13813         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13814         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13815         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13816         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13817         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13818         for (i = 0; i < 32; i++) {
13819                 bwn_phy_lp_set_rxgain_idx(mac, i);
13820                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13821                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13822                         continue;
13823                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13824                 if ((tmp > 4000) && (tmp < 10000)) {
13825                         index = i;
13826                         break;
13827                 }
13828         }
13829         bwn_phy_lp_ddfs_turnoff(mac);
13830         return (index);
13831 }
13832
13833 static void
13834 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13835 {
13836
13837         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13838 }
13839
13840 static void
13841 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13842     int incr1, int incr2, int scale_idx)
13843 {
13844
13845         bwn_phy_lp_ddfs_turnoff(mac);
13846         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13847         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13848         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13849         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13850         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13851         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13852         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13853         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13854         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13855         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13856 }
13857
13858 static uint8_t
13859 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13860     struct bwn_phy_lp_iq_est *ie)
13861 {
13862         int i;
13863
13864         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13865         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13866         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13867         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13868         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13869
13870         for (i = 0; i < 500; i++) {
13871                 if (!(BWN_PHY_READ(mac,
13872                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13873                         break;
13874                 DELAY(1000);
13875         }
13876         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13877                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13878                 return 0;
13879         }
13880
13881         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13882         ie->ie_iqprod <<= 16;
13883         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13884         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13885         ie->ie_ipwr <<= 16;
13886         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13887         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13888         ie->ie_qpwr <<= 16;
13889         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13890
13891         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13892         return 1;
13893 }
13894
13895 static uint32_t
13896 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13897 {
13898         uint32_t offset, type, value;
13899
13900         type = BWN_TAB_GETTYPE(typeoffset);
13901         offset = BWN_TAB_GETOFFSET(typeoffset);
13902         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13903
13904         switch (type) {
13905         case BWN_TAB_8BIT:
13906                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13907                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13908                 break;
13909         case BWN_TAB_16BIT:
13910                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13911                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13912                 break;
13913         case BWN_TAB_32BIT:
13914                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13915                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13916                 value <<= 16;
13917                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13918                 break;
13919         default:
13920                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13921                 value = 0;
13922         }
13923
13924         return (value);
13925 }
13926
13927 static void
13928 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13929 {
13930
13931         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13932         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13933 }
13934
13935 static void
13936 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13937 {
13938         uint16_t ctl;
13939
13940         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13941         ctl |= dac << 7;
13942         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13943 }
13944
13945 static void
13946 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13947 {
13948
13949         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13950         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13951 }
13952
13953 static void
13954 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
13955 {
13956
13957         if (mac->mac_phy.rev < 2)
13958                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
13959         else {
13960                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
13961                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
13962         }
13963         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
13964 }
13965
13966 static uint16_t
13967 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
13968 {
13969
13970         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
13971 }
13972
13973 static uint8_t
13974 bwn_nbits(int32_t val)
13975 {
13976         uint32_t tmp;
13977         uint8_t nbits = 0;
13978
13979         for (tmp = abs(val); tmp != 0; tmp >>= 1)
13980                 nbits++;
13981         return (nbits);
13982 }
13983
13984 static void
13985 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
13986     struct bwn_txgain_entry *table)
13987 {
13988         int i;
13989
13990         for (i = offset; i < count; i++)
13991                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
13992 }
13993
13994 static void
13995 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
13996     struct bwn_txgain_entry data)
13997 {
13998
13999         if (mac->mac_phy.rev >= 2)
14000                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14001         else
14002                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14003 }
14004
14005 static void
14006 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14007     struct bwn_txgain_entry te)
14008 {
14009         struct bwn_softc *sc = mac->mac_sc;
14010         struct ieee80211com *ic = &sc->sc_ic;
14011         uint32_t tmp;
14012
14013         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14014
14015         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14016         if (mac->mac_phy.rev >= 3) {
14017                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14018                     (0x10 << 24) : (0x70 << 24));
14019         } else {
14020                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14021                     (0x14 << 24) : (0x7f << 24));
14022         }
14023         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14024         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14025             te.te_bbmult << 20 | te.te_dac << 28);
14026 }
14027
14028 static void
14029 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14030     struct bwn_txgain_entry te)
14031 {
14032
14033         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14034
14035         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14036             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14037             te.te_dac);
14038         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14039 }
14040
14041 static void
14042 bwn_sysctl_node(struct bwn_softc *sc)
14043 {
14044         device_t dev = sc->sc_dev;
14045         struct bwn_mac *mac;
14046         struct bwn_stats *stats;
14047
14048         /* XXX assume that count of MAC is only 1. */
14049
14050         if ((mac = sc->sc_curmac) == NULL)
14051                 return;
14052         stats = &mac->mac_stats;
14053
14054         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14055             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14056             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14057         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14058             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14059             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14060         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14061             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14062             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14063
14064 #ifdef BWN_DEBUG
14065         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14066             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14067             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14068 #endif
14069 }
14070
14071 static device_method_t bwn_methods[] = {
14072         /* Device interface */
14073         DEVMETHOD(device_probe,         bwn_probe),
14074         DEVMETHOD(device_attach,        bwn_attach),
14075         DEVMETHOD(device_detach,        bwn_detach),
14076         DEVMETHOD(device_suspend,       bwn_suspend),
14077         DEVMETHOD(device_resume,        bwn_resume),
14078         DEVMETHOD_END
14079 };
14080 static driver_t bwn_driver = {
14081         "bwn",
14082         bwn_methods,
14083         sizeof(struct bwn_softc)
14084 };
14085 static devclass_t bwn_devclass;
14086 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14087 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14088 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14089 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14090 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);