]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/dev/bwn/if_bwn.c
MFC r205003:
[FreeBSD/stable/8.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
60
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_amrr.h>
71 #include <net80211/ieee80211_phy.h>
72
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
75
76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
77
78 /*
79  * Tunable & sysctl variables.
80  */
81
82 #ifdef BWN_DEBUG
83 static  int bwn_debug = 0;
84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
85     "Broadcom debugging printfs");
86 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
87 enum {
88         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
89         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
90         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
91         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
92         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
93         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
94         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
95         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
96         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
97         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
98         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
99         BWN_DEBUG_LED           = 0x00000800,   /* led management */
100         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
101         BWN_DEBUG_LO            = 0x00002000,   /* LO */
102         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
103         BWN_DEBUG_WME           = 0x00008000,   /* WME */
104         BWN_DEBUG_RF            = 0x00010000,   /* RF */
105         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
106         BWN_DEBUG_ANY           = 0xffffffff
107 };
108 #define DPRINTF(sc, m, fmt, ...) do {                   \
109         if (sc->sc_debug & (m))                         \
110                 printf(fmt, __VA_ARGS__);               \
111 } while (0)
112 #else
113 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
114 #endif
115
116 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
118     "uses Bad Frames Preemption");
119 static int      bwn_bluetooth = 1;
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
121     "turns on Bluetooth Coexistence");
122 static int      bwn_hwpctl = 0;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
124     "uses H/W power control");
125 static int      bwn_msi_disable = 0;            /* MSI disabled  */
126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
127 static int      bwn_usedma = 1;
128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
129     "uses DMA");
130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
131 static int      bwn_wme = 1;
132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
133     "uses WME support");
134
135 static int      bwn_attach_pre(struct bwn_softc *);
136 static int      bwn_attach_post(struct bwn_softc *);
137 static void     bwn_sprom_bugfixes(device_t);
138 static void     bwn_init(void *);
139 static int      bwn_init_locked(struct bwn_softc *);
140 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t);
141 static void     bwn_start(struct ifnet *);
142 static int      bwn_attach_core(struct bwn_mac *);
143 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
144 static int      bwn_phy_getinfo(struct bwn_mac *, int);
145 static int      bwn_chiptest(struct bwn_mac *);
146 static int      bwn_setup_channels(struct bwn_mac *, int, int);
147 static int      bwn_phy_g_attach(struct bwn_mac *);
148 static void     bwn_phy_g_detach(struct bwn_mac *);
149 static void     bwn_phy_g_init_pre(struct bwn_mac *);
150 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
151 static int      bwn_phy_g_init(struct bwn_mac *);
152 static void     bwn_phy_g_exit(struct bwn_mac *);
153 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
154 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
155                     uint16_t);
156 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
157 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
158                     uint16_t);
159 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
160 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
161 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
162 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
163 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
164 static int      bwn_phy_g_im(struct bwn_mac *, int);
165 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
166 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
167 static void     bwn_phy_g_task_15s(struct bwn_mac *);
168 static void     bwn_phy_g_task_60s(struct bwn_mac *);
169 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
170 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
171 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
172 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
173                     uint16_t);
174 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
175 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
176                     uint32_t);
177 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
178                     uint16_t);
179 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
180                     const struct bwn_channelinfo *, int);
181 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
182                     const struct ieee80211_bpf_params *);
183 static void     bwn_newassoc(struct ieee80211_node *, int);
184 static void     bwn_updateslot(struct ifnet *);
185 static void     bwn_update_promisc(struct ifnet *);
186 static void     bwn_wme_init(struct bwn_mac *);
187 static int      bwn_wme_update(struct ieee80211com *);
188 static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
189                     const uint8_t [IEEE80211_ADDR_LEN]);
190 static void     bwn_wme_clear(struct bwn_softc *);
191 static void     bwn_wme_load(struct bwn_mac *);
192 static void     bwn_wme_loadparams(struct bwn_mac *,
193                     const struct wmeParams *, uint16_t);
194 static void     bwn_node_cleanup(struct ieee80211_node *);
195 static void     bwn_scan_start(struct ieee80211com *);
196 static void     bwn_scan_end(struct ieee80211com *);
197 static void     bwn_set_channel(struct ieee80211com *);
198 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
199                     const char [IFNAMSIZ], int, int,
200                     int, const uint8_t [IEEE80211_ADDR_LEN],
201                     const uint8_t [IEEE80211_ADDR_LEN]);
202 static void     bwn_vap_delete(struct ieee80211vap *);
203 static void     bwn_stop(struct bwn_softc *, int);
204 static void     bwn_stop_locked(struct bwn_softc *, int);
205 static int      bwn_core_init(struct bwn_mac *);
206 static void     bwn_core_start(struct bwn_mac *);
207 static void     bwn_core_exit(struct bwn_mac *);
208 static void     bwn_bt_disable(struct bwn_mac *);
209 static int      bwn_chip_init(struct bwn_mac *);
210 static uint64_t bwn_hf_read(struct bwn_mac *);
211 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
212 static void     bwn_set_txretry(struct bwn_mac *, int, int);
213 static void     bwn_rate_init(struct bwn_mac *);
214 static void     bwn_set_phytxctl(struct bwn_mac *);
215 static void     bwn_spu_setdelay(struct bwn_mac *, int);
216 static void     bwn_bt_enable(struct bwn_mac *);
217 static void     bwn_set_macaddr(struct bwn_mac *);
218 static void     bwn_crypt_init(struct bwn_mac *);
219 static void     bwn_chip_exit(struct bwn_mac *);
220 static int      bwn_fw_fillinfo(struct bwn_mac *);
221 static int      bwn_fw_loaducode(struct bwn_mac *);
222 static int      bwn_gpio_init(struct bwn_mac *);
223 static int      bwn_fw_loadinitvals(struct bwn_mac *);
224 static int      bwn_phy_init(struct bwn_mac *);
225 static void     bwn_set_txantenna(struct bwn_mac *, int);
226 static void     bwn_set_opmode(struct bwn_mac *);
227 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
228 static uint8_t  bwn_plcp_getcck(const uint8_t);
229 static uint8_t  bwn_plcp_getofdm(const uint8_t);
230 static void     bwn_pio_init(struct bwn_mac *);
231 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
232 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
233                     int);
234 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
235                     struct bwn_pio_rxqueue *, int);
236 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
237 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
238                     uint16_t);
239 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
240 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
241 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
242 static void     bwn_pio_handle_txeof(struct bwn_mac *,
243                     const struct bwn_txstatus *);
244 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
245 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
246 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
247                     uint16_t);
248 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
249                     uint32_t);
250 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
251                     struct mbuf *);
252 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
253 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
254                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
255 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
256                     uint16_t, uint32_t);
257 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
258                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
259 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
260                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
261 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
262                     uint16_t, struct bwn_pio_txpkt **);
263 static void     bwn_dma_init(struct bwn_mac *);
264 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
265 static int      bwn_dma_mask2type(uint64_t);
266 static uint64_t bwn_dma_mask(struct bwn_mac *);
267 static uint16_t bwn_dma_base(int, int);
268 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
269 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
270                     int, struct bwn_dmadesc_generic **,
271                     struct bwn_dmadesc_meta **);
272 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
273                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
274                     int, int);
275 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
276 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
277 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
278 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
279 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
280 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
281                     int, struct bwn_dmadesc_generic **,
282                     struct bwn_dmadesc_meta **);
283 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
284                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
285                     int, int);
286 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
287 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
288 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
289 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
290 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
291 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
292 static void     bwn_dma_setup(struct bwn_dma_ring *);
293 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
294 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
295 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
296 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
297 static void     bwn_dma_rx(struct bwn_dma_ring *);
298 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
299 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
300                     struct bwn_dmadesc_meta *);
301 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
302 static int      bwn_dma_gettype(struct bwn_mac *);
303 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
304 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
305 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
306 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
307 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
308                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
309                     int);
310 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
311                     bus_size_t, int);
312 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
313 static void     bwn_dma_handle_txeof(struct bwn_mac *,
314                     const struct bwn_txstatus *);
315 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
316                     struct mbuf *);
317 static int      bwn_dma_getslot(struct bwn_dma_ring *);
318 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
319                     uint8_t);
320 static int      bwn_dma_attach(struct bwn_mac *);
321 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
322                     int, int, int);
323 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
324                     const struct bwn_txstatus *, uint16_t, int *);
325 static void     bwn_dma_free(struct bwn_mac *);
326 static void     bwn_phy_g_init_sub(struct bwn_mac *);
327 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
328 static void     bwn_phy_init_b5(struct bwn_mac *);
329 static void     bwn_phy_init_b6(struct bwn_mac *);
330 static void     bwn_phy_init_a(struct bwn_mac *);
331 static void     bwn_loopback_calcgain(struct bwn_mac *);
332 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
333 static void     bwn_lo_g_init(struct bwn_mac *);
334 static void     bwn_lo_g_adjust(struct bwn_mac *);
335 static void     bwn_lo_get_powervector(struct bwn_mac *);
336 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
337                     const struct bwn_bbatt *, const struct bwn_rfatt *);
338 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
339 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
340 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
341 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
342                     const struct bwn_bbatt *, const struct bwn_rfatt *,
343                     uint8_t);
344 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
345 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
346 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
347 static void     bwn_wa_init(struct bwn_mac *);
348 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
349                     uint16_t);
350 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
351 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
352                     uint32_t);
353 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
354                     uint16_t);
355 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
356 static void     bwn_mac_suspend(struct bwn_mac *);
357 static void     bwn_mac_enable(struct bwn_mac *);
358 static void     bwn_psctl(struct bwn_mac *, uint32_t);
359 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
360 static void     bwn_nrssi_offset(struct bwn_mac *);
361 static void     bwn_nrssi_threshold(struct bwn_mac *);
362 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
363 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
364                     int16_t);
365 static void     bwn_set_original_gains(struct bwn_mac *);
366 static void     bwn_hwpctl_early_init(struct bwn_mac *);
367 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
368 static uint16_t bwn_phy_g_chan2freq(uint8_t);
369 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
370 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
371                     const char *, struct bwn_fwfile *);
372 static void     bwn_release_firmware(struct bwn_mac *);
373 static void     bwn_do_release_fw(struct bwn_fwfile *);
374 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
375 static int      bwn_fwinitvals_write(struct bwn_mac *,
376                     const struct bwn_fwinitvals *, size_t, size_t);
377 static int      bwn_switch_channel(struct bwn_mac *, int);
378 static uint16_t bwn_ant2phy(int);
379 static void     bwn_mac_write_bssid(struct bwn_mac *);
380 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
381                     const uint8_t *);
382 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
383                     const uint8_t *, size_t, const uint8_t *);
384 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
385                     const uint8_t *);
386 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
387                     const uint8_t *);
388 static void     bwn_phy_exit(struct bwn_mac *);
389 static void     bwn_core_stop(struct bwn_mac *);
390 static int      bwn_switch_band(struct bwn_softc *,
391                     struct ieee80211_channel *);
392 static void     bwn_phy_reset(struct bwn_mac *);
393 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
394 static void     bwn_set_pretbtt(struct bwn_mac *);
395 static int      bwn_intr(void *);
396 static void     bwn_intrtask(void *, int);
397 static void     bwn_restart(struct bwn_mac *, const char *);
398 static void     bwn_intr_ucode_debug(struct bwn_mac *);
399 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
400 static void     bwn_intr_atim_end(struct bwn_mac *);
401 static void     bwn_intr_beacon(struct bwn_mac *);
402 static void     bwn_intr_pmq(struct bwn_mac *);
403 static void     bwn_intr_noise(struct bwn_mac *);
404 static void     bwn_intr_txeof(struct bwn_mac *);
405 static void     bwn_hwreset(void *, int);
406 static void     bwn_handle_fwpanic(struct bwn_mac *);
407 static void     bwn_load_beacon0(struct bwn_mac *);
408 static void     bwn_load_beacon1(struct bwn_mac *);
409 static uint32_t bwn_jssi_read(struct bwn_mac *);
410 static void     bwn_noise_gensample(struct bwn_mac *);
411 static void     bwn_handle_txeof(struct bwn_mac *,
412                     const struct bwn_txstatus *);
413 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
414 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
415 static void     bwn_start_locked(struct ifnet *);
416 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
417                     struct mbuf *);
418 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
419 static int      bwn_set_txhdr(struct bwn_mac *,
420                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
421                     uint16_t);
422 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
423                     const uint8_t);
424 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
425 static uint8_t  bwn_get_fbrate(uint8_t);
426 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
427 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
428 static void     bwn_phy_lock(struct bwn_mac *);
429 static void     bwn_phy_unlock(struct bwn_mac *);
430 static void     bwn_rf_lock(struct bwn_mac *);
431 static void     bwn_rf_unlock(struct bwn_mac *);
432 static void     bwn_txpwr(void *, int);
433 static void     bwn_tasks(void *);
434 static void     bwn_task_15s(struct bwn_mac *);
435 static void     bwn_task_30s(struct bwn_mac *);
436 static void     bwn_task_60s(struct bwn_mac *);
437 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
438                     uint8_t);
439 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
440 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
441                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
442                     int, int);
443 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
444 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
445 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
446 static void     bwn_watchdog(void *);
447 static void     bwn_dma_stop(struct bwn_mac *);
448 static void     bwn_pio_stop(struct bwn_mac *);
449 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
450 static void     bwn_led_attach(struct bwn_mac *);
451 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
452 static void     bwn_led_event(struct bwn_mac *, int);
453 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
454 static void     bwn_led_blink_next(void *);
455 static void     bwn_led_blink_end(void *);
456 static void     bwn_rfswitch(void *);
457 static void     bwn_rf_turnon(struct bwn_mac *);
458 static void     bwn_rf_turnoff(struct bwn_mac *);
459 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
460 static int      bwn_phy_lp_init(struct bwn_mac *);
461 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
462 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
464                     uint16_t);
465 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
466 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
467 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
468 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
469 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
470 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
471 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
472 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
473 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
474 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
475 static void     bwn_phy_lp_calib(struct bwn_mac *);
476 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
477 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
478 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
479 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
480 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
481 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
482 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
483 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
484 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
485 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
486 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
487 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
488 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
489 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
490 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
491 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
492 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
493 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
494 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
495 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
496 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
497 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
498                     const void *);
499 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
500 static struct bwn_txgain
501                 bwn_phy_lp_get_txgain(struct bwn_mac *);
502 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
503 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
504 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
505 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
506 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
507 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
508 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
509 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
510 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
511 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
512 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
513 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
514 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
515 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
516 static int      bwn_phy_lp_loopback(struct bwn_mac *);
517 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
518 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
519                     int);
520 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
521                     struct bwn_phy_lp_iq_est *);
522 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
523 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
524 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
525 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
526 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
527 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
528 static uint8_t  bwn_nbits(int32_t);
529 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
530                     struct bwn_txgain_entry *);
531 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
532                     struct bwn_txgain_entry);
533 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
534                     struct bwn_txgain_entry);
535 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
536                     struct bwn_txgain_entry);
537 static void     bwn_sysctl_node(struct bwn_softc *);
538
539 static struct resource_spec bwn_res_spec_legacy[] = {
540         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
541         { -1,                   0,              0 }
542 };
543
544 static struct resource_spec bwn_res_spec_msi[] = {
545         { SYS_RES_IRQ,          1,              RF_ACTIVE },
546         { -1,                   0,              0 }
547 };
548
549 static const struct bwn_channelinfo bwn_chantable_bg = {
550         .channels = {
551                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
552                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
553                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
554                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
555                 { 2472, 13, 30 }, { 2484, 14, 30 } },
556         .nchannels = 14
557 };
558
559 static const struct bwn_channelinfo bwn_chantable_a = {
560         .channels = {
561                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
562                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
563                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
564                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
565                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
566                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
567                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
568                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
569                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
570                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
571                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
572                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
573                 { 6080, 216, 30 } },
574         .nchannels = 37
575 };
576
577 static const struct bwn_channelinfo bwn_chantable_n = {
578         .channels = {
579                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
580                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
581                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
582                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
583                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
584                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
585                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
586                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
587                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
588                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
589                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
590                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
591                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
592                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
593                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
594                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
595                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
596                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
597                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
598                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
599                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
600                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
601                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
602                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
603                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
604                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
605                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
606                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
607                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
608                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
609                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
610                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
611                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
612                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
613                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
614                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
615                 { 6130, 226, 30 }, { 6140, 228, 30 } },
616         .nchannels = 110
617 };
618
619 static const uint8_t bwn_b2063_chantable_data[33][12] = {
620         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
622         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
623         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
624         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
625         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
626         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
627         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
628         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
629         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
630         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
631         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
632         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
633         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
634         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
635         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
636         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
637         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
638         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
639         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
640         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
641         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
642         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
643         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
644         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
645         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
646         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
647         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
648         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
649         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
650         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
651         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
652         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
653 };
654
655 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
656         { 1, 2412, bwn_b2063_chantable_data[0] },
657         { 2, 2417, bwn_b2063_chantable_data[0] },
658         { 3, 2422, bwn_b2063_chantable_data[0] },
659         { 4, 2427, bwn_b2063_chantable_data[1] },
660         { 5, 2432, bwn_b2063_chantable_data[1] },
661         { 6, 2437, bwn_b2063_chantable_data[1] },
662         { 7, 2442, bwn_b2063_chantable_data[1] },
663         { 8, 2447, bwn_b2063_chantable_data[1] },
664         { 9, 2452, bwn_b2063_chantable_data[2] },
665         { 10, 2457, bwn_b2063_chantable_data[2] },
666         { 11, 2462, bwn_b2063_chantable_data[3] },
667         { 12, 2467, bwn_b2063_chantable_data[3] },
668         { 13, 2472, bwn_b2063_chantable_data[3] },
669         { 14, 2484, bwn_b2063_chantable_data[4] },
670         { 34, 5170, bwn_b2063_chantable_data[5] },
671         { 36, 5180, bwn_b2063_chantable_data[6] },
672         { 38, 5190, bwn_b2063_chantable_data[7] },
673         { 40, 5200, bwn_b2063_chantable_data[8] },
674         { 42, 5210, bwn_b2063_chantable_data[9] },
675         { 44, 5220, bwn_b2063_chantable_data[10] },
676         { 46, 5230, bwn_b2063_chantable_data[11] },
677         { 48, 5240, bwn_b2063_chantable_data[12] },
678         { 52, 5260, bwn_b2063_chantable_data[13] },
679         { 56, 5280, bwn_b2063_chantable_data[14] },
680         { 60, 5300, bwn_b2063_chantable_data[14] },
681         { 64, 5320, bwn_b2063_chantable_data[15] },
682         { 100, 5500, bwn_b2063_chantable_data[16] },
683         { 104, 5520, bwn_b2063_chantable_data[17] },
684         { 108, 5540, bwn_b2063_chantable_data[18] },
685         { 112, 5560, bwn_b2063_chantable_data[19] },
686         { 116, 5580, bwn_b2063_chantable_data[20] },
687         { 120, 5600, bwn_b2063_chantable_data[21] },
688         { 124, 5620, bwn_b2063_chantable_data[21] },
689         { 128, 5640, bwn_b2063_chantable_data[22] },
690         { 132, 5660, bwn_b2063_chantable_data[22] },
691         { 136, 5680, bwn_b2063_chantable_data[22] },
692         { 140, 5700, bwn_b2063_chantable_data[23] },
693         { 149, 5745, bwn_b2063_chantable_data[23] },
694         { 153, 5765, bwn_b2063_chantable_data[23] },
695         { 157, 5785, bwn_b2063_chantable_data[23] },
696         { 161, 5805, bwn_b2063_chantable_data[23] },
697         { 165, 5825, bwn_b2063_chantable_data[23] },
698         { 184, 4920, bwn_b2063_chantable_data[24] },
699         { 188, 4940, bwn_b2063_chantable_data[25] },
700         { 192, 4960, bwn_b2063_chantable_data[26] },
701         { 196, 4980, bwn_b2063_chantable_data[27] },
702         { 200, 5000, bwn_b2063_chantable_data[28] },
703         { 204, 5020, bwn_b2063_chantable_data[29] },
704         { 208, 5040, bwn_b2063_chantable_data[30] },
705         { 212, 5060, bwn_b2063_chantable_data[31] },
706         { 216, 5080, bwn_b2063_chantable_data[32] }
707 };
708
709 static const uint8_t bwn_b2062_chantable_data[22][12] = {
710         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
711         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
718         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
719         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
720         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
721         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
722         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
723         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
728         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
729         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
730         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
731         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
732 };
733
734 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
735         { 1, 2412, bwn_b2062_chantable_data[0] },
736         { 2, 2417, bwn_b2062_chantable_data[0] },
737         { 3, 2422, bwn_b2062_chantable_data[0] },
738         { 4, 2427, bwn_b2062_chantable_data[0] },
739         { 5, 2432, bwn_b2062_chantable_data[0] },
740         { 6, 2437, bwn_b2062_chantable_data[0] },
741         { 7, 2442, bwn_b2062_chantable_data[0] },
742         { 8, 2447, bwn_b2062_chantable_data[0] },
743         { 9, 2452, bwn_b2062_chantable_data[0] },
744         { 10, 2457, bwn_b2062_chantable_data[0] },
745         { 11, 2462, bwn_b2062_chantable_data[0] },
746         { 12, 2467, bwn_b2062_chantable_data[0] },
747         { 13, 2472, bwn_b2062_chantable_data[0] },
748         { 14, 2484, bwn_b2062_chantable_data[0] },
749         { 34, 5170, bwn_b2062_chantable_data[1] },
750         { 38, 5190, bwn_b2062_chantable_data[2] },
751         { 42, 5210, bwn_b2062_chantable_data[2] },
752         { 46, 5230, bwn_b2062_chantable_data[3] },
753         { 36, 5180, bwn_b2062_chantable_data[4] },
754         { 40, 5200, bwn_b2062_chantable_data[5] },
755         { 44, 5220, bwn_b2062_chantable_data[6] },
756         { 48, 5240, bwn_b2062_chantable_data[3] },
757         { 52, 5260, bwn_b2062_chantable_data[3] },
758         { 56, 5280, bwn_b2062_chantable_data[3] },
759         { 60, 5300, bwn_b2062_chantable_data[7] },
760         { 64, 5320, bwn_b2062_chantable_data[8] },
761         { 100, 5500, bwn_b2062_chantable_data[9] },
762         { 104, 5520, bwn_b2062_chantable_data[10] },
763         { 108, 5540, bwn_b2062_chantable_data[10] },
764         { 112, 5560, bwn_b2062_chantable_data[10] },
765         { 116, 5580, bwn_b2062_chantable_data[11] },
766         { 120, 5600, bwn_b2062_chantable_data[12] },
767         { 124, 5620, bwn_b2062_chantable_data[12] },
768         { 128, 5640, bwn_b2062_chantable_data[12] },
769         { 132, 5660, bwn_b2062_chantable_data[12] },
770         { 136, 5680, bwn_b2062_chantable_data[12] },
771         { 140, 5700, bwn_b2062_chantable_data[12] },
772         { 149, 5745, bwn_b2062_chantable_data[12] },
773         { 153, 5765, bwn_b2062_chantable_data[12] },
774         { 157, 5785, bwn_b2062_chantable_data[12] },
775         { 161, 5805, bwn_b2062_chantable_data[12] },
776         { 165, 5825, bwn_b2062_chantable_data[12] },
777         { 184, 4920, bwn_b2062_chantable_data[13] },
778         { 188, 4940, bwn_b2062_chantable_data[14] },
779         { 192, 4960, bwn_b2062_chantable_data[15] },
780         { 196, 4980, bwn_b2062_chantable_data[16] },
781         { 200, 5000, bwn_b2062_chantable_data[17] },
782         { 204, 5020, bwn_b2062_chantable_data[18] },
783         { 208, 5040, bwn_b2062_chantable_data[19] },
784         { 212, 5060, bwn_b2062_chantable_data[20] },
785         { 216, 5080, bwn_b2062_chantable_data[21] }
786 };
787
788 /* for LP PHY */
789 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
790         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
791         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
792         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
793         { 13, -66, 13 }, { 14, -66, 13 },
794 };
795
796 /* for LP PHY */
797 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
798         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
799         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
800         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
801         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
802         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
803         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
804         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
805         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
806         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
807         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
808         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
809         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
810         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
811 };
812
813 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
814
815 static const uint8_t bwn_tab_sigsq_tbl[] = {
816         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
817         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
818         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
819         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
820         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
821         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
822 };
823
824 static const uint8_t bwn_tab_pllfrac_tbl[] = {
825         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
826         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
827 };
828
829 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
830         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
831         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
832         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
834         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
835         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
840         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
841         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
842 };
843
844 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
845 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
846 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
847 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
848 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
849 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
850
851 #define VENDOR_LED_ACT(vendor)                          \
852 {                                                       \
853         .vid = PCI_VENDOR_##vendor,                     \
854         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
855 }
856
857 static const struct {
858         uint16_t        vid;
859         uint8_t         led_act[BWN_LED_MAX];
860 } bwn_vendor_led_act[] = {
861         VENDOR_LED_ACT(COMPAQ),
862         VENDOR_LED_ACT(ASUSTEK)
863 };
864
865 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
866         { BWN_VENDOR_LED_ACT_DEFAULT };
867
868 #undef VENDOR_LED_ACT
869
870 static const struct {
871         int             on_dur;
872         int             off_dur;
873 } bwn_led_duration[109] = {
874         [0]     = { 400, 100 },
875         [2]     = { 150, 75 },
876         [4]     = { 90, 45 },
877         [11]    = { 66, 34 },
878         [12]    = { 53, 26 },
879         [18]    = { 42, 21 },
880         [22]    = { 35, 17 },
881         [24]    = { 32, 16 },
882         [36]    = { 21, 10 },
883         [48]    = { 16, 8 },
884         [72]    = { 11, 5 },
885         [96]    = { 9, 4 },
886         [108]   = { 7, 3 }
887 };
888
889 static const uint16_t bwn_wme_shm_offsets[] = {
890         [0] = BWN_WME_BESTEFFORT,
891         [1] = BWN_WME_BACKGROUND,
892         [2] = BWN_WME_VOICE,
893         [3] = BWN_WME_VIDEO,
894 };
895
896 static const struct siba_devid bwn_devs[] = {
897         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
898         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
899         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
900         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
901         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
902         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
903         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
904         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
905         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
906 };
907
908 static int
909 bwn_probe(device_t dev)
910 {
911         int i;
912
913         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
914                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
915                     siba_get_device(dev) == bwn_devs[i].sd_device &&
916                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
917                         return (BUS_PROBE_DEFAULT);
918         }
919
920         return (ENXIO);
921 }
922
923 static int
924 bwn_attach(device_t dev)
925 {
926         struct bwn_mac *mac;
927         struct bwn_softc *sc = device_get_softc(dev);
928         int error, i, msic, reg;
929
930         sc->sc_dev = dev;
931 #ifdef BWN_DEBUG
932         sc->sc_debug = bwn_debug;
933 #endif
934
935         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
936                 error = bwn_attach_pre(sc);
937                 if (error != 0)
938                         return (error);
939                 bwn_sprom_bugfixes(dev);
940                 sc->sc_flags |= BWN_FLAG_ATTACHED;
941         }
942
943         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
944                 if (siba_get_pci_device(dev) != 0x4313 &&
945                     siba_get_pci_device(dev) != 0x431a &&
946                     siba_get_pci_device(dev) != 0x4321) {
947                         device_printf(sc->sc_dev,
948                             "skip 802.11 cores\n");
949                         return (ENODEV);
950                 }
951         }
952
953         mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
954             M_NOWAIT | M_ZERO);
955         if (mac == NULL)
956                 return (ENOMEM);
957         mac->mac_sc = sc;
958         mac->mac_status = BWN_MAC_STATUS_UNINIT;
959         if (bwn_bfp != 0)
960                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
961
962         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
963         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
964         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
965
966         error = bwn_attach_core(mac);
967         if (error)
968                 goto fail0;
969         bwn_led_attach(mac);
970
971         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
972             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
973             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
974             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
975             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
976             mac->mac_phy.rf_rev);
977         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
978                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
979                     mac->mac_method.dma.dmatype);
980         else
981                 device_printf(sc->sc_dev, "PIO\n");
982
983         /*
984          * setup PCI resources and interrupt.
985          */
986         if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
987                 msic = pci_msi_count(dev);
988                 if (bootverbose)
989                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
990         } else
991                 msic = 0;
992
993         mac->mac_intr_spec = bwn_res_spec_legacy;
994         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
995                 if (pci_alloc_msi(dev, &msic) == 0) {
996                         device_printf(sc->sc_dev,
997                             "Using %d MSI messages\n", msic);
998                         mac->mac_intr_spec = bwn_res_spec_msi;
999                         mac->mac_msi = 1;
1000                 }
1001         }
1002
1003         error = bus_alloc_resources(dev, mac->mac_intr_spec,
1004             mac->mac_res_irq);
1005         if (error) {
1006                 device_printf(sc->sc_dev,
1007                     "couldn't allocate IRQ resources (%d)\n", error);
1008                 goto fail1;
1009         }
1010
1011         if (mac->mac_msi == 0)
1012                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1013                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1014                     &mac->mac_intrhand[0]);
1015         else {
1016                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1017                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1018                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1019                             &mac->mac_intrhand[i]);
1020                         if (error != 0) {
1021                                 device_printf(sc->sc_dev,
1022                                     "couldn't setup interrupt (%d)\n", error);
1023                                 break;
1024                         }
1025                 }
1026         }
1027
1028         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1029
1030         /*
1031          * calls attach-post routine
1032          */
1033         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1034                 bwn_attach_post(sc);
1035
1036         return (0);
1037 fail1:
1038         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1039                 pci_release_msi(dev);
1040 fail0:
1041         free(mac, M_DEVBUF);
1042         return (error);
1043 }
1044
1045 static int
1046 bwn_is_valid_ether_addr(uint8_t *addr)
1047 {
1048         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1049
1050         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1051                 return (FALSE);
1052
1053         return (TRUE);
1054 }
1055
1056 static int
1057 bwn_attach_post(struct bwn_softc *sc)
1058 {
1059         struct ieee80211com *ic;
1060         struct ifnet *ifp = sc->sc_ifp;
1061
1062         ic = ifp->if_l2com;
1063         ic->ic_ifp = ifp;
1064         /* XXX not right but it's not used anywhere important */
1065         ic->ic_phytype = IEEE80211_T_OFDM;
1066         ic->ic_opmode = IEEE80211_M_STA;
1067         ic->ic_caps =
1068                   IEEE80211_C_STA               /* station mode supported */
1069                 | IEEE80211_C_MONITOR           /* monitor mode */
1070                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1071                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1072                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1073                 | IEEE80211_C_WME               /* WME/WMM supported */
1074                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1075                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1076                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1077                 ;
1078
1079         /* call MI attach routine. */
1080         ieee80211_ifattach(ic,
1081             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1082             siba_sprom_get_mac_80211a(sc->sc_dev) :
1083             siba_sprom_get_mac_80211bg(sc->sc_dev));
1084
1085         ic->ic_headroom = sizeof(struct bwn_txhdr);
1086
1087         /* override default methods */
1088         ic->ic_raw_xmit = bwn_raw_xmit;
1089         ic->ic_newassoc = bwn_newassoc;
1090         ic->ic_updateslot = bwn_updateslot;
1091         ic->ic_update_promisc = bwn_update_promisc;
1092         ic->ic_wme.wme_update = bwn_wme_update;
1093
1094         ic->ic_node_alloc = bwn_node_alloc;
1095         sc->sc_node_cleanup = ic->ic_node_cleanup;
1096         ic->ic_node_cleanup = bwn_node_cleanup;
1097
1098         ic->ic_scan_start = bwn_scan_start;
1099         ic->ic_scan_end = bwn_scan_end;
1100         ic->ic_set_channel = bwn_set_channel;
1101
1102         ic->ic_vap_create = bwn_vap_create;
1103         ic->ic_vap_delete = bwn_vap_delete;
1104
1105         ieee80211_radiotap_attach(ic,
1106             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1107             BWN_TX_RADIOTAP_PRESENT,
1108             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1109             BWN_RX_RADIOTAP_PRESENT);
1110
1111         bwn_sysctl_node(sc);
1112
1113         if (bootverbose)
1114                 ieee80211_announce(ic);
1115         return (0);
1116 }
1117
1118 static void
1119 bwn_phy_detach(struct bwn_mac *mac)
1120 {
1121
1122         if (mac->mac_phy.detach != NULL)
1123                 mac->mac_phy.detach(mac);
1124 }
1125
1126 static int
1127 bwn_detach(device_t dev)
1128 {
1129         struct bwn_softc *sc = device_get_softc(dev);
1130         struct bwn_mac *mac = sc->sc_curmac;
1131         struct ifnet *ifp = sc->sc_ifp;
1132         struct ieee80211com *ic = ifp->if_l2com;
1133         int i;
1134
1135         sc->sc_flags |= BWN_FLAG_INVALID;
1136
1137         if (device_is_attached(sc->sc_dev)) {
1138                 bwn_stop(sc, 1);
1139                 bwn_dma_free(mac);
1140                 callout_drain(&sc->sc_led_blink_ch);
1141                 callout_drain(&sc->sc_rfswitch_ch);
1142                 callout_drain(&sc->sc_task_ch);
1143                 callout_drain(&sc->sc_watchdog_ch);
1144                 bwn_phy_detach(mac);
1145                 if (ifp != NULL) {
1146                         ieee80211_draintask(ic, &mac->mac_hwreset);
1147                         ieee80211_draintask(ic, &mac->mac_txpower);
1148                         ieee80211_ifdetach(ic);
1149                         if_free(ifp);
1150                 }
1151         }
1152         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1153         taskqueue_free(sc->sc_tq);
1154
1155         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1156                 if (mac->mac_intrhand[i] != NULL) {
1157                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1158                             mac->mac_intrhand[i]);
1159                         mac->mac_intrhand[i] = NULL;
1160                 }
1161         }
1162         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1163         if (mac->mac_msi != 0)
1164                 pci_release_msi(dev);
1165
1166         BWN_LOCK_DESTROY(sc);
1167         return (0);
1168 }
1169
1170 static int
1171 bwn_attach_pre(struct bwn_softc *sc)
1172 {
1173         struct ifnet *ifp;
1174         int error = 0;
1175
1176         BWN_LOCK_INIT(sc);
1177         TAILQ_INIT(&sc->sc_maclist);
1178         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1179         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1180         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1181
1182         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1183                 taskqueue_thread_enqueue, &sc->sc_tq);
1184         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1185                 "%s taskq", device_get_nameunit(sc->sc_dev));
1186
1187         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1188         if (ifp == NULL) {
1189                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1190                 error = ENOSPC;
1191                 goto fail;
1192         }
1193
1194         /* set these up early for if_printf use */
1195         if_initname(ifp, device_get_name(sc->sc_dev),
1196             device_get_unit(sc->sc_dev));
1197
1198         ifp->if_softc = sc;
1199         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1200         ifp->if_init = bwn_init;
1201         ifp->if_ioctl = bwn_ioctl;
1202         ifp->if_start = bwn_start;
1203         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
1204         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
1205         IFQ_SET_READY(&ifp->if_snd);
1206
1207         return (0);
1208
1209 fail:   BWN_LOCK_DESTROY(sc);
1210         return (error);
1211 }
1212
1213 static void
1214 bwn_sprom_bugfixes(device_t dev)
1215 {
1216 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1217         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1218          (siba_get_pci_device(dev) == _device) &&                       \
1219          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1220          (siba_get_pci_subdevice(dev) == _subdevice))
1221
1222         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1223             siba_get_pci_subdevice(dev) == 0x4e &&
1224             siba_get_pci_revid(dev) > 0x40)
1225                 siba_sprom_set_bf_lo(dev,
1226                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1227         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1228             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1229                 siba_sprom_set_bf_lo(dev,
1230                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1231         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1232                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1233                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1234                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1235                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1236                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1237                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1238                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1239                         siba_sprom_set_bf_lo(dev,
1240                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1241         }
1242 #undef  BWN_ISDEV
1243 }
1244
1245 static int
1246 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1247 {
1248 #define IS_RUNNING(ifp) \
1249         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1250         struct bwn_softc *sc = ifp->if_softc;
1251         struct ieee80211com *ic = ifp->if_l2com;
1252         struct ifreq *ifr = (struct ifreq *)data;
1253         int error = 0, startall;
1254
1255         switch (cmd) {
1256         case SIOCSIFFLAGS:
1257                 startall = 0;
1258                 if (IS_RUNNING(ifp)) {
1259                         bwn_update_promisc(ifp);
1260                 } else if (ifp->if_flags & IFF_UP) {
1261                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1262                                 bwn_init(sc);
1263                                 startall = 1;
1264                         }
1265                 } else
1266                         bwn_stop(sc, 1);
1267                 if (startall)
1268                         ieee80211_start_all(ic);
1269                 break;
1270         case SIOCGIFMEDIA:
1271                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1272                 break;
1273         case SIOCGIFADDR:
1274                 error = ether_ioctl(ifp, cmd, data);
1275                 break;
1276         default:
1277                 error = EINVAL;
1278                 break;
1279         }
1280         return (error);
1281 }
1282
1283 static void
1284 bwn_start(struct ifnet *ifp)
1285 {
1286         struct bwn_softc *sc = ifp->if_softc;
1287
1288         BWN_LOCK(sc);
1289         bwn_start_locked(ifp);
1290         BWN_UNLOCK(sc);
1291 }
1292
1293 static void
1294 bwn_start_locked(struct ifnet *ifp)
1295 {
1296         struct bwn_softc *sc = ifp->if_softc;
1297         struct bwn_mac *mac = sc->sc_curmac;
1298         struct ieee80211_frame *wh;
1299         struct ieee80211_node *ni;
1300         struct ieee80211_key *k;
1301         struct mbuf *m;
1302
1303         BWN_ASSERT_LOCKED(sc);
1304
1305         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1306             mac->mac_status < BWN_MAC_STATUS_STARTED)
1307                 return;
1308
1309         for (;;) {
1310                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);       /* XXX: LOCK */
1311                 if (m == NULL)
1312                         break;
1313
1314                 if (bwn_tx_isfull(sc, m))
1315                         break;
1316                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1317                 if (ni == NULL) {
1318                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1319                         m_freem(m);
1320                         ifp->if_oerrors++;
1321                         continue;
1322                 }
1323                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1324                 wh = mtod(m, struct ieee80211_frame *);
1325                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1326                         k = ieee80211_crypto_encap(ni, m);
1327                         if (k == NULL) {
1328                                 ieee80211_free_node(ni);
1329                                 m_freem(m);
1330                                 ifp->if_oerrors++;
1331                                 continue;
1332                         }
1333                 }
1334                 wh = NULL;      /* Catch any invalid use */
1335
1336                 if (bwn_tx_start(sc, ni, m) != 0) {
1337                         if (ni != NULL)
1338                                 ieee80211_free_node(ni);
1339                         ifp->if_oerrors++;
1340                         continue;
1341                 }
1342
1343                 sc->sc_watchdog_timer = 5;
1344         }
1345 }
1346
1347 static int
1348 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1349 {
1350         struct bwn_dma_ring *dr;
1351         struct bwn_mac *mac = sc->sc_curmac;
1352         struct bwn_pio_txqueue *tq;
1353         struct ifnet *ifp = sc->sc_ifp;
1354         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1355
1356         BWN_ASSERT_LOCKED(sc);
1357
1358         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1359                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1360                 if (dr->dr_stop == 1 ||
1361                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1362                         dr->dr_stop = 1;
1363                         goto full;
1364                 }
1365         } else {
1366                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1367                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1368                     pktlen > (tq->tq_size - tq->tq_used)) {
1369                         tq->tq_stop = 1;
1370                         goto full;
1371                 }
1372         }
1373         return (0);
1374 full:
1375         IFQ_DRV_PREPEND(&ifp->if_snd, m);
1376         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1377         return (1);
1378 }
1379
1380 static int
1381 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1382 {
1383         struct bwn_mac *mac = sc->sc_curmac;
1384         int error;
1385
1386         BWN_ASSERT_LOCKED(sc);
1387
1388         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1389                 m_freem(m);
1390                 return (ENXIO);
1391         }
1392
1393         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1394             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1395         if (error) {
1396                 m_freem(m);
1397                 return (error);
1398         }
1399         return (0);
1400 }
1401
1402 static int
1403 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1404 {
1405         struct bwn_pio_txpkt *tp;
1406         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1407         struct bwn_softc *sc = mac->mac_sc;
1408         struct bwn_txhdr txhdr;
1409         struct mbuf *m_new;
1410         uint32_t ctl32;
1411         int error;
1412         uint16_t ctl16;
1413
1414         BWN_ASSERT_LOCKED(sc);
1415
1416         /* XXX TODO send packets after DTIM */
1417
1418         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1419         tp = TAILQ_FIRST(&tq->tq_pktlist);
1420         tp->tp_ni = ni;
1421         tp->tp_m = m;
1422
1423         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1424         if (error) {
1425                 device_printf(sc->sc_dev, "tx fail\n");
1426                 return (error);
1427         }
1428
1429         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1430         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1431         tq->tq_free--;
1432
1433         if (siba_get_revid(sc->sc_dev) >= 8) {
1434                 /*
1435                  * XXX please removes m_defrag(9)
1436                  */
1437                 m_new = m_defrag(m, M_DONTWAIT);
1438                 if (m_new == NULL) {
1439                         device_printf(sc->sc_dev,
1440                             "%s: can't defrag TX buffer\n",
1441                             __func__);
1442                         return (ENOBUFS);
1443                 }
1444                 if (m_new->m_next != NULL)
1445                         device_printf(sc->sc_dev,
1446                             "TODO: fragmented packets for PIO\n");
1447                 tp->tp_m = m_new;
1448
1449                 /* send HEADER */
1450                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1451                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1452                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1453                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1454                 /* send BODY */
1455                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1456                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1457                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1458                     ctl32 | BWN_PIO8_TXCTL_EOF);
1459         } else {
1460                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1461                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1462                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1463                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1464                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1465                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1466                     ctl16 | BWN_PIO_TXCTL_EOF);
1467         }
1468
1469         return (0);
1470 }
1471
1472 static struct bwn_pio_txqueue *
1473 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1474 {
1475
1476         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1477                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1478
1479         switch (prio) {
1480         case 0:
1481                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1482         case 1:
1483                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1484         case 2:
1485                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1486         case 3:
1487                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1488         }
1489         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1490         return (NULL);
1491 }
1492
1493 static int
1494 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1495 {
1496 #define BWN_GET_TXHDRCACHE(slot)                                        \
1497         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1498         struct bwn_dma *dma = &mac->mac_method.dma;
1499         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1500         struct bwn_dmadesc_generic *desc;
1501         struct bwn_dmadesc_meta *mt;
1502         struct bwn_softc *sc = mac->mac_sc;
1503         struct ifnet *ifp = sc->sc_ifp;
1504         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1505         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1506
1507         BWN_ASSERT_LOCKED(sc);
1508         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1509
1510         /* XXX send after DTIM */
1511
1512         slot = bwn_dma_getslot(dr);
1513         dr->getdesc(dr, slot, &desc, &mt);
1514         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1515             ("%s:%d: fail", __func__, __LINE__));
1516
1517         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1518             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1519             BWN_DMA_COOKIE(dr, slot));
1520         if (error)
1521                 goto fail;
1522         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1523             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1524             &mt->mt_paddr, BUS_DMA_NOWAIT);
1525         if (error) {
1526                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1527                     __func__, error);
1528                 goto fail;
1529         }
1530         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1531             BUS_DMASYNC_PREWRITE);
1532         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1533         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1534             BUS_DMASYNC_PREWRITE);
1535
1536         slot = bwn_dma_getslot(dr);
1537         dr->getdesc(dr, slot, &desc, &mt);
1538         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1539             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1540         mt->mt_m = m;
1541         mt->mt_ni = ni;
1542
1543         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1544             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1545         if (error && error != EFBIG) {
1546                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1547                     __func__, error);
1548                 goto fail;
1549         }
1550         if (error) {    /* error == EFBIG */
1551                 struct mbuf *m_new;
1552
1553                 m_new = m_defrag(m, M_DONTWAIT);
1554                 if (m_new == NULL) {
1555                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1556                             __func__);
1557                         error = ENOBUFS;
1558                         goto fail;
1559                 } else {
1560                         m = m_new;
1561                 }
1562
1563                 mt->mt_m = m;
1564                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1565                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1566                 if (error) {
1567                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1568                             __func__, error);
1569                         goto fail;
1570                 }
1571         }
1572         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1573         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1574         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1575             BUS_DMASYNC_PREWRITE);
1576
1577         /* XXX send after DTIM */
1578
1579         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1580         return (0);
1581 fail:
1582         dr->dr_curslot = backup[0];
1583         dr->dr_usedslot = backup[1];
1584         return (error);
1585 #undef BWN_GET_TXHDRCACHE
1586 }
1587
1588 static void
1589 bwn_watchdog(void *arg)
1590 {
1591         struct bwn_softc *sc = arg;
1592         struct ifnet *ifp = sc->sc_ifp;
1593
1594         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1595                 if_printf(ifp, "device timeout\n");
1596                 ifp->if_oerrors++;
1597         }
1598         callout_schedule(&sc->sc_watchdog_ch, hz);
1599 }
1600
1601 static int
1602 bwn_attach_core(struct bwn_mac *mac)
1603 {
1604         struct bwn_softc *sc = mac->mac_sc;
1605         int error, have_bg = 0, have_a = 0;
1606         uint32_t high;
1607
1608         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1609             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1610
1611         siba_powerup(sc->sc_dev, 0);
1612
1613         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1614         bwn_reset_core(mac,
1615             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1616         error = bwn_phy_getinfo(mac, high);
1617         if (error)
1618                 goto fail;
1619
1620         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1621         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1622         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1623             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1624             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1625                 have_a = have_bg = 0;
1626                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1627                         have_a = 1;
1628                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1629                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1630                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1631                         have_bg = 1;
1632                 else
1633                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1634                             mac->mac_phy.type));
1635         }
1636         /* XXX turns off PHY A because it's not supported */
1637         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1638             mac->mac_phy.type != BWN_PHYTYPE_N) {
1639                 have_a = 0;
1640                 have_bg = 1;
1641         }
1642
1643         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1644                 mac->mac_phy.attach = bwn_phy_g_attach;
1645                 mac->mac_phy.detach = bwn_phy_g_detach;
1646                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1647                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1648                 mac->mac_phy.init = bwn_phy_g_init;
1649                 mac->mac_phy.exit = bwn_phy_g_exit;
1650                 mac->mac_phy.phy_read = bwn_phy_g_read;
1651                 mac->mac_phy.phy_write = bwn_phy_g_write;
1652                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1653                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1654                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1655                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1656                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1657                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1658                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1659                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1660                 mac->mac_phy.set_im = bwn_phy_g_im;
1661                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1662                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1663                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1664                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1665         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1666                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1667                 mac->mac_phy.init = bwn_phy_lp_init;
1668                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1669                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1670                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1671                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1672                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1673                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1674                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1675                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1676                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1677                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1678                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1679         } else {
1680                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1681                     mac->mac_phy.type);
1682                 error = ENXIO;
1683                 goto fail;
1684         }
1685
1686         mac->mac_phy.gmode = have_bg;
1687         if (mac->mac_phy.attach != NULL) {
1688                 error = mac->mac_phy.attach(mac);
1689                 if (error) {
1690                         device_printf(sc->sc_dev, "failed\n");
1691                         goto fail;
1692                 }
1693         }
1694
1695         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1696
1697         error = bwn_chiptest(mac);
1698         if (error)
1699                 goto fail;
1700         error = bwn_setup_channels(mac, have_bg, have_a);
1701         if (error) {
1702                 device_printf(sc->sc_dev, "failed to setup channels\n");
1703                 goto fail;
1704         }
1705
1706         if (sc->sc_curmac == NULL)
1707                 sc->sc_curmac = mac;
1708
1709         error = bwn_dma_attach(mac);
1710         if (error != 0) {
1711                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1712                 goto fail;
1713         }
1714
1715         mac->mac_phy.switch_analog(mac, 0);
1716
1717         siba_dev_down(sc->sc_dev, 0);
1718 fail:
1719         siba_powerdown(sc->sc_dev);
1720         return (error);
1721 }
1722
1723 static void
1724 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1725 {
1726         struct bwn_softc *sc = mac->mac_sc;
1727         uint32_t low, ctl;
1728
1729         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1730
1731         siba_dev_up(sc->sc_dev, flags);
1732         DELAY(2000);
1733
1734         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1735             ~BWN_TGSLOW_PHYRESET;
1736         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1737         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1738         DELAY(1000);
1739         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1740         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1741         DELAY(1000);
1742
1743         if (mac->mac_phy.switch_analog != NULL)
1744                 mac->mac_phy.switch_analog(mac, 1);
1745
1746         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1747         if (flags & BWN_TGSLOW_SUPPORT_G)
1748                 ctl |= BWN_MACCTL_GMODE;
1749         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1750 }
1751
1752 static int
1753 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1754 {
1755         struct bwn_phy *phy = &mac->mac_phy;
1756         struct bwn_softc *sc = mac->mac_sc;
1757         uint32_t tmp;
1758
1759         /* PHY */
1760         tmp = BWN_READ_2(mac, BWN_PHYVER);
1761         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1762         phy->rf_on = 1;
1763         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1764         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1765         phy->rev = (tmp & BWN_PHYVER_VERSION);
1766         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1767             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1768                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1769             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1770             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1771             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1772                 goto unsupphy;
1773
1774         /* RADIO */
1775         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1776                 if (siba_get_chiprev(sc->sc_dev) == 0)
1777                         tmp = 0x3205017f;
1778                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1779                         tmp = 0x4205017f;
1780                 else
1781                         tmp = 0x5205017f;
1782         } else {
1783                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1784                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1785                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1786                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1787         }
1788         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1789         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1790         phy->rf_manuf = (tmp & 0x00000fff);
1791         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1792                 goto unsupradio;
1793         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1794              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1795             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1796             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1797             (phy->type == BWN_PHYTYPE_N &&
1798              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1799             (phy->type == BWN_PHYTYPE_LP &&
1800              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1801                 goto unsupradio;
1802
1803         return (0);
1804 unsupphy:
1805         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1806             "analog %#x)\n",
1807             phy->type, phy->rev, phy->analog);
1808         return (ENXIO);
1809 unsupradio:
1810         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1811             "rev %#x)\n",
1812             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1813         return (ENXIO);
1814 }
1815
1816 static int
1817 bwn_chiptest(struct bwn_mac *mac)
1818 {
1819 #define TESTVAL0        0x55aaaa55
1820 #define TESTVAL1        0xaa5555aa
1821         struct bwn_softc *sc = mac->mac_sc;
1822         uint32_t v, backup;
1823
1824         BWN_LOCK(sc);
1825
1826         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1827
1828         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1829         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1830                 goto error;
1831         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1832         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1833                 goto error;
1834
1835         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1836
1837         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1838             (siba_get_revid(sc->sc_dev) <= 10)) {
1839                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1840                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1841                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1842                         goto error;
1843                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1844                         goto error;
1845         }
1846         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1847
1848         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1849         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1850                 goto error;
1851
1852         BWN_UNLOCK(sc);
1853         return (0);
1854 error:
1855         BWN_UNLOCK(sc);
1856         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1857         return (ENODEV);
1858 }
1859
1860 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1861 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1862
1863 static int
1864 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1865 {
1866         struct bwn_softc *sc = mac->mac_sc;
1867         struct ifnet *ifp = sc->sc_ifp;
1868         struct ieee80211com *ic = ifp->if_l2com;
1869
1870         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1871         ic->ic_nchans = 0;
1872
1873         if (have_bg)
1874                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1875                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1876         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1877                 if (have_a)
1878                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1879                             &ic->ic_nchans, &bwn_chantable_n,
1880                             IEEE80211_CHAN_HTA);
1881         } else {
1882                 if (have_a)
1883                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1884                             &ic->ic_nchans, &bwn_chantable_a,
1885                             IEEE80211_CHAN_A);
1886         }
1887
1888         mac->mac_phy.supports_2ghz = have_bg;
1889         mac->mac_phy.supports_5ghz = have_a;
1890
1891         return (ic->ic_nchans == 0 ? ENXIO : 0);
1892 }
1893
1894 static uint32_t
1895 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1896 {
1897         uint32_t ret;
1898
1899         BWN_ASSERT_LOCKED(mac->mac_sc);
1900
1901         if (way == BWN_SHARED) {
1902                 KASSERT((offset & 0x0001) == 0,
1903                     ("%s:%d warn", __func__, __LINE__));
1904                 if (offset & 0x0003) {
1905                         bwn_shm_ctlword(mac, way, offset >> 2);
1906                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1907                         ret <<= 16;
1908                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1909                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1910                         goto out;
1911                 }
1912                 offset >>= 2;
1913         }
1914         bwn_shm_ctlword(mac, way, offset);
1915         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1916 out:
1917         return (ret);
1918 }
1919
1920 static uint16_t
1921 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1922 {
1923         uint16_t ret;
1924
1925         BWN_ASSERT_LOCKED(mac->mac_sc);
1926
1927         if (way == BWN_SHARED) {
1928                 KASSERT((offset & 0x0001) == 0,
1929                     ("%s:%d warn", __func__, __LINE__));
1930                 if (offset & 0x0003) {
1931                         bwn_shm_ctlword(mac, way, offset >> 2);
1932                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1933                         goto out;
1934                 }
1935                 offset >>= 2;
1936         }
1937         bwn_shm_ctlword(mac, way, offset);
1938         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1939 out:
1940
1941         return (ret);
1942 }
1943
1944 static void
1945 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1946     uint16_t offset)
1947 {
1948         uint32_t control;
1949
1950         control = way;
1951         control <<= 16;
1952         control |= offset;
1953         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1954 }
1955
1956 static void
1957 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1958     uint32_t value)
1959 {
1960         BWN_ASSERT_LOCKED(mac->mac_sc);
1961
1962         if (way == BWN_SHARED) {
1963                 KASSERT((offset & 0x0001) == 0,
1964                     ("%s:%d warn", __func__, __LINE__));
1965                 if (offset & 0x0003) {
1966                         bwn_shm_ctlword(mac, way, offset >> 2);
1967                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1968                                     (value >> 16) & 0xffff);
1969                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1970                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1971                         return;
1972                 }
1973                 offset >>= 2;
1974         }
1975         bwn_shm_ctlword(mac, way, offset);
1976         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1977 }
1978
1979 static void
1980 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1981     uint16_t value)
1982 {
1983         BWN_ASSERT_LOCKED(mac->mac_sc);
1984
1985         if (way == BWN_SHARED) {
1986                 KASSERT((offset & 0x0001) == 0,
1987                     ("%s:%d warn", __func__, __LINE__));
1988                 if (offset & 0x0003) {
1989                         bwn_shm_ctlword(mac, way, offset >> 2);
1990                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1991                         return;
1992                 }
1993                 offset >>= 2;
1994         }
1995         bwn_shm_ctlword(mac, way, offset);
1996         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1997 }
1998
1999 static void
2000 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
2001     int txpow)
2002 {
2003
2004         c->ic_freq = freq;
2005         c->ic_flags = flags;
2006         c->ic_ieee = ieee;
2007         c->ic_minpower = 0;
2008         c->ic_maxpower = 2 * txpow;
2009         c->ic_maxregpower = txpow;
2010 }
2011
2012 static void
2013 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2014     const struct bwn_channelinfo *ci, int flags)
2015 {
2016         struct ieee80211_channel *c;
2017         int i;
2018
2019         c = &chans[*nchans];
2020
2021         for (i = 0; i < ci->nchannels; i++) {
2022                 const struct bwn_channel *hc;
2023
2024                 hc = &ci->channels[i];
2025                 if (*nchans >= maxchans)
2026                         break;
2027                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2028                 c++, (*nchans)++;
2029                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2030                         /* g channel have a separate b-only entry */
2031                         if (*nchans >= maxchans)
2032                                 break;
2033                         c[0] = c[-1];
2034                         c[-1].ic_flags = IEEE80211_CHAN_B;
2035                         c++, (*nchans)++;
2036                 }
2037                 if (flags == IEEE80211_CHAN_HTG) {
2038                         /* HT g channel have a separate g-only entry */
2039                         if (*nchans >= maxchans)
2040                                 break;
2041                         c[-1].ic_flags = IEEE80211_CHAN_G;
2042                         c[0] = c[-1];
2043                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2044                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2045                         c++, (*nchans)++;
2046                 }
2047                 if (flags == IEEE80211_CHAN_HTA) {
2048                         /* HT a channel have a separate a-only entry */
2049                         if (*nchans >= maxchans)
2050                                 break;
2051                         c[-1].ic_flags = IEEE80211_CHAN_A;
2052                         c[0] = c[-1];
2053                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2054                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
2055                         c++, (*nchans)++;
2056                 }
2057         }
2058 }
2059
2060 static int
2061 bwn_phy_g_attach(struct bwn_mac *mac)
2062 {
2063         struct bwn_softc *sc = mac->mac_sc;
2064         struct bwn_phy *phy = &mac->mac_phy;
2065         struct bwn_phy_g *pg = &phy->phy_g;
2066         unsigned int i;
2067         int16_t pab0, pab1, pab2;
2068         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2069         int8_t bg;
2070
2071         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2072         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2073         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2074         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2075
2076         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2077                 device_printf(sc->sc_dev, "not supported anymore\n");
2078
2079         pg->pg_flags = 0;
2080         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2081             pab2 == -1) {
2082                 pg->pg_idletssi = 52;
2083                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2084                 return (0);
2085         }
2086
2087         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2088         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2089         if (pg->pg_tssi2dbm == NULL) {
2090                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2091                 return (ENOMEM);
2092         }
2093         for (i = 0; i < 64; i++) {
2094                 int32_t m1, m2, f, q, delta;
2095                 int8_t j = 0;
2096
2097                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2098                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2099                 f = 256;
2100
2101                 do {
2102                         if (j > 15) {
2103                                 device_printf(sc->sc_dev,
2104                                     "failed to generate tssi2dBm\n");
2105                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2106                                 return (ENOMEM);
2107                         }
2108                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2109                             f, 2048);
2110                         delta = abs(q - f);
2111                         f = q;
2112                         j++;
2113                 } while (delta >= 2);
2114
2115                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2116                     128);
2117         }
2118
2119         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2120         return (0);
2121 }
2122
2123 static void
2124 bwn_phy_g_detach(struct bwn_mac *mac)
2125 {
2126         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2127
2128         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2129                 free(pg->pg_tssi2dbm, M_DEVBUF);
2130                 pg->pg_tssi2dbm = NULL;
2131         }
2132         pg->pg_flags = 0;
2133 }
2134
2135 static void
2136 bwn_phy_g_init_pre(struct bwn_mac *mac)
2137 {
2138         struct bwn_phy *phy = &mac->mac_phy;
2139         struct bwn_phy_g *pg = &phy->phy_g;
2140         void *tssi2dbm;
2141         int idletssi;
2142         unsigned int i;
2143
2144         tssi2dbm = pg->pg_tssi2dbm;
2145         idletssi = pg->pg_idletssi;
2146
2147         memset(pg, 0, sizeof(*pg));
2148
2149         pg->pg_tssi2dbm = tssi2dbm;
2150         pg->pg_idletssi = idletssi;
2151
2152         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2153
2154         for (i = 0; i < N(pg->pg_nrssi); i++)
2155                 pg->pg_nrssi[i] = -1000;
2156         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2157                 pg->pg_nrssi_lt[i] = i;
2158         pg->pg_lofcal = 0xffff;
2159         pg->pg_initval = 0xffff;
2160         pg->pg_immode = BWN_IMMODE_NONE;
2161         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2162         pg->pg_avgtssi = 0xff;
2163
2164         pg->pg_loctl.tx_bias = 0xff;
2165         TAILQ_INIT(&pg->pg_loctl.calib_list);
2166 }
2167
2168 static int
2169 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2170 {
2171         struct bwn_phy *phy = &mac->mac_phy;
2172         struct bwn_phy_g *pg = &phy->phy_g;
2173         struct bwn_softc *sc = mac->mac_sc;
2174         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2175         static const struct bwn_rfatt rfatt0[] = {
2176                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2177                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2178                 { 3, 1 }, { 4, 1 }
2179         };
2180         static const struct bwn_rfatt rfatt1[] = {
2181                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2182                 { 14, 1 }
2183         };
2184         static const struct bwn_rfatt rfatt2[] = {
2185                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2186                 { 9, 1 }
2187         };
2188         static const struct bwn_bbatt bbatt_0[] = {
2189                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2190         };
2191
2192         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2193
2194         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2195                 pg->pg_bbatt.att = 0;
2196         else
2197                 pg->pg_bbatt.att = 2;
2198
2199         /* prepare Radio Attenuation */
2200         pg->pg_rfatt.padmix = 0;
2201
2202         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2203             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2204                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2205                         pg->pg_rfatt.att = 2;
2206                         goto done;
2207                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2208                         pg->pg_rfatt.att = 3;
2209                         goto done;
2210                 }
2211         }
2212
2213         if (phy->type == BWN_PHYTYPE_A) {
2214                 pg->pg_rfatt.att = 0x60;
2215                 goto done;
2216         }
2217
2218         switch (phy->rf_ver) {
2219         case 0x2050:
2220                 switch (phy->rf_rev) {
2221                 case 0:
2222                         pg->pg_rfatt.att = 5;
2223                         goto done;
2224                 case 1:
2225                         if (phy->type == BWN_PHYTYPE_G) {
2226                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2227                                     SIBA_BOARDVENDOR_BCM &&
2228                                     siba_get_pci_subdevice(sc->sc_dev) ==
2229                                     SIBA_BOARD_BCM4309G &&
2230                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2231                                         pg->pg_rfatt.att = 3;
2232                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2233                                     SIBA_BOARDVENDOR_BCM &&
2234                                     siba_get_pci_subdevice(sc->sc_dev) ==
2235                                     SIBA_BOARD_BU4306)
2236                                         pg->pg_rfatt.att = 3;
2237                                 else
2238                                         pg->pg_rfatt.att = 1;
2239                         } else {
2240                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2241                                     SIBA_BOARDVENDOR_BCM &&
2242                                     siba_get_pci_subdevice(sc->sc_dev) ==
2243                                     SIBA_BOARD_BCM4309G &&
2244                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2245                                         pg->pg_rfatt.att = 7;
2246                                 else
2247                                         pg->pg_rfatt.att = 6;
2248                         }
2249                         goto done;
2250                 case 2:
2251                         if (phy->type == BWN_PHYTYPE_G) {
2252                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2253                                     SIBA_BOARDVENDOR_BCM &&
2254                                     siba_get_pci_subdevice(sc->sc_dev) ==
2255                                     SIBA_BOARD_BCM4309G &&
2256                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2257                                         pg->pg_rfatt.att = 3;
2258                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2259                                     SIBA_BOARDVENDOR_BCM &&
2260                                     siba_get_pci_subdevice(sc->sc_dev) ==
2261                                     SIBA_BOARD_BU4306)
2262                                         pg->pg_rfatt.att = 5;
2263                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2264                                         pg->pg_rfatt.att = 4;
2265                                 else
2266                                         pg->pg_rfatt.att = 3;
2267                         } else
2268                                 pg->pg_rfatt.att = 6;
2269                         goto done;
2270                 case 3:
2271                         pg->pg_rfatt.att = 5;
2272                         goto done;
2273                 case 4:
2274                 case 5:
2275                         pg->pg_rfatt.att = 1;
2276                         goto done;
2277                 case 6:
2278                 case 7:
2279                         pg->pg_rfatt.att = 5;
2280                         goto done;
2281                 case 8:
2282                         pg->pg_rfatt.att = 0xa;
2283                         pg->pg_rfatt.padmix = 1;
2284                         goto done;
2285                 case 9:
2286                 default:
2287                         pg->pg_rfatt.att = 5;
2288                         goto done;
2289                 }
2290                 break;
2291         case 0x2053:
2292                 switch (phy->rf_rev) {
2293                 case 1:
2294                         pg->pg_rfatt.att = 6;
2295                         goto done;
2296                 }
2297                 break;
2298         }
2299         pg->pg_rfatt.att = 5;
2300 done:
2301         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2302
2303         if (!bwn_has_hwpctl(mac)) {
2304                 lo->rfatt.array = rfatt0;
2305                 lo->rfatt.len = N(rfatt0);
2306                 lo->rfatt.min = 0;
2307                 lo->rfatt.max = 9;
2308                 goto genbbatt;
2309         }
2310         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2311                 lo->rfatt.array = rfatt1;
2312                 lo->rfatt.len = N(rfatt1);
2313                 lo->rfatt.min = 0;
2314                 lo->rfatt.max = 14;
2315                 goto genbbatt;
2316         }
2317         lo->rfatt.array = rfatt2;
2318         lo->rfatt.len = N(rfatt2);
2319         lo->rfatt.min = 0;
2320         lo->rfatt.max = 9;
2321 genbbatt:
2322         lo->bbatt.array = bbatt_0;
2323         lo->bbatt.len = N(bbatt_0);
2324         lo->bbatt.min = 0;
2325         lo->bbatt.max = 8;
2326
2327         BWN_READ_4(mac, BWN_MACCTL);
2328         if (phy->rev == 1) {
2329                 phy->gmode = 0;
2330                 bwn_reset_core(mac, 0);
2331                 bwn_phy_g_init_sub(mac);
2332                 phy->gmode = 1;
2333                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2334         }
2335         return (0);
2336 }
2337
2338 static uint16_t
2339 bwn_phy_g_txctl(struct bwn_mac *mac)
2340 {
2341         struct bwn_phy *phy = &mac->mac_phy;
2342
2343         if (phy->rf_ver != 0x2050)
2344                 return (0);
2345         if (phy->rf_rev == 1)
2346                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2347         if (phy->rf_rev < 6)
2348                 return (BWN_TXCTL_PA2DB);
2349         if (phy->rf_rev == 8)
2350                 return (BWN_TXCTL_TXMIX);
2351         return (0);
2352 }
2353
2354 static int
2355 bwn_phy_g_init(struct bwn_mac *mac)
2356 {
2357
2358         bwn_phy_g_init_sub(mac);
2359         return (0);
2360 }
2361
2362 static void
2363 bwn_phy_g_exit(struct bwn_mac *mac)
2364 {
2365         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2366         struct bwn_lo_calib *cal, *tmp;
2367
2368         if (lo == NULL)
2369                 return;
2370         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2371                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2372                 free(cal, M_DEVBUF);
2373         }
2374 }
2375
2376 static uint16_t
2377 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2378 {
2379
2380         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2381         return (BWN_READ_2(mac, BWN_PHYDATA));
2382 }
2383
2384 static void
2385 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2386 {
2387
2388         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2389         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2390 }
2391
2392 static uint16_t
2393 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2394 {
2395
2396         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2397         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2398         return (BWN_READ_2(mac, BWN_RFDATALO));
2399 }
2400
2401 static void
2402 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2403 {
2404
2405         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2406         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2407         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2408 }
2409
2410 static int
2411 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2412 {
2413
2414         return (mac->mac_phy.rev >= 6);
2415 }
2416
2417 static void
2418 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2419 {
2420         struct bwn_phy *phy = &mac->mac_phy;
2421         struct bwn_phy_g *pg = &phy->phy_g;
2422         unsigned int channel;
2423         uint16_t rfover, rfoverval;
2424
2425         if (on) {
2426                 if (phy->rf_on)
2427                         return;
2428
2429                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2430                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2431                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2432                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2433                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2434                             pg->pg_radioctx_over);
2435                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2436                             pg->pg_radioctx_overval);
2437                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2438                 }
2439                 channel = phy->chan;
2440                 bwn_phy_g_switch_chan(mac, 6, 1);
2441                 bwn_phy_g_switch_chan(mac, channel, 0);
2442                 return;
2443         }
2444
2445         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2446         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2447         pg->pg_radioctx_over = rfover;
2448         pg->pg_radioctx_overval = rfoverval;
2449         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2450         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2451         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2452 }
2453
2454 static int
2455 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2456 {
2457
2458         if ((newchan < 1) || (newchan > 14))
2459                 return (EINVAL);
2460         bwn_phy_g_switch_chan(mac, newchan, 0);
2461
2462         return (0);
2463 }
2464
2465 static uint32_t
2466 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2467 {
2468
2469         return (1);
2470 }
2471
2472 static void
2473 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2474 {
2475         struct bwn_phy *phy = &mac->mac_phy;
2476         uint64_t hf;
2477         int autodiv = 0;
2478         uint16_t tmp;
2479
2480         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2481                 autodiv = 1;
2482
2483         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2484         bwn_hf_write(mac, hf);
2485
2486         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2487             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2488             ((autodiv ? BWN_ANTAUTO1 : antenna)
2489                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2490
2491         if (autodiv) {
2492                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2493                 if (antenna == BWN_ANTAUTO1)
2494                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2495                 else
2496                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2497                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2498         }
2499         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2500         if (autodiv)
2501                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2502         else
2503                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2504         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2505         if (phy->rev >= 2) {
2506                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2507                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2508                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2509                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2510                     0x15);
2511                 if (phy->rev == 2)
2512                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2513                 else
2514                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2515                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2516                             8);
2517         }
2518         if (phy->rev >= 6)
2519                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2520
2521         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2522         bwn_hf_write(mac, hf);
2523 }
2524
2525 static int
2526 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2527 {
2528         struct bwn_phy *phy = &mac->mac_phy;
2529         struct bwn_phy_g *pg = &phy->phy_g;
2530
2531         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2532         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2533
2534         if (phy->rev == 0 || !phy->gmode)
2535                 return (ENODEV);
2536
2537         pg->pg_aci_wlan_automatic = 0;
2538         return (0);
2539 }
2540
2541 static int
2542 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2543 {
2544         struct bwn_phy *phy = &mac->mac_phy;
2545         struct bwn_phy_g *pg = &phy->phy_g;
2546         struct bwn_softc *sc = mac->mac_sc;
2547         unsigned int tssi;
2548         int cck, ofdm;
2549         int power;
2550         int rfatt, bbatt;
2551         unsigned int max;
2552
2553         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2554
2555         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2556         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2557         if (cck < 0 && ofdm < 0) {
2558                 if (ignore_tssi == 0)
2559                         return (BWN_TXPWR_RES_DONE);
2560                 cck = 0;
2561                 ofdm = 0;
2562         }
2563         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2564         if (pg->pg_avgtssi != 0xff)
2565                 tssi = (tssi + pg->pg_avgtssi) / 2;
2566         pg->pg_avgtssi = tssi;
2567         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2568
2569         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2570         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2571                 max -= 3;
2572         if (max >= 120) {
2573                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2574                 max = 80;
2575                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2576         }
2577
2578         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2579             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2580              tssi, 0x00), 0x3f)]);
2581         if (power == 0)
2582                 return (BWN_TXPWR_RES_DONE);
2583
2584         rfatt = -((power + 7) / 8);
2585         bbatt = (-(power / 2)) - (4 * rfatt);
2586         if ((rfatt == 0) && (bbatt == 0))
2587                 return (BWN_TXPWR_RES_DONE);
2588         pg->pg_bbatt_delta = bbatt;
2589         pg->pg_rfatt_delta = rfatt;
2590         return (BWN_TXPWR_RES_NEED_ADJUST);
2591 }
2592
2593 static void
2594 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2595 {
2596         struct bwn_phy *phy = &mac->mac_phy;
2597         struct bwn_phy_g *pg = &phy->phy_g;
2598         struct bwn_softc *sc = mac->mac_sc;
2599         int rfatt, bbatt;
2600         uint8_t txctl;
2601
2602         bwn_mac_suspend(mac);
2603
2604         BWN_ASSERT_LOCKED(sc);
2605
2606         bbatt = pg->pg_bbatt.att;
2607         bbatt += pg->pg_bbatt_delta;
2608         rfatt = pg->pg_rfatt.att;
2609         rfatt += pg->pg_rfatt_delta;
2610
2611         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2612         txctl = pg->pg_txctl;
2613         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2614                 if (rfatt <= 1) {
2615                         if (txctl == 0) {
2616                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2617                                 rfatt += 2;
2618                                 bbatt += 2;
2619                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2620                             BWN_BFL_PACTRL) {
2621                                 bbatt += 4 * (rfatt - 2);
2622                                 rfatt = 2;
2623                         }
2624                 } else if (rfatt > 4 && txctl) {
2625                         txctl = 0;
2626                         if (bbatt < 3) {
2627                                 rfatt -= 3;
2628                                 bbatt += 2;
2629                         } else {
2630                                 rfatt -= 2;
2631                                 bbatt -= 2;
2632                         }
2633                 }
2634         }
2635         pg->pg_txctl = txctl;
2636         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2637         pg->pg_rfatt.att = rfatt;
2638         pg->pg_bbatt.att = bbatt;
2639
2640         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2641
2642         bwn_phy_lock(mac);
2643         bwn_rf_lock(mac);
2644         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2645             pg->pg_txctl);
2646         bwn_rf_unlock(mac);
2647         bwn_phy_unlock(mac);
2648
2649         bwn_mac_enable(mac);
2650 }
2651
2652 static void
2653 bwn_phy_g_task_15s(struct bwn_mac *mac)
2654 {
2655         struct bwn_phy *phy = &mac->mac_phy;
2656         struct bwn_phy_g *pg = &phy->phy_g;
2657         struct bwn_softc *sc = mac->mac_sc;
2658         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2659         unsigned long expire, now;
2660         struct bwn_lo_calib *cal, *tmp;
2661         uint8_t expired = 0;
2662
2663         bwn_mac_suspend(mac);
2664
2665         if (lo == NULL)
2666                 goto fail;
2667
2668         BWN_GETTIME(now);
2669         if (bwn_has_hwpctl(mac)) {
2670                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2671                 if (time_before(lo->pwr_vec_read_time, expire)) {
2672                         bwn_lo_get_powervector(mac);
2673                         bwn_phy_g_dc_lookup_init(mac, 0);
2674                 }
2675                 goto fail;
2676         }
2677
2678         expire = now - BWN_LO_CALIB_EXPIRE;
2679         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2680                 if (!time_before(cal->calib_time, expire))
2681                         continue;
2682                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2683                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2684                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2685                         expired = 1;
2686                 }
2687
2688                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2689                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2690                     cal->ctl.i, cal->ctl.q);
2691
2692                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2693                 free(cal, M_DEVBUF);
2694         }
2695         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2696                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2697                     &pg->pg_rfatt);
2698                 if (cal == NULL) {
2699                         device_printf(sc->sc_dev,
2700                             "failed to recalibrate LO\n");
2701                         goto fail;
2702                 }
2703                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2704                 bwn_lo_write(mac, &cal->ctl);
2705         }
2706
2707 fail:
2708         bwn_mac_enable(mac);
2709 }
2710
2711 static void
2712 bwn_phy_g_task_60s(struct bwn_mac *mac)
2713 {
2714         struct bwn_phy *phy = &mac->mac_phy;
2715         struct bwn_softc *sc = mac->mac_sc;
2716         uint8_t old = phy->chan;
2717
2718         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2719                 return;
2720
2721         bwn_mac_suspend(mac);
2722         bwn_nrssi_slope_11g(mac);
2723         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2724                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2725                 bwn_switch_channel(mac, old);
2726         }
2727         bwn_mac_enable(mac);
2728 }
2729
2730 static void
2731 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2732 {
2733
2734         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2735 }
2736
2737 static int
2738 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2739         const struct ieee80211_bpf_params *params)
2740 {
2741         struct ieee80211com *ic = ni->ni_ic;
2742         struct ifnet *ifp = ic->ic_ifp;
2743         struct bwn_softc *sc = ifp->if_softc;
2744         struct bwn_mac *mac = sc->sc_curmac;
2745
2746         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2747             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2748                 ieee80211_free_node(ni);
2749                 m_freem(m);
2750                 return (ENETDOWN);
2751         }
2752
2753         BWN_LOCK(sc);
2754         if (bwn_tx_isfull(sc, m)) {
2755                 ieee80211_free_node(ni);
2756                 m_freem(m);
2757                 ifp->if_oerrors++;
2758                 BWN_UNLOCK(sc);
2759                 return (ENOBUFS);
2760         }
2761
2762         if (bwn_tx_start(sc, ni, m) != 0) {
2763                 if (ni != NULL)
2764                         ieee80211_free_node(ni);
2765                 ifp->if_oerrors++;
2766         }
2767         sc->sc_watchdog_timer = 5;
2768         BWN_UNLOCK(sc);
2769         return (0);
2770 }
2771
2772 /*
2773  * Setup driver-specific state for a newly associated node.
2774  * Note that we're called also on a re-associate, the isnew
2775  * param tells us if this is the first time or not.
2776  */
2777 static void
2778 bwn_newassoc(struct ieee80211_node *ni, int isnew)
2779 {
2780         struct ieee80211vap *vap = ni->ni_vap;
2781
2782         ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
2783             &BWN_NODE(ni)->bn_amn, ni);
2784 }
2785
2786 /*
2787  * Callback from the 802.11 layer to update the slot time
2788  * based on the current setting.  We use it to notify the
2789  * firmware of ERP changes and the f/w takes care of things
2790  * like slot time and preamble.
2791  */
2792 static void
2793 bwn_updateslot(struct ifnet *ifp)
2794 {
2795         struct bwn_softc *sc = ifp->if_softc;
2796         struct ieee80211com *ic = ifp->if_l2com;
2797         struct bwn_mac *mac;
2798
2799         BWN_LOCK(sc);
2800         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2801                 mac = (struct bwn_mac *)sc->sc_curmac;
2802                 bwn_set_slot_time(mac,
2803                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2804         }
2805         BWN_UNLOCK(sc);
2806 }
2807
2808 /*
2809  * Callback from the 802.11 layer after a promiscuous mode change.
2810  * Note this interface does not check the operating mode as this
2811  * is an internal callback and we are expected to honor the current
2812  * state (e.g. this is used for setting the interface in promiscuous
2813  * mode when operating in hostap mode to do ACS).
2814  */
2815 static void
2816 bwn_update_promisc(struct ifnet *ifp)
2817 {
2818         struct bwn_softc *sc = ifp->if_softc;
2819         struct bwn_mac *mac = sc->sc_curmac;
2820
2821         BWN_LOCK(sc);
2822         mac = sc->sc_curmac;
2823         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2824                 if (ifp->if_flags & IFF_PROMISC)
2825                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2826                 else
2827                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2828                 bwn_set_opmode(mac);
2829         }
2830         BWN_UNLOCK(sc);
2831 }
2832
2833 /*
2834  * Callback from the 802.11 layer to update WME parameters.
2835  */
2836 static int
2837 bwn_wme_update(struct ieee80211com *ic)
2838 {
2839         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2840         struct bwn_mac *mac = sc->sc_curmac;
2841         struct wmeParams *wmep;
2842         int i;
2843
2844         BWN_LOCK(sc);
2845         mac = sc->sc_curmac;
2846         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847                 bwn_mac_suspend(mac);
2848                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2849                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2850                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2851                 }
2852                 bwn_mac_enable(mac);
2853         }
2854         BWN_UNLOCK(sc);
2855         return (0);
2856 }
2857
2858 static struct ieee80211_node *
2859 bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
2860 {
2861         struct ieee80211com *ic = vap->iv_ic;
2862         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2863         const size_t space = sizeof(struct bwn_node);
2864         struct bwn_node *bn;
2865
2866         bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
2867         if (bn == NULL) {
2868                 /* XXX stat+msg */
2869                 return (NULL);
2870         }
2871         DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
2872         return (&bn->bn_node);
2873 }
2874
2875 static void
2876 bwn_node_cleanup(struct ieee80211_node *ni)
2877 {
2878         struct ieee80211com *ic = ni->ni_ic;
2879         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2880
2881         sc->sc_node_cleanup(ni);
2882 }
2883
2884 static void
2885 bwn_scan_start(struct ieee80211com *ic)
2886 {
2887         struct ifnet *ifp = ic->ic_ifp;
2888         struct bwn_softc *sc = ifp->if_softc;
2889         struct bwn_mac *mac;
2890
2891         BWN_LOCK(sc);
2892         mac = sc->sc_curmac;
2893         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2894                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2895                 bwn_set_opmode(mac);
2896                 /* disable CFP update during scan */
2897                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2898         }
2899         BWN_UNLOCK(sc);
2900 }
2901
2902 static void
2903 bwn_scan_end(struct ieee80211com *ic)
2904 {
2905         struct ifnet *ifp = ic->ic_ifp;
2906         struct bwn_softc *sc = ifp->if_softc;
2907         struct bwn_mac *mac;
2908
2909         BWN_LOCK(sc);
2910         mac = sc->sc_curmac;
2911         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2912                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2913                 bwn_set_opmode(mac);
2914                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2915         }
2916         BWN_UNLOCK(sc);
2917 }
2918
2919 static void
2920 bwn_set_channel(struct ieee80211com *ic)
2921 {
2922         struct ifnet *ifp = ic->ic_ifp;
2923         struct bwn_softc *sc = ifp->if_softc;
2924         struct bwn_mac *mac = sc->sc_curmac;
2925         struct bwn_phy *phy = &mac->mac_phy;
2926         int chan, error;
2927
2928         BWN_LOCK(sc);
2929
2930         error = bwn_switch_band(sc, ic->ic_curchan);
2931         if (error)
2932                 goto fail;;
2933         bwn_mac_suspend(mac);
2934         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2935         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2936         if (chan != phy->chan)
2937                 bwn_switch_channel(mac, chan);
2938
2939         /* TX power level */
2940         if (ic->ic_curchan->ic_maxpower != 0 &&
2941             ic->ic_curchan->ic_maxpower != phy->txpower) {
2942                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2943                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2944                     BWN_TXPWR_IGNORE_TSSI);
2945         }
2946
2947         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2948         if (phy->set_antenna)
2949                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2950
2951         if (sc->sc_rf_enabled != phy->rf_on) {
2952                 if (sc->sc_rf_enabled) {
2953                         bwn_rf_turnon(mac);
2954                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2955                                 device_printf(sc->sc_dev,
2956                                     "please turns on the RF switch\n");
2957                 } else
2958                         bwn_rf_turnoff(mac);
2959         }
2960
2961         bwn_mac_enable(mac);
2962
2963 fail:
2964         /*
2965          * Setup radio tap channel freq and flags
2966          */
2967         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2968                 htole16(ic->ic_curchan->ic_freq);
2969         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2970                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2971
2972         BWN_UNLOCK(sc);
2973 }
2974
2975 static struct ieee80211vap *
2976 bwn_vap_create(struct ieee80211com *ic,
2977         const char name[IFNAMSIZ], int unit, int opmode, int flags,
2978         const uint8_t bssid[IEEE80211_ADDR_LEN],
2979         const uint8_t mac0[IEEE80211_ADDR_LEN])
2980 {
2981         struct ifnet *ifp = ic->ic_ifp;
2982         struct bwn_softc *sc = ifp->if_softc;
2983         struct ieee80211vap *vap;
2984         struct bwn_vap *bvp;
2985         uint8_t mac[IEEE80211_ADDR_LEN];
2986
2987         IEEE80211_ADDR_COPY(mac, mac0);
2988         switch (opmode) {
2989         case IEEE80211_M_HOSTAP:
2990         case IEEE80211_M_MBSS:
2991         case IEEE80211_M_STA:
2992         case IEEE80211_M_WDS:
2993         case IEEE80211_M_MONITOR:
2994         case IEEE80211_M_IBSS:
2995         case IEEE80211_M_AHDEMO:
2996                 break;
2997         default:
2998                 return (NULL);
2999         }
3000
3001         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
3002
3003         bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
3004             M_80211_VAP, M_NOWAIT | M_ZERO);
3005         if (bvp == NULL) {
3006                 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
3007                 return (NULL);
3008         }
3009         vap = &bvp->bv_vap;
3010         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
3011         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
3012         /* override with driver methods */
3013         bvp->bv_newstate = vap->iv_newstate;
3014         vap->iv_newstate = bwn_newstate;
3015
3016         /* override max aid so sta's cannot assoc when we're out of sta id's */
3017         vap->iv_max_aid = BWN_STAID_MAX;
3018
3019         ieee80211_amrr_init(&bvp->bv_amrr, vap,
3020             IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
3021             IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
3022             500 /*ms*/);
3023
3024         /* complete setup */
3025         ieee80211_vap_attach(vap, ieee80211_media_change,
3026             ieee80211_media_status);
3027         return (vap);
3028 }
3029
3030 static void
3031 bwn_vap_delete(struct ieee80211vap *vap)
3032 {
3033         struct bwn_vap *bvp = BWN_VAP(vap);
3034
3035         ieee80211_amrr_cleanup(&bvp->bv_amrr);
3036         ieee80211_vap_detach(vap);
3037         free(bvp, M_80211_VAP);
3038 }
3039
3040 static void
3041 bwn_init(void *arg)
3042 {
3043         struct bwn_softc *sc = arg;
3044         struct ifnet *ifp = sc->sc_ifp;
3045         struct ieee80211com *ic = ifp->if_l2com;
3046         int error = 0;
3047
3048         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3049                 __func__, ifp->if_flags);
3050
3051         BWN_LOCK(sc);
3052         error = bwn_init_locked(sc);
3053         BWN_UNLOCK(sc);
3054
3055         if (error == 0)
3056                 ieee80211_start_all(ic);        /* start all vap's */
3057 }
3058
3059 static int
3060 bwn_init_locked(struct bwn_softc *sc)
3061 {
3062         struct bwn_mac *mac;
3063         struct ifnet *ifp = sc->sc_ifp;
3064         int error;
3065
3066         BWN_ASSERT_LOCKED(sc);
3067
3068         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3069         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3070         sc->sc_filters = 0;
3071         bwn_wme_clear(sc);
3072         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3073         sc->sc_rf_enabled = 1;
3074
3075         mac = sc->sc_curmac;
3076         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3077                 error = bwn_core_init(mac);
3078                 if (error != 0)
3079                         return (error);
3080         }
3081         if (mac->mac_status == BWN_MAC_STATUS_INITED)
3082                 bwn_core_start(mac);
3083
3084         bwn_set_opmode(mac);
3085         bwn_set_pretbtt(mac);
3086         bwn_spu_setdelay(mac, 0);
3087         bwn_set_macaddr(mac);
3088
3089         ifp->if_drv_flags |= IFF_DRV_RUNNING;
3090         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3091         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3092
3093         return (0);
3094 }
3095
3096 static void
3097 bwn_stop(struct bwn_softc *sc, int statechg)
3098 {
3099
3100         BWN_LOCK(sc);
3101         bwn_stop_locked(sc, statechg);
3102         BWN_UNLOCK(sc);
3103 }
3104
3105 static void
3106 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3107 {
3108         struct bwn_mac *mac = sc->sc_curmac;
3109         struct ifnet *ifp = sc->sc_ifp;
3110
3111         BWN_ASSERT_LOCKED(sc);
3112
3113         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3114                 /* XXX FIXME opmode not based on VAP */
3115                 bwn_set_opmode(mac);
3116                 bwn_set_macaddr(mac);
3117         }
3118
3119         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3120                 bwn_core_stop(mac);
3121
3122         callout_stop(&sc->sc_led_blink_ch);
3123         sc->sc_led_blinking = 0;
3124
3125         bwn_core_exit(mac);
3126         sc->sc_rf_enabled = 0;
3127
3128         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3129 }
3130
3131 static void
3132 bwn_wme_clear(struct bwn_softc *sc)
3133 {
3134 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3135         struct wmeParams *p;
3136         unsigned int i;
3137
3138         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3139             ("%s:%d: fail", __func__, __LINE__));
3140
3141         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3142                 p = &(sc->sc_wmeParams[i]);
3143
3144                 switch (bwn_wme_shm_offsets[i]) {
3145                 case BWN_WME_VOICE:
3146                         p->wmep_txopLimit = 0;
3147                         p->wmep_aifsn = 2;
3148                         /* XXX FIXME: log2(cwmin) */
3149                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3150                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3151                         break;
3152                 case BWN_WME_VIDEO:
3153                         p->wmep_txopLimit = 0;
3154                         p->wmep_aifsn = 2;
3155                         /* XXX FIXME: log2(cwmin) */
3156                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3157                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3158                         break;
3159                 case BWN_WME_BESTEFFORT:
3160                         p->wmep_txopLimit = 0;
3161                         p->wmep_aifsn = 3;
3162                         /* XXX FIXME: log2(cwmin) */
3163                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3164                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3165                         break;
3166                 case BWN_WME_BACKGROUND:
3167                         p->wmep_txopLimit = 0;
3168                         p->wmep_aifsn = 7;
3169                         /* XXX FIXME: log2(cwmin) */
3170                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3171                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3172                         break;
3173                 default:
3174                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3175                 }
3176         }
3177 }
3178
3179 static int
3180 bwn_core_init(struct bwn_mac *mac)
3181 {
3182         struct bwn_softc *sc = mac->mac_sc;
3183         uint64_t hf;
3184         int error;
3185
3186         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3187             ("%s:%d: fail", __func__, __LINE__));
3188
3189         siba_powerup(sc->sc_dev, 0);
3190         if (!siba_dev_isup(sc->sc_dev))
3191                 bwn_reset_core(mac,
3192                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3193
3194         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3195         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3196         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3197         BWN_GETTIME(mac->mac_phy.nexttime);
3198         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3199         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3200         mac->mac_stats.link_noise = -95;
3201         mac->mac_reason_intr = 0;
3202         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3203         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3204 #ifdef BWN_DEBUG
3205         if (sc->sc_debug & BWN_DEBUG_XMIT)
3206                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3207 #endif
3208         mac->mac_suspended = 1;
3209         mac->mac_task_state = 0;
3210         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3211
3212         mac->mac_phy.init_pre(mac);
3213
3214         siba_pcicore_intr(sc->sc_dev);
3215
3216         siba_fix_imcfglobug(sc->sc_dev);
3217         bwn_bt_disable(mac);
3218         if (mac->mac_phy.prepare_hw) {
3219                 error = mac->mac_phy.prepare_hw(mac);
3220                 if (error)
3221                         goto fail0;
3222         }
3223         error = bwn_chip_init(mac);
3224         if (error)
3225                 goto fail0;
3226         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3227             siba_get_revid(sc->sc_dev));
3228         hf = bwn_hf_read(mac);
3229         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3230                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3231                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3232                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3233                 if (mac->mac_phy.rev == 1)
3234                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3235         }
3236         if (mac->mac_phy.rf_ver == 0x2050) {
3237                 if (mac->mac_phy.rf_rev < 6)
3238                         hf |= BWN_HF_FORCE_VCO_RECALC;
3239                 if (mac->mac_phy.rf_rev == 6)
3240                         hf |= BWN_HF_4318_TSSI;
3241         }
3242         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3243                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3244         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3245             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3246                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3247         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3248         bwn_hf_write(mac, hf);
3249
3250         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3251         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3252         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3253         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3254
3255         bwn_rate_init(mac);
3256         bwn_set_phytxctl(mac);
3257
3258         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3259             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3260         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3261
3262         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3263                 bwn_pio_init(mac);
3264         else
3265                 bwn_dma_init(mac);
3266         if (error)
3267                 goto fail1;
3268         bwn_wme_init(mac);
3269         bwn_spu_setdelay(mac, 1);
3270         bwn_bt_enable(mac);
3271
3272         siba_powerup(sc->sc_dev,
3273             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3274         bwn_set_macaddr(mac);
3275         bwn_crypt_init(mac);
3276
3277         /* XXX LED initializatin */
3278
3279         mac->mac_status = BWN_MAC_STATUS_INITED;
3280
3281         return (error);
3282
3283 fail1:
3284         bwn_chip_exit(mac);
3285 fail0:
3286         siba_powerdown(sc->sc_dev);
3287         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3288             ("%s:%d: fail", __func__, __LINE__));
3289         return (error);
3290 }
3291
3292 static void
3293 bwn_core_start(struct bwn_mac *mac)
3294 {
3295         struct bwn_softc *sc = mac->mac_sc;
3296         uint32_t tmp;
3297
3298         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3299             ("%s:%d: fail", __func__, __LINE__));
3300
3301         if (siba_get_revid(sc->sc_dev) < 5)
3302                 return;
3303
3304         while (1) {
3305                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3306                 if (!(tmp & 0x00000001))
3307                         break;
3308                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3309         }
3310
3311         bwn_mac_enable(mac);
3312         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3313         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3314
3315         mac->mac_status = BWN_MAC_STATUS_STARTED;
3316 }
3317
3318 static void
3319 bwn_core_exit(struct bwn_mac *mac)
3320 {
3321         struct bwn_softc *sc = mac->mac_sc;
3322         uint32_t macctl;
3323
3324         BWN_ASSERT_LOCKED(mac->mac_sc);
3325
3326         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3327             ("%s:%d: fail", __func__, __LINE__));
3328
3329         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3330                 return;
3331         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3332
3333         macctl = BWN_READ_4(mac, BWN_MACCTL);
3334         macctl &= ~BWN_MACCTL_MCODE_RUN;
3335         macctl |= BWN_MACCTL_MCODE_JMP0;
3336         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3337
3338         bwn_dma_stop(mac);
3339         bwn_pio_stop(mac);
3340         bwn_chip_exit(mac);
3341         mac->mac_phy.switch_analog(mac, 0);
3342         siba_dev_down(sc->sc_dev, 0);
3343         siba_powerdown(sc->sc_dev);
3344 }
3345
3346 static void
3347 bwn_bt_disable(struct bwn_mac *mac)
3348 {
3349         struct bwn_softc *sc = mac->mac_sc;
3350
3351         (void)sc;
3352         /* XXX do nothing yet */
3353 }
3354
3355 static int
3356 bwn_chip_init(struct bwn_mac *mac)
3357 {
3358         struct bwn_softc *sc = mac->mac_sc;
3359         struct bwn_phy *phy = &mac->mac_phy;
3360         uint32_t macctl;
3361         int error;
3362
3363         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3364         if (phy->gmode)
3365                 macctl |= BWN_MACCTL_GMODE;
3366         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3367
3368         error = bwn_fw_fillinfo(mac);
3369         if (error)
3370                 return (error);
3371         error = bwn_fw_loaducode(mac);
3372         if (error)
3373                 return (error);
3374
3375         error = bwn_gpio_init(mac);
3376         if (error)
3377                 return (error);
3378
3379         error = bwn_fw_loadinitvals(mac);
3380         if (error) {
3381                 siba_gpio_set(sc->sc_dev, 0);
3382                 return (error);
3383         }
3384         phy->switch_analog(mac, 1);
3385         error = bwn_phy_init(mac);
3386         if (error) {
3387                 siba_gpio_set(sc->sc_dev, 0);
3388                 return (error);
3389         }
3390         if (phy->set_im)
3391                 phy->set_im(mac, BWN_IMMODE_NONE);
3392         if (phy->set_antenna)
3393                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3394         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3395
3396         if (phy->type == BWN_PHYTYPE_B)
3397                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3398         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3399         if (siba_get_revid(sc->sc_dev) < 5)
3400                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3401
3402         BWN_WRITE_4(mac, BWN_MACCTL,
3403             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3404         BWN_WRITE_4(mac, BWN_MACCTL,
3405             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3406         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3407
3408         bwn_set_opmode(mac);
3409         if (siba_get_revid(sc->sc_dev) < 3) {
3410                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3411                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3412                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3413                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3414         } else {
3415                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3416                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3417         }
3418         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3419         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3420         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3421         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3422         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3423         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3424         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3425         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3426             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3427         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3428         return (error);
3429 }
3430
3431 /* read hostflags */
3432 static uint64_t
3433 bwn_hf_read(struct bwn_mac *mac)
3434 {
3435         uint64_t ret;
3436
3437         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3438         ret <<= 16;
3439         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3440         ret <<= 16;
3441         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3442         return (ret);
3443 }
3444
3445 static void
3446 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3447 {
3448
3449         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3450             (value & 0x00000000ffffull));
3451         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3452             (value & 0x0000ffff0000ull) >> 16);
3453         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3454             (value & 0xffff00000000ULL) >> 32);
3455 }
3456
3457 static void
3458 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3459 {
3460
3461         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3462         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3463 }
3464
3465 static void
3466 bwn_rate_init(struct bwn_mac *mac)
3467 {
3468
3469         switch (mac->mac_phy.type) {
3470         case BWN_PHYTYPE_A:
3471         case BWN_PHYTYPE_G:
3472         case BWN_PHYTYPE_LP:
3473         case BWN_PHYTYPE_N:
3474                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3475                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3476                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3477                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3478                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3479                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3480                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3481                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3482                         break;
3483                 /* FALLTHROUGH */
3484         case BWN_PHYTYPE_B:
3485                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3486                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3487                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3488                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3489                 break;
3490         default:
3491                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3492         }
3493 }
3494
3495 static void
3496 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3497 {
3498         uint16_t offset;
3499
3500         if (ofdm) {
3501                 offset = 0x480;
3502                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3503         } else {
3504                 offset = 0x4c0;
3505                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3506         }
3507         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3508             bwn_shm_read_2(mac, BWN_SHARED, offset));
3509 }
3510
3511 static uint8_t
3512 bwn_plcp_getcck(const uint8_t bitrate)
3513 {
3514
3515         switch (bitrate) {
3516         case BWN_CCK_RATE_1MB:
3517                 return (0x0a);
3518         case BWN_CCK_RATE_2MB:
3519                 return (0x14);
3520         case BWN_CCK_RATE_5MB:
3521                 return (0x37);
3522         case BWN_CCK_RATE_11MB:
3523                 return (0x6e);
3524         }
3525         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3526         return (0);
3527 }
3528
3529 static uint8_t
3530 bwn_plcp_getofdm(const uint8_t bitrate)
3531 {
3532
3533         switch (bitrate) {
3534         case BWN_OFDM_RATE_6MB:
3535                 return (0xb);
3536         case BWN_OFDM_RATE_9MB:
3537                 return (0xf);
3538         case BWN_OFDM_RATE_12MB:
3539                 return (0xa);
3540         case BWN_OFDM_RATE_18MB:
3541                 return (0xe);
3542         case BWN_OFDM_RATE_24MB:
3543                 return (0x9);
3544         case BWN_OFDM_RATE_36MB:
3545                 return (0xd);
3546         case BWN_OFDM_RATE_48MB:
3547                 return (0x8);
3548         case BWN_OFDM_RATE_54MB:
3549                 return (0xc);
3550         }
3551         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3552         return (0);
3553 }
3554
3555 static void
3556 bwn_set_phytxctl(struct bwn_mac *mac)
3557 {
3558         uint16_t ctl;
3559
3560         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3561             BWN_TX_PHY_TXPWR);
3562         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3563         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3564         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3565 }
3566
3567 static void
3568 bwn_pio_init(struct bwn_mac *mac)
3569 {
3570         struct bwn_pio *pio = &mac->mac_method.pio;
3571
3572         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3573             & ~BWN_MACCTL_BIGENDIAN);
3574         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3575
3576         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3577         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3578         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3579         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3580         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3581         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3582 }
3583
3584 static void
3585 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3586     int index)
3587 {
3588         struct bwn_pio_txpkt *tp;
3589         struct bwn_softc *sc = mac->mac_sc;
3590         unsigned int i;
3591
3592         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3593         tq->tq_index = index;
3594
3595         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3596         if (siba_get_revid(sc->sc_dev) >= 8)
3597                 tq->tq_size = 1920;
3598         else {
3599                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3600                 tq->tq_size -= 80;
3601         }
3602
3603         TAILQ_INIT(&tq->tq_pktlist);
3604         for (i = 0; i < N(tq->tq_pkts); i++) {
3605                 tp = &(tq->tq_pkts[i]);
3606                 tp->tp_index = i;
3607                 tp->tp_queue = tq;
3608                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3609         }
3610 }
3611
3612 static uint16_t
3613 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3614 {
3615         struct bwn_softc *sc = mac->mac_sc;
3616         static const uint16_t bases[] = {
3617                 BWN_PIO_BASE0,
3618                 BWN_PIO_BASE1,
3619                 BWN_PIO_BASE2,
3620                 BWN_PIO_BASE3,
3621                 BWN_PIO_BASE4,
3622                 BWN_PIO_BASE5,
3623                 BWN_PIO_BASE6,
3624                 BWN_PIO_BASE7,
3625         };
3626         static const uint16_t bases_rev11[] = {
3627                 BWN_PIO11_BASE0,
3628                 BWN_PIO11_BASE1,
3629                 BWN_PIO11_BASE2,
3630                 BWN_PIO11_BASE3,
3631                 BWN_PIO11_BASE4,
3632                 BWN_PIO11_BASE5,
3633         };
3634
3635         if (siba_get_revid(sc->sc_dev) >= 11) {
3636                 if (index >= N(bases_rev11))
3637                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3638                 return (bases_rev11[index]);
3639         }
3640         if (index >= N(bases))
3641                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3642         return (bases[index]);
3643 }
3644
3645 static void
3646 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3647     int index)
3648 {
3649         struct bwn_softc *sc = mac->mac_sc;
3650
3651         prq->prq_mac = mac;
3652         prq->prq_rev = siba_get_revid(sc->sc_dev);
3653         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3654         bwn_dma_rxdirectfifo(mac, index, 1);
3655 }
3656
3657 static void
3658 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3659 {
3660         if (tq == NULL)
3661                 return;
3662         bwn_pio_cancel_tx_packets(tq);
3663 }
3664
3665 static void
3666 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3667 {
3668
3669         bwn_destroy_pioqueue_tx(pio);
3670 }
3671
3672 static uint16_t
3673 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3674     uint16_t offset)
3675 {
3676
3677         return (BWN_READ_2(mac, tq->tq_base + offset));
3678 }
3679
3680 static void
3681 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3682 {
3683         uint32_t ctl;
3684         int type;
3685         uint16_t base;
3686
3687         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3688         base = bwn_dma_base(type, idx);
3689         if (type == BWN_DMA_64BIT) {
3690                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3691                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3692                 if (enable)
3693                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3694                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3695         } else {
3696                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3697                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3698                 if (enable)
3699                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3700                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3701         }
3702 }
3703
3704 static uint64_t
3705 bwn_dma_mask(struct bwn_mac *mac)
3706 {
3707         uint32_t tmp;
3708         uint16_t base;
3709
3710         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3711         if (tmp & SIBA_TGSHIGH_DMA64)
3712                 return (BWN_DMA_BIT_MASK(64));
3713         base = bwn_dma_base(0, 0);
3714         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3715         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3716         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3717                 return (BWN_DMA_BIT_MASK(32));
3718
3719         return (BWN_DMA_BIT_MASK(30));
3720 }
3721
3722 static int
3723 bwn_dma_mask2type(uint64_t dmamask)
3724 {
3725
3726         if (dmamask == BWN_DMA_BIT_MASK(30))
3727                 return (BWN_DMA_30BIT);
3728         if (dmamask == BWN_DMA_BIT_MASK(32))
3729                 return (BWN_DMA_32BIT);
3730         if (dmamask == BWN_DMA_BIT_MASK(64))
3731                 return (BWN_DMA_64BIT);
3732         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3733         return (BWN_DMA_30BIT);
3734 }
3735
3736 static void
3737 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3738 {
3739         struct bwn_pio_txpkt *tp;
3740         unsigned int i;
3741
3742         for (i = 0; i < N(tq->tq_pkts); i++) {
3743                 tp = &(tq->tq_pkts[i]);
3744                 if (tp->tp_m) {
3745                         m_freem(tp->tp_m);
3746                         tp->tp_m = NULL;
3747                 }
3748         }
3749 }
3750
3751 static uint16_t
3752 bwn_dma_base(int type, int controller_idx)
3753 {
3754         static const uint16_t map64[] = {
3755                 BWN_DMA64_BASE0,
3756                 BWN_DMA64_BASE1,
3757                 BWN_DMA64_BASE2,
3758                 BWN_DMA64_BASE3,
3759                 BWN_DMA64_BASE4,
3760                 BWN_DMA64_BASE5,
3761         };
3762         static const uint16_t map32[] = {
3763                 BWN_DMA32_BASE0,
3764                 BWN_DMA32_BASE1,
3765                 BWN_DMA32_BASE2,
3766                 BWN_DMA32_BASE3,
3767                 BWN_DMA32_BASE4,
3768                 BWN_DMA32_BASE5,
3769         };
3770
3771         if (type == BWN_DMA_64BIT) {
3772                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3773                     ("%s:%d: fail", __func__, __LINE__));
3774                 return (map64[controller_idx]);
3775         }
3776         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3777             ("%s:%d: fail", __func__, __LINE__));
3778         return (map32[controller_idx]);
3779 }
3780
3781 static void
3782 bwn_dma_init(struct bwn_mac *mac)
3783 {
3784         struct bwn_dma *dma = &mac->mac_method.dma;
3785
3786         /* setup TX DMA channels. */
3787         bwn_dma_setup(dma->wme[WME_AC_BK]);
3788         bwn_dma_setup(dma->wme[WME_AC_BE]);
3789         bwn_dma_setup(dma->wme[WME_AC_VI]);
3790         bwn_dma_setup(dma->wme[WME_AC_VO]);
3791         bwn_dma_setup(dma->mcast);
3792         /* setup RX DMA channel. */
3793         bwn_dma_setup(dma->rx);
3794 }
3795
3796 static struct bwn_dma_ring *
3797 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3798     int for_tx, int type)
3799 {
3800         struct bwn_dma *dma = &mac->mac_method.dma;
3801         struct bwn_dma_ring *dr;
3802         struct bwn_dmadesc_generic *desc;
3803         struct bwn_dmadesc_meta *mt;
3804         struct bwn_softc *sc = mac->mac_sc;
3805         int error, i;
3806
3807         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3808         if (dr == NULL)
3809                 goto out;
3810         dr->dr_numslots = BWN_RXRING_SLOTS;
3811         if (for_tx)
3812                 dr->dr_numslots = BWN_TXRING_SLOTS;
3813
3814         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3815             M_DEVBUF, M_NOWAIT | M_ZERO);
3816         if (dr->dr_meta == NULL)
3817                 goto fail0;
3818
3819         dr->dr_type = type;
3820         dr->dr_mac = mac;
3821         dr->dr_base = bwn_dma_base(type, controller_index);
3822         dr->dr_index = controller_index;
3823         if (type == BWN_DMA_64BIT) {
3824                 dr->getdesc = bwn_dma_64_getdesc;
3825                 dr->setdesc = bwn_dma_64_setdesc;
3826                 dr->start_transfer = bwn_dma_64_start_transfer;
3827                 dr->suspend = bwn_dma_64_suspend;
3828                 dr->resume = bwn_dma_64_resume;
3829                 dr->get_curslot = bwn_dma_64_get_curslot;
3830                 dr->set_curslot = bwn_dma_64_set_curslot;
3831         } else {
3832                 dr->getdesc = bwn_dma_32_getdesc;
3833                 dr->setdesc = bwn_dma_32_setdesc;
3834                 dr->start_transfer = bwn_dma_32_start_transfer;
3835                 dr->suspend = bwn_dma_32_suspend;
3836                 dr->resume = bwn_dma_32_resume;
3837                 dr->get_curslot = bwn_dma_32_get_curslot;
3838                 dr->set_curslot = bwn_dma_32_set_curslot;
3839         }
3840         if (for_tx) {
3841                 dr->dr_tx = 1;
3842                 dr->dr_curslot = -1;
3843         } else {
3844                 if (dr->dr_index == 0) {
3845                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3846                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3847                 } else
3848                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3849         }
3850
3851         error = bwn_dma_allocringmemory(dr);
3852         if (error)
3853                 goto fail2;
3854
3855         if (for_tx) {
3856                 /*
3857                  * Assumption: BWN_TXRING_SLOTS can be divided by
3858                  * BWN_TX_SLOTS_PER_FRAME
3859                  */
3860                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3861                     ("%s:%d: fail", __func__, __LINE__));
3862
3863                 dr->dr_txhdr_cache =
3864                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3865                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3866                 KASSERT(dr->dr_txhdr_cache != NULL,
3867                     ("%s:%d: fail", __func__, __LINE__));
3868
3869                 /*
3870                  * Create TX ring DMA stuffs
3871                  */
3872                 error = bus_dma_tag_create(dma->parent_dtag,
3873                                     BWN_ALIGN, 0,
3874                                     BUS_SPACE_MAXADDR,
3875                                     BUS_SPACE_MAXADDR,
3876                                     NULL, NULL,
3877                                     BWN_HDRSIZE(mac),
3878                                     1,
3879                                     BUS_SPACE_MAXSIZE_32BIT,
3880                                     0,
3881                                     NULL, NULL,
3882                                     &dr->dr_txring_dtag);
3883                 if (error) {
3884                         device_printf(sc->sc_dev,
3885                             "can't create TX ring DMA tag: TODO frees\n");
3886                         goto fail1;
3887                 }
3888
3889                 for (i = 0; i < dr->dr_numslots; i += 2) {
3890                         dr->getdesc(dr, i, &desc, &mt);
3891
3892                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3893                         mt->mt_m = NULL;
3894                         mt->mt_ni = NULL;
3895                         mt->mt_islast = 0;
3896                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3897                             &mt->mt_dmap);
3898                         if (error) {
3899                                 device_printf(sc->sc_dev,
3900                                      "can't create RX buf DMA map\n");
3901                                 goto fail1;
3902                         }
3903
3904                         dr->getdesc(dr, i + 1, &desc, &mt);
3905
3906                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3907                         mt->mt_m = NULL;
3908                         mt->mt_ni = NULL;
3909                         mt->mt_islast = 1;
3910                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3911                             &mt->mt_dmap);
3912                         if (error) {
3913                                 device_printf(sc->sc_dev,
3914                                      "can't create RX buf DMA map\n");
3915                                 goto fail1;
3916                         }
3917                 }
3918         } else {
3919                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3920                     &dr->dr_spare_dmap);
3921                 if (error) {
3922                         device_printf(sc->sc_dev,
3923                             "can't create RX buf DMA map\n");
3924                         goto out;               /* XXX wrong! */
3925                 }
3926
3927                 for (i = 0; i < dr->dr_numslots; i++) {
3928                         dr->getdesc(dr, i, &desc, &mt);
3929
3930                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3931                             &mt->mt_dmap);
3932                         if (error) {
3933                                 device_printf(sc->sc_dev,
3934                                     "can't create RX buf DMA map\n");
3935                                 goto out;       /* XXX wrong! */
3936                         }
3937                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3938                         if (error) {
3939                                 device_printf(sc->sc_dev,
3940                                     "failed to allocate RX buf\n");
3941                                 goto out;       /* XXX wrong! */
3942                         }
3943                 }
3944
3945                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3946                     BUS_DMASYNC_PREWRITE);
3947
3948                 dr->dr_usedslot = dr->dr_numslots;
3949         }
3950
3951       out:
3952         return (dr);
3953
3954 fail2:
3955         free(dr->dr_txhdr_cache, M_DEVBUF);
3956 fail1:
3957         free(dr->dr_meta, M_DEVBUF);
3958 fail0:
3959         free(dr, M_DEVBUF);
3960         return (NULL);
3961 }
3962
3963 static void
3964 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3965 {
3966
3967         if (dr == NULL)
3968                 return;
3969
3970         bwn_dma_free_descbufs(*dr);
3971         bwn_dma_free_ringmemory(*dr);
3972
3973         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3974         free((*dr)->dr_meta, M_DEVBUF);
3975         free(*dr, M_DEVBUF);
3976
3977         *dr = NULL;
3978 }
3979
3980 static void
3981 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3982     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3983 {
3984         struct bwn_dmadesc32 *desc;
3985
3986         *meta = &(dr->dr_meta[slot]);
3987         desc = dr->dr_ring_descbase;
3988         desc = &(desc[slot]);
3989
3990         *gdesc = (struct bwn_dmadesc_generic *)desc;
3991 }
3992
3993 static void
3994 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3995     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3996     int start, int end, int irq)
3997 {
3998         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3999         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4000         uint32_t addr, addrext, ctl;
4001         int slot;
4002
4003         slot = (int)(&(desc->dma.dma32) - descbase);
4004         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4005             ("%s:%d: fail", __func__, __LINE__));
4006
4007         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
4008         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
4009         addr |= siba_dma_translation(sc->sc_dev);
4010         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
4011         if (slot == dr->dr_numslots - 1)
4012                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
4013         if (start)
4014                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
4015         if (end)
4016                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
4017         if (irq)
4018                 ctl |= BWN_DMA32_DCTL_IRQ;
4019         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
4020             & BWN_DMA32_DCTL_ADDREXT_MASK;
4021
4022         desc->dma.dma32.control = htole32(ctl);
4023         desc->dma.dma32.address = htole32(addr);
4024 }
4025
4026 static void
4027 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
4028 {
4029
4030         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
4031             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
4032 }
4033
4034 static void
4035 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
4036 {
4037
4038         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4039             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
4040 }
4041
4042 static void
4043 bwn_dma_32_resume(struct bwn_dma_ring *dr)
4044 {
4045
4046         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4047             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
4048 }
4049
4050 static int
4051 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4052 {
4053         uint32_t val;
4054
4055         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4056         val &= BWN_DMA32_RXDPTR;
4057
4058         return (val / sizeof(struct bwn_dmadesc32));
4059 }
4060
4061 static void
4062 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4063 {
4064
4065         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4066             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4067 }
4068
4069 static void
4070 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4071     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4072 {
4073         struct bwn_dmadesc64 *desc;
4074
4075         *meta = &(dr->dr_meta[slot]);
4076         desc = dr->dr_ring_descbase;
4077         desc = &(desc[slot]);
4078
4079         *gdesc = (struct bwn_dmadesc_generic *)desc;
4080 }
4081
4082 static void
4083 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4084     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4085     int start, int end, int irq)
4086 {
4087         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4088         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4089         int slot;
4090         uint32_t ctl0 = 0, ctl1 = 0;
4091         uint32_t addrlo, addrhi;
4092         uint32_t addrext;
4093
4094         slot = (int)(&(desc->dma.dma64) - descbase);
4095         KASSERT(slot >= 0 && slot < dr->dr_numslots,
4096             ("%s:%d: fail", __func__, __LINE__));
4097
4098         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4099         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4100         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4101             30;
4102         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4103         if (slot == dr->dr_numslots - 1)
4104                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4105         if (start)
4106                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4107         if (end)
4108                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4109         if (irq)
4110                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4111         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4112         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4113             & BWN_DMA64_DCTL1_ADDREXT_MASK;
4114
4115         desc->dma.dma64.control0 = htole32(ctl0);
4116         desc->dma.dma64.control1 = htole32(ctl1);
4117         desc->dma.dma64.address_low = htole32(addrlo);
4118         desc->dma.dma64.address_high = htole32(addrhi);
4119 }
4120
4121 static void
4122 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4123 {
4124
4125         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4126             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4127 }
4128
4129 static void
4130 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4131 {
4132
4133         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4134             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4135 }
4136
4137 static void
4138 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4139 {
4140
4141         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4142             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4143 }
4144
4145 static int
4146 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4147 {
4148         uint32_t val;
4149
4150         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4151         val &= BWN_DMA64_RXSTATDPTR;
4152
4153         return (val / sizeof(struct bwn_dmadesc64));
4154 }
4155
4156 static void
4157 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4158 {
4159
4160         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4161             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4162 }
4163
4164 static int
4165 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4166 {
4167         struct bwn_mac *mac = dr->dr_mac;
4168         struct bwn_dma *dma = &mac->mac_method.dma;
4169         struct bwn_softc *sc = mac->mac_sc;
4170         int error;
4171
4172         error = bus_dma_tag_create(dma->parent_dtag,
4173                             BWN_ALIGN, 0,
4174                             BUS_SPACE_MAXADDR,
4175                             BUS_SPACE_MAXADDR,
4176                             NULL, NULL,
4177                             BWN_DMA_RINGMEMSIZE,
4178                             1,
4179                             BUS_SPACE_MAXSIZE_32BIT,
4180                             0,
4181                             NULL, NULL,
4182                             &dr->dr_ring_dtag);
4183         if (error) {
4184                 device_printf(sc->sc_dev,
4185                     "can't create TX ring DMA tag: TODO frees\n");
4186                 return (-1);
4187         }
4188
4189         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4190             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4191             &dr->dr_ring_dmap);
4192         if (error) {
4193                 device_printf(sc->sc_dev,
4194                     "can't allocate DMA mem: TODO frees\n");
4195                 return (-1);
4196         }
4197         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4198             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4199             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4200         if (error) {
4201                 device_printf(sc->sc_dev,
4202                     "can't load DMA mem: TODO free\n");
4203                 return (-1);
4204         }
4205
4206         return (0);
4207 }
4208
4209 static void
4210 bwn_dma_setup(struct bwn_dma_ring *dr)
4211 {
4212         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4213         uint64_t ring64;
4214         uint32_t addrext, ring32, value;
4215         uint32_t trans = siba_dma_translation(sc->sc_dev);
4216
4217         if (dr->dr_tx) {
4218                 dr->dr_curslot = -1;
4219
4220                 if (dr->dr_type == BWN_DMA_64BIT) {
4221                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4222                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4223                             >> 30;
4224                         value = BWN_DMA64_TXENABLE;
4225                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4226                             & BWN_DMA64_TXADDREXT_MASK;
4227                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4228                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4229                             (ring64 & 0xffffffff));
4230                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4231                             ((ring64 >> 32) &
4232                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4233                 } else {
4234                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4235                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4236                         value = BWN_DMA32_TXENABLE;
4237                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4238                             & BWN_DMA32_TXADDREXT_MASK;
4239                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4240                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4241                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4242                 }
4243                 return;
4244         }
4245
4246         /*
4247          * set for RX
4248          */
4249         dr->dr_usedslot = dr->dr_numslots;
4250
4251         if (dr->dr_type == BWN_DMA_64BIT) {
4252                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4253                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4254                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4255                 value |= BWN_DMA64_RXENABLE;
4256                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4257                     & BWN_DMA64_RXADDREXT_MASK;
4258                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4259                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4260                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4261                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4262                     | (trans << 1));
4263                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4264                     sizeof(struct bwn_dmadesc64));
4265         } else {
4266                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4267                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4268                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4269                 value |= BWN_DMA32_RXENABLE;
4270                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4271                     & BWN_DMA32_RXADDREXT_MASK;
4272                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4273                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4274                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4275                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4276                     sizeof(struct bwn_dmadesc32));
4277         }
4278 }
4279
4280 static void
4281 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4282 {
4283
4284         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4285         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4286             dr->dr_ring_dmap);
4287 }
4288
4289 static void
4290 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4291 {
4292
4293         if (dr->dr_tx) {
4294                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4295                 if (dr->dr_type == BWN_DMA_64BIT) {
4296                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4297                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4298                 } else
4299                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4300         } else {
4301                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4302                 if (dr->dr_type == BWN_DMA_64BIT) {
4303                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4304                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4305                 } else
4306                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4307         }
4308 }
4309
4310 static void
4311 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4312 {
4313         struct bwn_dmadesc_generic *desc;
4314         struct bwn_dmadesc_meta *meta;
4315         struct bwn_mac *mac = dr->dr_mac;
4316         struct bwn_dma *dma = &mac->mac_method.dma;
4317         struct bwn_softc *sc = mac->mac_sc;
4318         int i;
4319
4320         if (!dr->dr_usedslot)
4321                 return;
4322         for (i = 0; i < dr->dr_numslots; i++) {
4323                 dr->getdesc(dr, i, &desc, &meta);
4324
4325                 if (meta->mt_m == NULL) {
4326                         if (!dr->dr_tx)
4327                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4328                                     __func__);
4329                         continue;
4330                 }
4331                 if (dr->dr_tx) {
4332                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4333                                 bus_dmamap_unload(dr->dr_txring_dtag,
4334                                     meta->mt_dmap);
4335                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4336                                 bus_dmamap_unload(dma->txbuf_dtag,
4337                                     meta->mt_dmap);
4338                 } else
4339                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4340                 bwn_dma_free_descbuf(dr, meta);
4341         }
4342 }
4343
4344 static int
4345 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4346     int type)
4347 {
4348         struct bwn_softc *sc = mac->mac_sc;
4349         uint32_t value;
4350         int i;
4351         uint16_t offset;
4352
4353         for (i = 0; i < 10; i++) {
4354                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4355                     BWN_DMA32_TXSTATUS;
4356                 value = BWN_READ_4(mac, base + offset);
4357                 if (type == BWN_DMA_64BIT) {
4358                         value &= BWN_DMA64_TXSTAT;
4359                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4360                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4361                             value == BWN_DMA64_TXSTAT_STOPPED)
4362                                 break;
4363                 } else {
4364                         value &= BWN_DMA32_TXSTATE;
4365                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4366                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4367                             value == BWN_DMA32_TXSTAT_STOPPED)
4368                                 break;
4369                 }
4370                 DELAY(1000);
4371         }
4372         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4373         BWN_WRITE_4(mac, base + offset, 0);
4374         for (i = 0; i < 10; i++) {
4375                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4376                                                    BWN_DMA32_TXSTATUS;
4377                 value = BWN_READ_4(mac, base + offset);
4378                 if (type == BWN_DMA_64BIT) {
4379                         value &= BWN_DMA64_TXSTAT;
4380                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4381                                 i = -1;
4382                                 break;
4383                         }
4384                 } else {
4385                         value &= BWN_DMA32_TXSTATE;
4386                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4387                                 i = -1;
4388                                 break;
4389                         }
4390                 }
4391                 DELAY(1000);
4392         }
4393         if (i != -1) {
4394                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4395                 return (ENODEV);
4396         }
4397         DELAY(1000);
4398
4399         return (0);
4400 }
4401
4402 static int
4403 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4404     int type)
4405 {
4406         struct bwn_softc *sc = mac->mac_sc;
4407         uint32_t value;
4408         int i;
4409         uint16_t offset;
4410
4411         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4412         BWN_WRITE_4(mac, base + offset, 0);
4413         for (i = 0; i < 10; i++) {
4414                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4415                     BWN_DMA32_RXSTATUS;
4416                 value = BWN_READ_4(mac, base + offset);
4417                 if (type == BWN_DMA_64BIT) {
4418                         value &= BWN_DMA64_RXSTAT;
4419                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4420                                 i = -1;
4421                                 break;
4422                         }
4423                 } else {
4424                         value &= BWN_DMA32_RXSTATE;
4425                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4426                                 i = -1;
4427                                 break;
4428                         }
4429                 }
4430                 DELAY(1000);
4431         }
4432         if (i != -1) {
4433                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4434                 return (ENODEV);
4435         }
4436
4437         return (0);
4438 }
4439
4440 static void
4441 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4442     struct bwn_dmadesc_meta *meta)
4443 {
4444
4445         if (meta->mt_m != NULL) {
4446                 m_freem(meta->mt_m);
4447                 meta->mt_m = NULL;
4448         }
4449         if (meta->mt_ni != NULL) {
4450                 ieee80211_free_node(meta->mt_ni);
4451                 meta->mt_ni = NULL;
4452         }
4453 }
4454
4455 static void
4456 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4457 {
4458         struct bwn_rxhdr4 *rxhdr;
4459         unsigned char *frame;
4460
4461         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4462         rxhdr->frame_len = 0;
4463
4464         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4465             sizeof(struct bwn_plcp6) + 2,
4466             ("%s:%d: fail", __func__, __LINE__));
4467         frame = mtod(m, char *) + dr->dr_frameoffset;
4468         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4469 }
4470
4471 static uint8_t
4472 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4473 {
4474         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4475
4476         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4477             == 0xff);
4478 }
4479
4480 static void
4481 bwn_wme_init(struct bwn_mac *mac)
4482 {
4483
4484         bwn_wme_load(mac);
4485
4486         /* enable WME support. */
4487         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4488         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4489             BWN_IFSCTL_USE_EDCF);
4490 }
4491
4492 static void
4493 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4494 {
4495         struct bwn_softc *sc = mac->mac_sc;
4496         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4497         uint16_t delay; /* microsec */
4498
4499         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4500         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4501                 delay = 500;
4502         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4503                 delay = max(delay, (uint16_t)2400);
4504
4505         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4506 }
4507
4508 static void
4509 bwn_bt_enable(struct bwn_mac *mac)
4510 {
4511         struct bwn_softc *sc = mac->mac_sc;
4512         uint64_t hf;
4513
4514         if (bwn_bluetooth == 0)
4515                 return;
4516         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4517                 return;
4518         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4519                 return;
4520
4521         hf = bwn_hf_read(mac);
4522         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4523                 hf |= BWN_HF_BT_COEXISTALT;
4524         else
4525                 hf |= BWN_HF_BT_COEXIST;
4526         bwn_hf_write(mac, hf);
4527 }
4528
4529 static void
4530 bwn_set_macaddr(struct bwn_mac *mac)
4531 {
4532
4533         bwn_mac_write_bssid(mac);
4534         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4535 }
4536
4537 static void
4538 bwn_clear_keys(struct bwn_mac *mac)
4539 {
4540         int i;
4541
4542         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4543                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4544                     ("%s:%d: fail", __func__, __LINE__));
4545
4546                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4547                     NULL, BWN_SEC_KEYSIZE, NULL);
4548                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4549                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4550                             NULL, BWN_SEC_KEYSIZE, NULL);
4551                 }
4552                 mac->mac_key[i].keyconf = NULL;
4553         }
4554 }
4555
4556 static void
4557 bwn_crypt_init(struct bwn_mac *mac)
4558 {
4559         struct bwn_softc *sc = mac->mac_sc;
4560
4561         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4562         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4563             ("%s:%d: fail", __func__, __LINE__));
4564         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4565         mac->mac_ktp *= 2;
4566         if (siba_get_revid(sc->sc_dev) >= 5)
4567                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4568         bwn_clear_keys(mac);
4569 }
4570
4571 static void
4572 bwn_chip_exit(struct bwn_mac *mac)
4573 {
4574         struct bwn_softc *sc = mac->mac_sc;
4575
4576         bwn_phy_exit(mac);
4577         siba_gpio_set(sc->sc_dev, 0);
4578 }
4579
4580 static int
4581 bwn_fw_fillinfo(struct bwn_mac *mac)
4582 {
4583         int error;
4584
4585         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4586         if (error == 0)
4587                 return (0);
4588         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4589         if (error == 0)
4590                 return (0);
4591         return (error);
4592 }
4593
4594 static int
4595 bwn_gpio_init(struct bwn_mac *mac)
4596 {
4597         struct bwn_softc *sc = mac->mac_sc;
4598         uint32_t mask = 0x1f, set = 0xf, value;
4599
4600         BWN_WRITE_4(mac, BWN_MACCTL,
4601             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4602         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4603             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4604
4605         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4606                 mask |= 0x0060;
4607                 set |= 0x0060;
4608         }
4609         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4610                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4611                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4612                 mask |= 0x0200;
4613                 set |= 0x0200;
4614         }
4615         if (siba_get_revid(sc->sc_dev) >= 2)
4616                 mask |= 0x0010;
4617
4618         value = siba_gpio_get(sc->sc_dev);
4619         if (value == -1)
4620                 return (0);
4621         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4622
4623         return (0);
4624 }
4625
4626 static int
4627 bwn_fw_loadinitvals(struct bwn_mac *mac)
4628 {
4629 #define GETFWOFFSET(fwp, offset)                                \
4630         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4631         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4632         const struct bwn_fwhdr *hdr;
4633         struct bwn_fw *fw = &mac->mac_fw;
4634         int error;
4635
4636         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4637         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4638             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4639         if (error)
4640                 return (error);
4641         if (fw->initvals_band.fw) {
4642                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4643                 error = bwn_fwinitvals_write(mac,
4644                     GETFWOFFSET(fw->initvals_band, hdr_len),
4645                     be32toh(hdr->size),
4646                     fw->initvals_band.fw->datasize - hdr_len);
4647         }
4648         return (error);
4649 #undef GETFWOFFSET
4650 }
4651
4652 static int
4653 bwn_phy_init(struct bwn_mac *mac)
4654 {
4655         struct bwn_softc *sc = mac->mac_sc;
4656         int error;
4657
4658         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4659         mac->mac_phy.rf_onoff(mac, 1);
4660         error = mac->mac_phy.init(mac);
4661         if (error) {
4662                 device_printf(sc->sc_dev, "PHY init failed\n");
4663                 goto fail0;
4664         }
4665         error = bwn_switch_channel(mac,
4666             mac->mac_phy.get_default_chan(mac));
4667         if (error) {
4668                 device_printf(sc->sc_dev,
4669                     "failed to switch default channel\n");
4670                 goto fail1;
4671         }
4672         return (0);
4673 fail1:
4674         if (mac->mac_phy.exit)
4675                 mac->mac_phy.exit(mac);
4676 fail0:
4677         mac->mac_phy.rf_onoff(mac, 0);
4678
4679         return (error);
4680 }
4681
4682 static void
4683 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4684 {
4685         uint16_t ant;
4686         uint16_t tmp;
4687
4688         ant = bwn_ant2phy(antenna);
4689
4690         /* For ACK/CTS */
4691         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4692         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4693         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4694         /* For Probe Resposes */
4695         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4696         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4697         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4698 }
4699
4700 static void
4701 bwn_set_opmode(struct bwn_mac *mac)
4702 {
4703         struct bwn_softc *sc = mac->mac_sc;
4704         struct ifnet *ifp = sc->sc_ifp;
4705         struct ieee80211com *ic = ifp->if_l2com;
4706         uint32_t ctl;
4707         uint16_t cfp_pretbtt;
4708
4709         ctl = BWN_READ_4(mac, BWN_MACCTL);
4710         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4711             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4712             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4713         ctl |= BWN_MACCTL_STA;
4714
4715         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4716             ic->ic_opmode == IEEE80211_M_MBSS)
4717                 ctl |= BWN_MACCTL_HOSTAP;
4718         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4719                 ctl &= ~BWN_MACCTL_STA;
4720         ctl |= sc->sc_filters;
4721
4722         if (siba_get_revid(sc->sc_dev) <= 4)
4723                 ctl |= BWN_MACCTL_PROMISC;
4724
4725         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4726
4727         cfp_pretbtt = 2;
4728         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4729                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4730                     siba_get_chiprev(sc->sc_dev) == 3)
4731                         cfp_pretbtt = 100;
4732                 else
4733                         cfp_pretbtt = 50;
4734         }
4735         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4736 }
4737
4738 static int
4739 bwn_dma_gettype(struct bwn_mac *mac)
4740 {
4741         uint32_t tmp;
4742         uint16_t base;
4743
4744         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4745         if (tmp & SIBA_TGSHIGH_DMA64)
4746                 return (BWN_DMA_64BIT);
4747         base = bwn_dma_base(0, 0);
4748         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4749         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4750         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4751                 return (BWN_DMA_32BIT);
4752
4753         return (BWN_DMA_30BIT);
4754 }
4755
4756 static void
4757 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4758 {
4759         if (!error) {
4760                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4761                 *((bus_addr_t *)arg) = seg->ds_addr;
4762         }
4763 }
4764
4765 static void
4766 bwn_phy_g_init_sub(struct bwn_mac *mac)
4767 {
4768         struct bwn_phy *phy = &mac->mac_phy;
4769         struct bwn_phy_g *pg = &phy->phy_g;
4770         struct bwn_softc *sc = mac->mac_sc;
4771         uint16_t i, tmp;
4772
4773         if (phy->rev == 1)
4774                 bwn_phy_init_b5(mac);
4775         else
4776                 bwn_phy_init_b6(mac);
4777
4778         if (phy->rev >= 2 || phy->gmode)
4779                 bwn_phy_init_a(mac);
4780
4781         if (phy->rev >= 2) {
4782                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4783                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4784         }
4785         if (phy->rev == 2) {
4786                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4787                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4788         }
4789         if (phy->rev > 5) {
4790                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4791                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4792         }
4793         if (phy->gmode || phy->rev >= 2) {
4794                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4795                 tmp &= BWN_PHYVER_VERSION;
4796                 if (tmp == 3 || tmp == 5) {
4797                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4798                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4799                 }
4800                 if (tmp == 5) {
4801                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4802                             0x1f00);
4803                 }
4804         }
4805         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4806                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4807         if (phy->rf_rev == 8) {
4808                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4809                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4810         }
4811         if (BWN_HAS_LOOPBACK(phy))
4812                 bwn_loopback_calcgain(mac);
4813
4814         if (phy->rf_rev != 8) {
4815                 if (pg->pg_initval == 0xffff)
4816                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4817                 else
4818                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4819         }
4820         bwn_lo_g_init(mac);
4821         if (BWN_HAS_TXMAG(phy)) {
4822                 BWN_RF_WRITE(mac, 0x52,
4823                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4824                     | pg->pg_loctl.tx_bias |
4825                     pg->pg_loctl.tx_magn);
4826         } else {
4827                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4828         }
4829         if (phy->rev >= 6) {
4830                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4831                     (pg->pg_loctl.tx_bias << 12));
4832         }
4833         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4834                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4835         else
4836                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4837         if (phy->rev < 2)
4838                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4839         else
4840                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4841         if (phy->gmode || phy->rev >= 2) {
4842                 bwn_lo_g_adjust(mac);
4843                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4844         }
4845
4846         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4847                 for (i = 0; i < 64; i++) {
4848                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4849                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4850                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4851                             -32), 31));
4852                 }
4853                 bwn_nrssi_threshold(mac);
4854         } else if (phy->gmode || phy->rev >= 2) {
4855                 if (pg->pg_nrssi[0] == -1000) {
4856                         KASSERT(pg->pg_nrssi[1] == -1000,
4857                             ("%s:%d: fail", __func__, __LINE__));
4858                         bwn_nrssi_slope_11g(mac);
4859                 } else
4860                         bwn_nrssi_threshold(mac);
4861         }
4862         if (phy->rf_rev == 8)
4863                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4864         bwn_phy_hwpctl_init(mac);
4865         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4866              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4867                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4868                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4869         }
4870 }
4871
4872 static uint8_t
4873 bwn_has_hwpctl(struct bwn_mac *mac)
4874 {
4875
4876         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4877                 return (0);
4878         return (mac->mac_phy.use_hwpctl(mac));
4879 }
4880
4881 static void
4882 bwn_phy_init_b5(struct bwn_mac *mac)
4883 {
4884         struct bwn_phy *phy = &mac->mac_phy;
4885         struct bwn_phy_g *pg = &phy->phy_g;
4886         struct bwn_softc *sc = mac->mac_sc;
4887         uint16_t offset, value;
4888         uint8_t old_channel;
4889
4890         if (phy->analog == 1)
4891                 BWN_RF_SET(mac, 0x007a, 0x0050);
4892         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4893             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4894                 value = 0x2120;
4895                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4896                         BWN_PHY_WRITE(mac, offset, value);
4897                         value += 0x202;
4898                 }
4899         }
4900         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4901         if (phy->rf_ver == 0x2050)
4902                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4903
4904         if (phy->gmode || phy->rev >= 2) {
4905                 if (phy->rf_ver == 0x2050) {
4906                         BWN_RF_SET(mac, 0x007a, 0x0020);
4907                         BWN_RF_SET(mac, 0x0051, 0x0004);
4908                 }
4909                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4910
4911                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4912                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4913
4914                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4915
4916                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4917                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4918                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4919         }
4920
4921         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4922                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4923
4924         if (phy->analog == 1) {
4925                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4926                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4927                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4928                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4929                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4930         } else
4931                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4932         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4933         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4934
4935         if (phy->analog == 1)
4936                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4937         else
4938                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4939
4940         if (phy->analog == 0)
4941                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4942
4943         old_channel = phy->chan;
4944         bwn_phy_g_switch_chan(mac, 7, 0);
4945
4946         if (phy->rf_ver != 0x2050) {
4947                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4948                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4949         }
4950
4951         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4952         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4953
4954         if (phy->rf_ver == 0x2050) {
4955                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4956                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4957         }
4958
4959         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4960         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4961         BWN_RF_SET(mac, 0x007a, 0x0007);
4962
4963         bwn_phy_g_switch_chan(mac, old_channel, 0);
4964         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4965         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4966         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4967
4968         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4969             pg->pg_txctl);
4970
4971         if (phy->rf_ver == 0x2050)
4972                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4973
4974         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4975 }
4976
4977 static void
4978 bwn_loopback_calcgain(struct bwn_mac *mac)
4979 {
4980         struct bwn_phy *phy = &mac->mac_phy;
4981         struct bwn_phy_g *pg = &phy->phy_g;
4982         struct bwn_softc *sc = mac->mac_sc;
4983         uint16_t backup_phy[16] = { 0 };
4984         uint16_t backup_radio[3];
4985         uint16_t backup_bband;
4986         uint16_t i, j, loop_i_max;
4987         uint16_t trsw_rx;
4988         uint16_t loop1_outer_done, loop1_inner_done;
4989
4990         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4991         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4992         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4993         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4994         if (phy->rev != 1) {
4995                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4996                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4997         }
4998         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4999         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5000         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5001         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
5002         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
5003         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5004         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5005         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
5006         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5007         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5008         backup_bband = pg->pg_bbatt.att;
5009         backup_radio[0] = BWN_RF_READ(mac, 0x52);
5010         backup_radio[1] = BWN_RF_READ(mac, 0x43);
5011         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
5012
5013         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
5014         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
5015         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
5016         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
5017         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
5018         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
5019         if (phy->rev != 1) {
5020                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
5021                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
5022                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
5023                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
5024         }
5025         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
5026         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
5027         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
5028         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
5029
5030         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
5031         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5032         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5033
5034         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
5035         if (phy->rev != 1) {
5036                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
5037                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
5038         }
5039         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
5040
5041         if (phy->rf_rev == 8)
5042                 BWN_RF_WRITE(mac, 0x43, 0x000f);
5043         else {
5044                 BWN_RF_WRITE(mac, 0x52, 0);
5045                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
5046         }
5047         bwn_phy_g_set_bbatt(mac, 11);
5048
5049         if (phy->rev >= 3)
5050                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5051         else
5052                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5053         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5054
5055         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5056         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5057
5058         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5059         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5060
5061         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5062                 if (phy->rev >= 7) {
5063                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5064                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5065                 }
5066         }
5067         BWN_RF_MASK(mac, 0x7a, 0x00f7);
5068
5069         j = 0;
5070         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5071         for (i = 0; i < loop_i_max; i++) {
5072                 for (j = 0; j < 16; j++) {
5073                         BWN_RF_WRITE(mac, 0x43, i);
5074                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5075                             (j << 8));
5076                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5077                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5078                         DELAY(20);
5079                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5080                                 goto done0;
5081                 }
5082         }
5083 done0:
5084         loop1_outer_done = i;
5085         loop1_inner_done = j;
5086         if (j >= 8) {
5087                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5088                 trsw_rx = 0x1b;
5089                 for (j = j - 8; j < 16; j++) {
5090                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5091                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5092                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5093                         DELAY(20);
5094                         trsw_rx -= 3;
5095                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5096                                 goto done1;
5097                 }
5098         } else
5099                 trsw_rx = 0x18;
5100 done1:
5101
5102         if (phy->rev != 1) {
5103                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5104                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5105         }
5106         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5107         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5108         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5109         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5110         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5111         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5112         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5113         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5114         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5115
5116         bwn_phy_g_set_bbatt(mac, backup_bband);
5117
5118         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5119         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5120         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5121
5122         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5123         DELAY(10);
5124         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5125         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5126         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5127         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5128
5129         pg->pg_max_lb_gain =
5130             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5131         pg->pg_trsw_rx_gain = trsw_rx * 2;
5132 }
5133
5134 static uint16_t
5135 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5136 {
5137         struct bwn_phy *phy = &mac->mac_phy;
5138         uint32_t tmp1 = 0, tmp2 = 0;
5139         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5140             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5141             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5142         static const uint8_t rcc_table[] = {
5143                 0x02, 0x03, 0x01, 0x0f,
5144                 0x06, 0x07, 0x05, 0x0f,
5145                 0x0a, 0x0b, 0x09, 0x0f,
5146                 0x0e, 0x0f, 0x0d, 0x0f,
5147         };
5148
5149         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5150             rfoverval = rfover = cck3 = 0;
5151         radio0 = BWN_RF_READ(mac, 0x43);
5152         radio1 = BWN_RF_READ(mac, 0x51);
5153         radio2 = BWN_RF_READ(mac, 0x52);
5154         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5155         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5156         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5157         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5158
5159         if (phy->type == BWN_PHYTYPE_B) {
5160                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5161                 reg0 = BWN_READ_2(mac, 0x3ec);
5162
5163                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5164                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5165         } else if (phy->gmode || phy->rev >= 2) {
5166                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5167                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5168                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5169                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5170                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5171                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5172
5173                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5174                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5175                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5176                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5177                 if (BWN_HAS_LOOPBACK(phy)) {
5178                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5179                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5180                         if (phy->rev >= 3)
5181                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5182                         else
5183                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5184                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5185                 }
5186
5187                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5188                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5189                         BWN_LPD(0, 1, 1)));
5190                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5191                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5192         }
5193         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5194
5195         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5196         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5197         reg1 = BWN_READ_2(mac, 0x3e6);
5198         reg2 = BWN_READ_2(mac, 0x3f4);
5199
5200         if (phy->analog == 0)
5201                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5202         else {
5203                 if (phy->analog >= 2)
5204                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5205                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5206                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5207         }
5208
5209         reg = BWN_RF_READ(mac, 0x60);
5210         index = (reg & 0x001e) >> 1;
5211         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5212
5213         if (phy->type == BWN_PHYTYPE_B)
5214                 BWN_RF_WRITE(mac, 0x78, 0x26);
5215         if (phy->gmode || phy->rev >= 2) {
5216                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5217                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5218                         BWN_LPD(0, 1, 1)));
5219         }
5220         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5221         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5222         if (phy->gmode || phy->rev >= 2) {
5223                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5224                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5225                         BWN_LPD(0, 0, 1)));
5226         }
5227         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5228         BWN_RF_SET(mac, 0x51, 0x0004);
5229         if (phy->rf_rev == 8)
5230                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5231         else {
5232                 BWN_RF_WRITE(mac, 0x52, 0);
5233                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5234         }
5235         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5236
5237         for (i = 0; i < 16; i++) {
5238                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5239                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5240                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5241                 if (phy->gmode || phy->rev >= 2) {
5242                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5243                             bwn_rf_2050_rfoverval(mac,
5244                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5245                 }
5246                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5247                 DELAY(10);
5248                 if (phy->gmode || phy->rev >= 2) {
5249                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5250                             bwn_rf_2050_rfoverval(mac,
5251                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5252                 }
5253                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5254                 DELAY(10);
5255                 if (phy->gmode || phy->rev >= 2) {
5256                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5257                             bwn_rf_2050_rfoverval(mac,
5258                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5259                 }
5260                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5261                 DELAY(20);
5262                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5263                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5264                 if (phy->gmode || phy->rev >= 2) {
5265                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5266                             bwn_rf_2050_rfoverval(mac,
5267                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5268                 }
5269                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5270         }
5271         DELAY(10);
5272
5273         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5274         tmp1++;
5275         tmp1 >>= 9;
5276
5277         for (i = 0; i < 16; i++) {
5278                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5279                 BWN_RF_WRITE(mac, 0x78, radio78);
5280                 DELAY(10);
5281                 for (j = 0; j < 16; j++) {
5282                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5283                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5284                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5285                         if (phy->gmode || phy->rev >= 2) {
5286                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5287                                     bwn_rf_2050_rfoverval(mac,
5288                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5289                         }
5290                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5291                         DELAY(10);
5292                         if (phy->gmode || phy->rev >= 2) {
5293                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5294                                     bwn_rf_2050_rfoverval(mac,
5295                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5296                         }
5297                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5298                         DELAY(10);
5299                         if (phy->gmode || phy->rev >= 2) {
5300                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5301                                     bwn_rf_2050_rfoverval(mac,
5302                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5303                         }
5304                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5305                         DELAY(10);
5306                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5307                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5308                         if (phy->gmode || phy->rev >= 2) {
5309                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5310                                     bwn_rf_2050_rfoverval(mac,
5311                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5312                         }
5313                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5314                 }
5315                 tmp2++;
5316                 tmp2 >>= 8;
5317                 if (tmp1 < tmp2)
5318                         break;
5319         }
5320
5321         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5322         BWN_RF_WRITE(mac, 0x51, radio1);
5323         BWN_RF_WRITE(mac, 0x52, radio2);
5324         BWN_RF_WRITE(mac, 0x43, radio0);
5325         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5326         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5327         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5328         BWN_WRITE_2(mac, 0x3e6, reg1);
5329         if (phy->analog != 0)
5330                 BWN_WRITE_2(mac, 0x3f4, reg2);
5331         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5332         bwn_spu_workaround(mac, phy->chan);
5333         if (phy->type == BWN_PHYTYPE_B) {
5334                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5335                 BWN_WRITE_2(mac, 0x3ec, reg0);
5336         } else if (phy->gmode) {
5337                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5338                             BWN_READ_2(mac, BWN_PHY_RADIO)
5339                             & 0x7fff);
5340                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5341                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5342                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5343                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5344                               analogoverval);
5345                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5346                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5347                 if (BWN_HAS_LOOPBACK(phy)) {
5348                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5349                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5350                 }
5351         }
5352
5353         return ((i > 15) ? radio78 : rcc);
5354 }
5355
5356 static void
5357 bwn_phy_init_b6(struct bwn_mac *mac)
5358 {
5359         struct bwn_phy *phy = &mac->mac_phy;
5360         struct bwn_phy_g *pg = &phy->phy_g;
5361         struct bwn_softc *sc = mac->mac_sc;
5362         uint16_t offset, val;
5363         uint8_t old_channel;
5364
5365         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5366             ("%s:%d: fail", __func__, __LINE__));
5367
5368         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5369         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5370         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5371                 BWN_RF_WRITE(mac, 0x51, 0x37);
5372                 BWN_RF_WRITE(mac, 0x52, 0x70);
5373                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5374                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5375                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5376                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5377                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5378                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5379                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5380                 bwn_hf_write(mac,
5381                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5382         }
5383         if (phy->rf_rev == 8) {
5384                 BWN_RF_WRITE(mac, 0x51, 0);
5385                 BWN_RF_WRITE(mac, 0x52, 0x40);
5386                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5387                 BWN_RF_WRITE(mac, 0x54, 0x98);
5388                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5389                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5390                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5391                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5392                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5393                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5394                 } else {
5395                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5396                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5397                 }
5398                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5399                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5400                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5401                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5402         }
5403         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5404                 BWN_PHY_WRITE(mac, offset, val);
5405                 val -= 0x0202;
5406         }
5407         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5408                 BWN_PHY_WRITE(mac, offset, val);
5409                 val -= 0x0202;
5410         }
5411         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5412                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5413                 val += 0x0202;
5414         }
5415         if (phy->type == BWN_PHYTYPE_G) {
5416                 BWN_RF_SET(mac, 0x007a, 0x0020);
5417                 BWN_RF_SET(mac, 0x0051, 0x0004);
5418                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5419                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5420                 BWN_PHY_WRITE(mac, 0x5b, 0);
5421                 BWN_PHY_WRITE(mac, 0x5c, 0);
5422         }
5423
5424         old_channel = phy->chan;
5425         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5426
5427         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5428         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5429         DELAY(40);
5430         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5431                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5432                 BWN_RF_WRITE(mac, 0x50, 0x20);
5433         }
5434         if (phy->rf_rev <= 2) {
5435                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5436                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5437                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5438                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5439         }
5440         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5441
5442         bwn_phy_g_switch_chan(mac, old_channel, 0);
5443
5444         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5445         if (phy->rf_rev >= 6)
5446                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5447         else
5448                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5449         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5450         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5451             pg->pg_txctl);
5452         if (phy->rf_rev <= 5)
5453                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5454         if (phy->rf_rev <= 2)
5455                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5456
5457         if (phy->analog == 4) {
5458                 BWN_WRITE_2(mac, 0x3e4, 9);
5459                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5460         } else
5461                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5462         if (phy->type == BWN_PHYTYPE_B)
5463                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5464         else if (phy->type == BWN_PHYTYPE_G)
5465                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5466 }
5467
5468 static void
5469 bwn_phy_init_a(struct bwn_mac *mac)
5470 {
5471         struct bwn_phy *phy = &mac->mac_phy;
5472         struct bwn_softc *sc = mac->mac_sc;
5473
5474         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5475             ("%s:%d: fail", __func__, __LINE__));
5476
5477         if (phy->rev >= 6) {
5478                 if (phy->type == BWN_PHYTYPE_A)
5479                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5480                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5481                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5482                 else
5483                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5484         }
5485
5486         bwn_wa_init(mac);
5487
5488         if (phy->type == BWN_PHYTYPE_G &&
5489             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5490                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5491 }
5492
5493 static void
5494 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5495 {
5496         int i;
5497
5498         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5499                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5500 }
5501
5502 static void
5503 bwn_wa_agc(struct bwn_mac *mac)
5504 {
5505         struct bwn_phy *phy = &mac->mac_phy;
5506
5507         if (phy->rev == 1) {
5508                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5509                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5510                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5511                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5512                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5513                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5514                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5515                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5516                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5517         } else {
5518                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5519                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5520                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5521                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5522         }
5523
5524         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5525             0x5700);
5526         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5527         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5528         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5529         BWN_RF_SET(mac, 0x7a, 0x0008);
5530         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5531         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5532         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5533         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5534         if (phy->rev == 1)
5535                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5536         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5537         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5538         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5539         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5540         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5541         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5542         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5543         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5544         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5545         if (phy->rev == 1) {
5546                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5547                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5548         } else {
5549                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5550                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5551                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5552                 if (phy->rev >= 6) {
5553                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5554                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5555                             (uint16_t)~0xf000, 0x3000);
5556                 }
5557         }
5558         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5559         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5560         if (phy->rev == 1) {
5561                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5562                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5563                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5564                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5565                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5566                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5567                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5568                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5569         } else {
5570                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5571                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5572                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5573                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5574         }
5575         if (phy->rev >= 6) {
5576                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5577                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5578         }
5579         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5580 }
5581
5582 static void
5583 bwn_wa_grev1(struct bwn_mac *mac)
5584 {
5585         struct bwn_phy *phy = &mac->mac_phy;
5586         int i;
5587         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5588         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5589         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5590
5591         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5592
5593         /* init CRSTHRES and ANTDWELL */
5594         if (phy->rev == 1) {
5595                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5596         } else if (phy->rev == 2) {
5597                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5598                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5599                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5600         } else {
5601                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5602                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5603                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5604                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5605         }
5606         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5607         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5608         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5609
5610         /* XXX support PHY-A??? */
5611         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5612                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5613                     bwn_tab_finefreqg[i]);
5614
5615         /* XXX support PHY-A??? */
5616         if (phy->rev == 1)
5617                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5618                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5619                             bwn_tab_noise_g1[i]);
5620         else
5621                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5622                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5623                             bwn_tab_noise_g2[i]);
5624
5625
5626         for (i = 0; i < N(bwn_tab_rotor); i++)
5627                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5628                     bwn_tab_rotor[i]);
5629
5630         /* XXX support PHY-A??? */
5631         if (phy->rev >= 6) {
5632                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5633                     BWN_PHY_ENCORE_EN)
5634                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5635                 else
5636                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5637         } else
5638                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5639
5640         for (i = 0; i < N(bwn_tab_retard); i++)
5641                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5642                     bwn_tab_retard[i]);
5643
5644         if (phy->rev == 1) {
5645                 for (i = 0; i < 16; i++)
5646                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5647                             i, 0x0020);
5648         } else {
5649                 for (i = 0; i < 32; i++)
5650                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5651         }
5652
5653         bwn_wa_agc(mac);
5654 }
5655
5656 static void
5657 bwn_wa_grev26789(struct bwn_mac *mac)
5658 {
5659         struct bwn_phy *phy = &mac->mac_phy;
5660         int i;
5661         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5662         uint16_t ofdmrev;
5663
5664         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5665
5666         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5667
5668         /* init CRSTHRES and ANTDWELL */
5669         if (phy->rev == 1)
5670                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5671         else if (phy->rev == 2) {
5672                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5673                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5674                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5675         } else {
5676                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5677                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5678                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5679                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5680         }
5681
5682         for (i = 0; i < 64; i++)
5683                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5684
5685         /* XXX support PHY-A??? */
5686         if (phy->rev == 1)
5687                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5688                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5689                             bwn_tab_noise_g1[i]);
5690         else
5691                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5692                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5693                             bwn_tab_noise_g2[i]);
5694
5695         /* XXX support PHY-A??? */
5696         if (phy->rev >= 6) {
5697                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5698                     BWN_PHY_ENCORE_EN)
5699                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5700                 else
5701                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5702         } else
5703                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5704
5705         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5706                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5707                     bwn_tab_sigmasqr2[i]);
5708
5709         if (phy->rev == 1) {
5710                 for (i = 0; i < 16; i++)
5711                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5712                             0x0020);
5713         } else {
5714                 for (i = 0; i < 32; i++)
5715                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5716         }
5717
5718         bwn_wa_agc(mac);
5719
5720         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5721         if (ofdmrev > 2) {
5722                 if (phy->type == BWN_PHYTYPE_A)
5723                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5724                 else
5725                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5726         } else {
5727                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5728                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5729                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5730         }
5731
5732         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5733         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5734 }
5735
5736 static void
5737 bwn_wa_init(struct bwn_mac *mac)
5738 {
5739         struct bwn_phy *phy = &mac->mac_phy;
5740         struct bwn_softc *sc = mac->mac_sc;
5741
5742         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5743
5744         switch (phy->rev) {
5745         case 1:
5746                 bwn_wa_grev1(mac);
5747                 break;
5748         case 2:
5749         case 6:
5750         case 7:
5751         case 8:
5752         case 9:
5753                 bwn_wa_grev26789(mac);
5754                 break;
5755         default:
5756                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5757         }
5758
5759         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5760             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5761             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5762                 if (phy->rev < 2) {
5763                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5764                             0x0002);
5765                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5766                             0x0001);
5767                 } else {
5768                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5769                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5770                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5771                              BWN_BFL_EXTLNA) &&
5772                             (phy->rev >= 7)) {
5773                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5774                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5775                                     0x0020, 0x0001);
5776                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5777                                     0x0021, 0x0001);
5778                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5779                                     0x0022, 0x0001);
5780                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5781                                     0x0023, 0x0000);
5782                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5783                                     0x0000, 0x0000);
5784                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5785                                     0x0003, 0x0002);
5786                         }
5787                 }
5788         }
5789         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5790                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5791                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5792         }
5793
5794         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5795         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5796 }
5797
5798 static void
5799 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5800     uint16_t value)
5801 {
5802         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5803         uint16_t addr;
5804
5805         addr = table + offset;
5806         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5807             (addr - 1 != pg->pg_ofdmtab_addr)) {
5808                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5809                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5810         }
5811         pg->pg_ofdmtab_addr = addr;
5812         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5813 }
5814
5815 static void
5816 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5817     uint32_t value)
5818 {
5819         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5820         uint16_t addr;
5821
5822         addr = table + offset;
5823         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5824             (addr - 1 != pg->pg_ofdmtab_addr)) {
5825                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5826                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5827         }
5828         pg->pg_ofdmtab_addr = addr;
5829
5830         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5831         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5832 }
5833
5834 static void
5835 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5836     uint16_t value)
5837 {
5838
5839         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5840         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5841 }
5842
5843 static void
5844 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5845 {
5846         struct bwn_phy *phy = &mac->mac_phy;
5847         struct bwn_softc *sc = mac->mac_sc;
5848         unsigned int i, max_loop;
5849         uint16_t value;
5850         uint32_t buffer[5] = {
5851                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5852         };
5853
5854         if (ofdm) {
5855                 max_loop = 0x1e;
5856                 buffer[0] = 0x000201cc;
5857         } else {
5858                 max_loop = 0xfa;
5859                 buffer[0] = 0x000b846e;
5860         }
5861
5862         BWN_ASSERT_LOCKED(mac->mac_sc);
5863
5864         for (i = 0; i < 5; i++)
5865                 bwn_ram_write(mac, i * 4, buffer[i]);
5866
5867         BWN_WRITE_2(mac, 0x0568, 0x0000);
5868         BWN_WRITE_2(mac, 0x07c0,
5869             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5870         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5871         BWN_WRITE_2(mac, 0x050c, value);
5872         if (phy->type == BWN_PHYTYPE_LP)
5873                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5874         BWN_WRITE_2(mac, 0x0508, 0x0000);
5875         BWN_WRITE_2(mac, 0x050a, 0x0000);
5876         BWN_WRITE_2(mac, 0x054c, 0x0000);
5877         BWN_WRITE_2(mac, 0x056a, 0x0014);
5878         BWN_WRITE_2(mac, 0x0568, 0x0826);
5879         BWN_WRITE_2(mac, 0x0500, 0x0000);
5880         if (phy->type == BWN_PHYTYPE_LP)
5881                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5882         else
5883                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5884
5885         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5886                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5887         for (i = 0x00; i < max_loop; i++) {
5888                 value = BWN_READ_2(mac, 0x050e);
5889                 if (value & 0x0080)
5890                         break;
5891                 DELAY(10);
5892         }
5893         for (i = 0x00; i < 0x0a; i++) {
5894                 value = BWN_READ_2(mac, 0x050e);
5895                 if (value & 0x0400)
5896                         break;
5897                 DELAY(10);
5898         }
5899         for (i = 0x00; i < 0x19; i++) {
5900                 value = BWN_READ_2(mac, 0x0690);
5901                 if (!(value & 0x0100))
5902                         break;
5903                 DELAY(10);
5904         }
5905         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5906                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5907 }
5908
5909 static void
5910 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5911 {
5912         uint32_t macctl;
5913
5914         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5915
5916         macctl = BWN_READ_4(mac, BWN_MACCTL);
5917         if (macctl & BWN_MACCTL_BIGENDIAN)
5918                 printf("TODO: need swap\n");
5919
5920         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5921         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5922         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5923 }
5924
5925 static void
5926 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5927 {
5928         uint16_t value;
5929
5930         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5931             ("%s:%d: fail", __func__, __LINE__));
5932
5933         value = (uint8_t) (ctl->q);
5934         value |= ((uint8_t) (ctl->i)) << 8;
5935         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5936 }
5937
5938 static uint16_t
5939 bwn_lo_calcfeed(struct bwn_mac *mac,
5940     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5941 {
5942         struct bwn_phy *phy = &mac->mac_phy;
5943         struct bwn_softc *sc = mac->mac_sc;
5944         uint16_t rfover;
5945         uint16_t feedthrough;
5946
5947         if (phy->gmode) {
5948                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5949                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5950
5951                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5952                     ("%s:%d: fail", __func__, __LINE__));
5953                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5954                     ("%s:%d: fail", __func__, __LINE__));
5955
5956                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5957
5958                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5959                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5960                     phy->rev > 6)
5961                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5962
5963                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5964                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5965                 DELAY(10);
5966                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5967                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5968                 DELAY(10);
5969                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5970                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5971                 DELAY(10);
5972                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5973         } else {
5974                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5975                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5976                 DELAY(10);
5977                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5978                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5979                 DELAY(10);
5980                 pga |= BWN_PHY_PGACTL_LPF;
5981                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5982         }
5983         DELAY(21);
5984         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5985
5986         return (feedthrough);
5987 }
5988
5989 static uint16_t
5990 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5991     uint16_t *value, uint16_t *pad_mix_gain)
5992 {
5993         struct bwn_phy *phy = &mac->mac_phy;
5994         uint16_t reg, v, padmix;
5995
5996         if (phy->type == BWN_PHYTYPE_B) {
5997                 v = 0x30;
5998                 if (phy->rf_rev <= 5) {
5999                         reg = 0x43;
6000                         padmix = 0;
6001                 } else {
6002                         reg = 0x52;
6003                         padmix = 5;
6004                 }
6005         } else {
6006                 if (phy->rev >= 2 && phy->rf_rev == 8) {
6007                         reg = 0x43;
6008                         v = 0x10;
6009                         padmix = 2;
6010                 } else {
6011                         reg = 0x52;
6012                         v = 0x30;
6013                         padmix = 5;
6014                 }
6015         }
6016         if (value)
6017                 *value = v;
6018         if (pad_mix_gain)
6019                 *pad_mix_gain = padmix;
6020
6021         return (reg);
6022 }
6023
6024 static void
6025 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
6026 {
6027         struct bwn_phy *phy = &mac->mac_phy;
6028         struct bwn_phy_g *pg = &phy->phy_g;
6029         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6030         uint16_t reg, mask;
6031         uint16_t trsw_rx, pga;
6032         uint16_t rf_pctl_reg;
6033
6034         static const uint8_t tx_bias_values[] = {
6035                 0x09, 0x08, 0x0a, 0x01, 0x00,
6036                 0x02, 0x05, 0x04, 0x06,
6037         };
6038         static const uint8_t tx_magn_values[] = {
6039                 0x70, 0x40,
6040         };
6041
6042         if (!BWN_HAS_LOOPBACK(phy)) {
6043                 rf_pctl_reg = 6;
6044                 trsw_rx = 2;
6045                 pga = 0;
6046         } else {
6047                 int lb_gain;
6048
6049                 trsw_rx = 0;
6050                 lb_gain = pg->pg_max_lb_gain / 2;
6051                 if (lb_gain > 10) {
6052                         rf_pctl_reg = 0;
6053                         pga = abs(10 - lb_gain) / 6;
6054                         pga = MIN(MAX(pga, 0), 15);
6055                 } else {
6056                         int cmp_val;
6057                         int tmp;
6058
6059                         pga = 0;
6060                         cmp_val = 0x24;
6061                         if ((phy->rev >= 2) &&
6062                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6063                                 cmp_val = 0x3c;
6064                         tmp = lb_gain;
6065                         if ((10 - lb_gain) < cmp_val)
6066                                 tmp = (10 - lb_gain);
6067                         if (tmp < 0)
6068                                 tmp += 6;
6069                         else
6070                                 tmp += 3;
6071                         cmp_val /= 4;
6072                         tmp /= 4;
6073                         if (tmp >= cmp_val)
6074                                 rf_pctl_reg = cmp_val;
6075                         else
6076                                 rf_pctl_reg = tmp;
6077                 }
6078         }
6079         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6080         bwn_phy_g_set_bbatt(mac, 2);
6081
6082         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6083         mask = ~mask;
6084         BWN_RF_MASK(mac, reg, mask);
6085
6086         if (BWN_HAS_TXMAG(phy)) {
6087                 int i, j;
6088                 int feedthrough;
6089                 int min_feedth = 0xffff;
6090                 uint8_t tx_magn, tx_bias;
6091
6092                 for (i = 0; i < N(tx_magn_values); i++) {
6093                         tx_magn = tx_magn_values[i];
6094                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6095                         for (j = 0; j < N(tx_bias_values); j++) {
6096                                 tx_bias = tx_bias_values[j];
6097                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6098                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6099                                     trsw_rx);
6100                                 if (feedthrough < min_feedth) {
6101                                         lo->tx_bias = tx_bias;
6102                                         lo->tx_magn = tx_magn;
6103                                         min_feedth = feedthrough;
6104                                 }
6105                                 if (lo->tx_bias == 0)
6106                                         break;
6107                         }
6108                         BWN_RF_WRITE(mac, 0x52,
6109                                           (BWN_RF_READ(mac, 0x52)
6110                                            & 0xff00) | lo->tx_bias | lo->
6111                                           tx_magn);
6112                 }
6113         } else {
6114                 lo->tx_magn = 0;
6115                 lo->tx_bias = 0;
6116                 BWN_RF_MASK(mac, 0x52, 0xfff0);
6117         }
6118
6119         BWN_GETTIME(lo->txctl_measured_time);
6120 }
6121
6122 static void
6123 bwn_lo_get_powervector(struct bwn_mac *mac)
6124 {
6125         struct bwn_phy *phy = &mac->mac_phy;
6126         struct bwn_phy_g *pg = &phy->phy_g;
6127         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6128         int i;
6129         uint64_t tmp;
6130         uint64_t power_vector = 0;
6131
6132         for (i = 0; i < 8; i += 2) {
6133                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6134                 power_vector |= (tmp << (i * 8));
6135                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6136         }
6137         if (power_vector)
6138                 lo->power_vector = power_vector;
6139
6140         BWN_GETTIME(lo->pwr_vec_read_time);
6141 }
6142
6143 static void
6144 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6145     int use_trsw_rx)
6146 {
6147         struct bwn_phy *phy = &mac->mac_phy;
6148         struct bwn_phy_g *pg = &phy->phy_g;
6149         uint16_t tmp;
6150
6151         if (max_rx_gain < 0)
6152                 max_rx_gain = 0;
6153
6154         if (BWN_HAS_LOOPBACK(phy)) {
6155                 int trsw_rx = 0;
6156                 int trsw_rx_gain;
6157
6158                 if (use_trsw_rx) {
6159                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6160                         if (max_rx_gain >= trsw_rx_gain) {
6161                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6162                                 trsw_rx = 0x20;
6163                         }
6164                 } else
6165                         trsw_rx_gain = max_rx_gain;
6166                 if (trsw_rx_gain < 9) {
6167                         pg->pg_lna_lod_gain = 0;
6168                 } else {
6169                         pg->pg_lna_lod_gain = 1;
6170                         trsw_rx_gain -= 8;
6171                 }
6172                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6173                 pg->pg_pga_gain = trsw_rx_gain / 3;
6174                 if (pg->pg_pga_gain >= 5) {
6175                         pg->pg_pga_gain -= 5;
6176                         pg->pg_lna_gain = 2;
6177                 } else
6178                         pg->pg_lna_gain = 0;
6179         } else {
6180                 pg->pg_lna_gain = 0;
6181                 pg->pg_trsw_rx_gain = 0x20;
6182                 if (max_rx_gain >= 0x14) {
6183                         pg->pg_lna_lod_gain = 1;
6184                         pg->pg_pga_gain = 2;
6185                 } else if (max_rx_gain >= 0x12) {
6186                         pg->pg_lna_lod_gain = 1;
6187                         pg->pg_pga_gain = 1;
6188                 } else if (max_rx_gain >= 0xf) {
6189                         pg->pg_lna_lod_gain = 1;
6190                         pg->pg_pga_gain = 0;
6191                 } else {
6192                         pg->pg_lna_lod_gain = 0;
6193                         pg->pg_pga_gain = 0;
6194                 }
6195         }
6196
6197         tmp = BWN_RF_READ(mac, 0x7a);
6198         if (pg->pg_lna_lod_gain == 0)
6199                 tmp &= ~0x0008;
6200         else
6201                 tmp |= 0x0008;
6202         BWN_RF_WRITE(mac, 0x7a, tmp);
6203 }
6204
6205 static void
6206 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6207 {
6208         struct bwn_phy *phy = &mac->mac_phy;
6209         struct bwn_phy_g *pg = &phy->phy_g;
6210         struct bwn_softc *sc = mac->mac_sc;
6211         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6212         struct timespec ts;
6213         uint16_t tmp;
6214
6215         if (bwn_has_hwpctl(mac)) {
6216                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6217                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6218                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6219                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6220                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6221
6222                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6223                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6224                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6225                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6226         }
6227         if (phy->type == BWN_PHYTYPE_B &&
6228             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6229                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6230                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6231         }
6232         if (phy->rev >= 2) {
6233                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6234                 sav->phy_analogoverval =
6235                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6236                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6237                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6238                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6239                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6240                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6241
6242                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6243                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6244                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6245                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6246                 if (phy->type == BWN_PHYTYPE_G) {
6247                         if ((phy->rev >= 7) &&
6248                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6249                              BWN_BFL_EXTLNA)) {
6250                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6251                         } else {
6252                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6253                         }
6254                 } else {
6255                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6256                 }
6257                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6258         }
6259         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6260         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6261         sav->rf0 = BWN_RF_READ(mac, 0x43);
6262         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6263         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6264         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6265         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6266         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6267
6268         if (!BWN_HAS_TXMAG(phy)) {
6269                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6270                 sav->rf2 &= 0x00f0;
6271         }
6272         if (phy->type == BWN_PHYTYPE_B) {
6273                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6274                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6275                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6276                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6277         } else {
6278                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6279                             | 0x8000);
6280         }
6281         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6282                     & 0xf000);
6283
6284         tmp =
6285             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6286         BWN_PHY_WRITE(mac, tmp, 0x007f);
6287
6288         tmp = sav->phy_syncctl;
6289         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6290         tmp = sav->rf1;
6291         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6292
6293         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6294         if (phy->type == BWN_PHYTYPE_G ||
6295             (phy->type == BWN_PHYTYPE_B &&
6296              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6297                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6298         } else
6299                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6300         if (phy->rev >= 2)
6301                 bwn_dummy_transmission(mac, 0, 1);
6302         bwn_phy_g_switch_chan(mac, 6, 0);
6303         BWN_RF_READ(mac, 0x51);
6304         if (phy->type == BWN_PHYTYPE_G)
6305                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6306
6307         nanouptime(&ts);
6308         if (time_before(lo->txctl_measured_time,
6309             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6310                 bwn_lo_measure_txctl_values(mac);
6311
6312         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6313                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6314         else {
6315                 if (phy->type == BWN_PHYTYPE_B)
6316                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6317                 else
6318                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6319         }
6320 }
6321
6322 static void
6323 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6324 {
6325         struct bwn_phy *phy = &mac->mac_phy;
6326         struct bwn_phy_g *pg = &phy->phy_g;
6327         uint16_t tmp;
6328
6329         if (phy->rev >= 2) {
6330                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6331                 tmp = (pg->pg_pga_gain << 8);
6332                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6333                 DELAY(5);
6334                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6335                 DELAY(2);
6336                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6337         } else {
6338                 tmp = (pg->pg_pga_gain | 0xefa0);
6339                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6340         }
6341         if (phy->type == BWN_PHYTYPE_G) {
6342                 if (phy->rev >= 3)
6343                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6344                 else
6345                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6346                 if (phy->rev >= 2)
6347                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6348                 else
6349                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6350         }
6351         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6352         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6353         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6354         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6355         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6356         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6357         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6358         if (!BWN_HAS_TXMAG(phy)) {
6359                 tmp = sav->rf2;
6360                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6361         }
6362         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6363         if (phy->type == BWN_PHYTYPE_B &&
6364             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6365                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6366                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6367         }
6368         if (phy->rev >= 2) {
6369                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6370                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6371                               sav->phy_analogoverval);
6372                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6373                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6374                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6375                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6376                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6377         }
6378         if (bwn_has_hwpctl(mac)) {
6379                 tmp = (sav->phy_lomask & 0xbfff);
6380                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6381                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6382                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6383                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6384                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6385         }
6386         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6387 }
6388
6389 static int
6390 bwn_lo_probe_loctl(struct bwn_mac *mac,
6391     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6392 {
6393         struct bwn_phy *phy = &mac->mac_phy;
6394         struct bwn_phy_g *pg = &phy->phy_g;
6395         struct bwn_loctl orig, test;
6396         struct bwn_loctl prev = { -100, -100 };
6397         static const struct bwn_loctl modifiers[] = {
6398                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6399                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6400         };
6401         int begin, end, lower = 0, i;
6402         uint16_t feedth;
6403
6404         if (d->curstate == 0) {
6405                 begin = 1;
6406                 end = 8;
6407         } else if (d->curstate % 2 == 0) {
6408                 begin = d->curstate - 1;
6409                 end = d->curstate + 1;
6410         } else {
6411                 begin = d->curstate - 2;
6412                 end = d->curstate + 2;
6413         }
6414         if (begin < 1)
6415                 begin += 8;
6416         if (end > 8)
6417                 end -= 8;
6418
6419         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6420         i = begin;
6421         d->curstate = i;
6422         while (1) {
6423                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6424                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6425                 test.i += modifiers[i - 1].i * d->multipler;
6426                 test.q += modifiers[i - 1].q * d->multipler;
6427                 if ((test.i != prev.i || test.q != prev.q) &&
6428                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6429                         bwn_lo_write(mac, &test);
6430                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6431                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6432                         if (feedth < d->feedth) {
6433                                 memcpy(probe, &test,
6434                                     sizeof(struct bwn_loctl));
6435                                 lower = 1;
6436                                 d->feedth = feedth;
6437                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6438                                         break;
6439                         }
6440                 }
6441                 memcpy(&prev, &test, sizeof(prev));
6442                 if (i == end)
6443                         break;
6444                 if (i == 8)
6445                         i = 1;
6446                 else
6447                         i++;
6448                 d->curstate = i;
6449         }
6450
6451         return (lower);
6452 }
6453
6454 static void
6455 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6456 {
6457         struct bwn_phy *phy = &mac->mac_phy;
6458         struct bwn_phy_g *pg = &phy->phy_g;
6459         struct bwn_lo_g_sm d;
6460         struct bwn_loctl probe;
6461         int lower, repeat, cnt = 0;
6462         uint16_t feedth;
6463
6464         d.nmeasure = 0;
6465         d.multipler = 1;
6466         if (BWN_HAS_LOOPBACK(phy))
6467                 d.multipler = 3;
6468
6469         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6470         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6471
6472         do {
6473                 bwn_lo_write(mac, &d.loctl);
6474                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6475                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6476                 if (feedth < 0x258) {
6477                         if (feedth >= 0x12c)
6478                                 *rxgain += 6;
6479                         else
6480                                 *rxgain += 3;
6481                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6482                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6483                 }
6484                 d.feedth = feedth;
6485                 d.curstate = 0;
6486                 do {
6487                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6488                             ("%s:%d: fail", __func__, __LINE__));
6489                         memcpy(&probe, &d.loctl,
6490                                sizeof(struct bwn_loctl));
6491                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6492                         if (!lower)
6493                                 break;
6494                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6495                                 break;
6496                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6497                         d.nmeasure++;
6498                 } while (d.nmeasure < 24);
6499                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6500
6501                 if (BWN_HAS_LOOPBACK(phy)) {
6502                         if (d.feedth > 0x1194)
6503                                 *rxgain -= 6;
6504                         else if (d.feedth < 0x5dc)
6505                                 *rxgain += 3;
6506                         if (cnt == 0) {
6507                                 if (d.feedth <= 0x5dc) {
6508                                         d.multipler = 1;
6509                                         cnt++;
6510                                 } else
6511                                         d.multipler = 2;
6512                         } else if (cnt == 2)
6513                                 d.multipler = 1;
6514                 }
6515                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6516         } while (++cnt < repeat);
6517 }
6518
6519 static struct bwn_lo_calib *
6520 bwn_lo_calibset(struct bwn_mac *mac,
6521     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6522 {
6523         struct bwn_phy *phy = &mac->mac_phy;
6524         struct bwn_phy_g *pg = &phy->phy_g;
6525         struct bwn_loctl loctl = { 0, 0 };
6526         struct bwn_lo_calib *cal;
6527         struct bwn_lo_g_value sval = { 0 };
6528         int rxgain;
6529         uint16_t pad, reg, value;
6530
6531         sval.old_channel = phy->chan;
6532         bwn_mac_suspend(mac);
6533         bwn_lo_save(mac, &sval);
6534
6535         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6536         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6537         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6538
6539         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6540         if (rfatt->padmix)
6541                 rxgain -= pad;
6542         if (BWN_HAS_LOOPBACK(phy))
6543                 rxgain += pg->pg_max_lb_gain;
6544         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6545         bwn_phy_g_set_bbatt(mac, bbatt->att);
6546         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6547
6548         bwn_lo_restore(mac, &sval);
6549         bwn_mac_enable(mac);
6550
6551         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6552         if (!cal) {
6553                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6554                 return (NULL);
6555         }
6556         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6557         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6558         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6559
6560         BWN_GETTIME(cal->calib_time);
6561
6562         return (cal);
6563 }
6564
6565 static struct bwn_lo_calib *
6566 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6567     const struct bwn_rfatt *rfatt)
6568 {
6569         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6570         struct bwn_lo_calib *c;
6571
6572         TAILQ_FOREACH(c, &lo->calib_list, list) {
6573                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6574                         continue;
6575                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6576                         continue;
6577                 return (c);
6578         }
6579
6580         c = bwn_lo_calibset(mac, bbatt, rfatt);
6581         if (!c)
6582                 return (NULL);
6583         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6584
6585         return (c);
6586 }
6587
6588 static void
6589 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6590 {
6591         struct bwn_phy *phy = &mac->mac_phy;
6592         struct bwn_phy_g *pg = &phy->phy_g;
6593         struct bwn_softc *sc = mac->mac_sc;
6594         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6595         const struct bwn_rfatt *rfatt;
6596         const struct bwn_bbatt *bbatt;
6597         uint64_t pvector;
6598         int i;
6599         int rf_offset, bb_offset;
6600         uint8_t changed = 0;
6601
6602         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6603         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6604             ("%s:%d: fail", __func__, __LINE__));
6605
6606         pvector = lo->power_vector;
6607         if (!update && !pvector)
6608                 return;
6609
6610         bwn_mac_suspend(mac);
6611
6612         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6613                 struct bwn_lo_calib *cal;
6614                 int idx;
6615                 uint16_t val;
6616
6617                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6618                         continue;
6619                 bb_offset = i / lo->rfatt.len;
6620                 rf_offset = i % lo->rfatt.len;
6621                 bbatt = &(lo->bbatt.array[bb_offset]);
6622                 rfatt = &(lo->rfatt.array[rf_offset]);
6623
6624                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6625                 if (!cal) {
6626                         device_printf(sc->sc_dev, "LO: Could not "
6627                             "calibrate DC table entry\n");
6628                         continue;
6629                 }
6630                 val = (uint8_t)(cal->ctl.q);
6631                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6632                 free(cal, M_DEVBUF);
6633
6634                 idx = i / 2;
6635                 if (i % 2)
6636                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6637                             | ((val & 0x00ff) << 8);
6638                 else
6639                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6640                             | (val & 0x00ff);
6641                 changed = 1;
6642         }
6643         if (changed) {
6644                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6645                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6646         }
6647         bwn_mac_enable(mac);
6648 }
6649
6650 static void
6651 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6652 {
6653
6654         if (!rf->padmix)
6655                 return;
6656         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6657                 rf->att = 4;
6658 }
6659
6660 static void
6661 bwn_lo_g_adjust(struct bwn_mac *mac)
6662 {
6663         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6664         struct bwn_lo_calib *cal;
6665         struct bwn_rfatt rf;
6666
6667         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6668         bwn_lo_fixup_rfatt(&rf);
6669
6670         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6671         if (!cal)
6672                 return;
6673         bwn_lo_write(mac, &cal->ctl);
6674 }
6675
6676 static void
6677 bwn_lo_g_init(struct bwn_mac *mac)
6678 {
6679
6680         if (!bwn_has_hwpctl(mac))
6681                 return;
6682
6683         bwn_lo_get_powervector(mac);
6684         bwn_phy_g_dc_lookup_init(mac, 1);
6685 }
6686
6687 static void
6688 bwn_mac_suspend(struct bwn_mac *mac)
6689 {
6690         struct bwn_softc *sc = mac->mac_sc;
6691         int i;
6692         uint32_t tmp;
6693
6694         KASSERT(mac->mac_suspended >= 0,
6695             ("%s:%d: fail", __func__, __LINE__));
6696
6697         if (mac->mac_suspended == 0) {
6698                 bwn_psctl(mac, BWN_PS_AWAKE);
6699                 BWN_WRITE_4(mac, BWN_MACCTL,
6700                             BWN_READ_4(mac, BWN_MACCTL)
6701                             & ~BWN_MACCTL_ON);
6702                 BWN_READ_4(mac, BWN_MACCTL);
6703                 for (i = 35; i; i--) {
6704                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6705                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6706                                 goto out;
6707                         DELAY(10);
6708                 }
6709                 for (i = 40; i; i--) {
6710                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6711                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6712                                 goto out;
6713                         DELAY(1000);
6714                 }
6715                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6716         }
6717 out:
6718         mac->mac_suspended++;
6719 }
6720
6721 static void
6722 bwn_mac_enable(struct bwn_mac *mac)
6723 {
6724         struct bwn_softc *sc = mac->mac_sc;
6725         uint16_t state;
6726
6727         state = bwn_shm_read_2(mac, BWN_SHARED,
6728             BWN_SHARED_UCODESTAT);
6729         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6730             state != BWN_SHARED_UCODESTAT_SLEEP)
6731                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6732
6733         mac->mac_suspended--;
6734         KASSERT(mac->mac_suspended >= 0,
6735             ("%s:%d: fail", __func__, __LINE__));
6736         if (mac->mac_suspended == 0) {
6737                 BWN_WRITE_4(mac, BWN_MACCTL,
6738                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6739                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6740                 BWN_READ_4(mac, BWN_MACCTL);
6741                 BWN_READ_4(mac, BWN_INTR_REASON);
6742                 bwn_psctl(mac, 0);
6743         }
6744 }
6745
6746 static void
6747 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6748 {
6749         struct bwn_softc *sc = mac->mac_sc;
6750         int i;
6751         uint16_t ucstat;
6752
6753         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6754             ("%s:%d: fail", __func__, __LINE__));
6755         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6756             ("%s:%d: fail", __func__, __LINE__));
6757
6758         /* XXX forcibly awake and hwps-off */
6759
6760         BWN_WRITE_4(mac, BWN_MACCTL,
6761             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6762             ~BWN_MACCTL_HWPS);
6763         BWN_READ_4(mac, BWN_MACCTL);
6764         if (siba_get_revid(sc->sc_dev) >= 5) {
6765                 for (i = 0; i < 100; i++) {
6766                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6767                             BWN_SHARED_UCODESTAT);
6768                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6769                                 break;
6770                         DELAY(10);
6771                 }
6772         }
6773 }
6774
6775 static int16_t
6776 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6777 {
6778
6779         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6780         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6781 }
6782
6783 static void
6784 bwn_nrssi_threshold(struct bwn_mac *mac)
6785 {
6786         struct bwn_phy *phy = &mac->mac_phy;
6787         struct bwn_phy_g *pg = &phy->phy_g;
6788         struct bwn_softc *sc = mac->mac_sc;
6789         int32_t a, b;
6790         int16_t tmp16;
6791         uint16_t tmpu16;
6792
6793         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6794
6795         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6796                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6797                         a = 0x13;
6798                         b = 0x12;
6799                 } else {
6800                         a = 0xe;
6801                         b = 0x11;
6802                 }
6803
6804                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6805                 a += (pg->pg_nrssi[0] << 6);
6806                 a += (a < 32) ? 31 : 32;
6807                 a = a >> 6;
6808                 a = MIN(MAX(a, -31), 31);
6809
6810                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6811                 b += (pg->pg_nrssi[0] << 6);
6812                 if (b < 32)
6813                         b += 31;
6814                 else
6815                         b += 32;
6816                 b = b >> 6;
6817                 b = MIN(MAX(b, -31), 31);
6818
6819                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6820                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6821                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6822                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6823                 return;
6824         }
6825
6826         tmp16 = bwn_nrssi_read(mac, 0x20);
6827         if (tmp16 >= 0x20)
6828                 tmp16 -= 0x40;
6829         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6830 }
6831
6832 static void
6833 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6834 {
6835 #define SAVE_RF_MAX             3
6836 #define SAVE_PHY_COMM_MAX       4
6837 #define SAVE_PHY3_MAX           8
6838         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6839                 { 0x7a, 0x52, 0x43 };
6840         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6841                 { 0x15, 0x5a, 0x59, 0x58 };
6842         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6843                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6844                 0x0801, 0x0060, 0x0014, 0x0478
6845         };
6846         struct bwn_phy *phy = &mac->mac_phy;
6847         struct bwn_phy_g *pg = &phy->phy_g;
6848         int32_t i, tmp32, phy3_idx = 0;
6849         uint16_t delta, tmp;
6850         uint16_t save_rf[SAVE_RF_MAX];
6851         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6852         uint16_t save_phy3[SAVE_PHY3_MAX];
6853         uint16_t ant_div, phy0, chan_ex;
6854         int16_t nrssi0, nrssi1;
6855
6856         KASSERT(phy->type == BWN_PHYTYPE_G,
6857             ("%s:%d: fail", __func__, __LINE__));
6858
6859         if (phy->rf_rev >= 9)
6860                 return;
6861         if (phy->rf_rev == 8)
6862                 bwn_nrssi_offset(mac);
6863
6864         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6865         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6866
6867         /*
6868          * Save RF/PHY registers for later restoration
6869          */
6870         ant_div = BWN_READ_2(mac, 0x03e2);
6871         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6872         for (i = 0; i < SAVE_RF_MAX; ++i)
6873                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6874         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6875                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6876
6877         phy0 = BWN_READ_2(mac, BWN_PHY0);
6878         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6879         if (phy->rev >= 3) {
6880                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6881                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6882                 BWN_PHY_WRITE(mac, 0x002e, 0);
6883                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6884                 switch (phy->rev) {
6885                 case 4:
6886                 case 6:
6887                 case 7:
6888                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6889                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6890                         break;
6891                 case 3:
6892                 case 5:
6893                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6894                         break;
6895                 }
6896                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6897                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6898         }
6899         /*
6900          * Calculate nrssi0
6901          */
6902         BWN_RF_SET(mac, 0x007a, 0x0070);
6903         bwn_set_all_gains(mac, 0, 8, 0);
6904         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6905         if (phy->rev >= 2) {
6906                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6907                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6908         }
6909         BWN_RF_SET(mac, 0x007a, 0x0080);
6910         DELAY(20);
6911
6912         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6913         if (nrssi0 >= 0x0020)
6914                 nrssi0 -= 0x0040;
6915
6916         /*
6917          * Calculate nrssi1
6918          */
6919         BWN_RF_MASK(mac, 0x007a, 0x007f);
6920         if (phy->rev >= 2)
6921                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6922
6923         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6924             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6925         BWN_RF_SET(mac, 0x007a, 0x000f);
6926         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6927         if (phy->rev >= 2) {
6928                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6929                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6930         }
6931
6932         bwn_set_all_gains(mac, 3, 0, 1);
6933         if (phy->rf_rev == 8) {
6934                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6935         } else {
6936                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6937                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6938                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6939                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6940         }
6941         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6942         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6943         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6944         DELAY(20);
6945         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6946
6947         /*
6948          * Install calculated narrow RSSI values
6949          */
6950         if (nrssi1 >= 0x0020)
6951                 nrssi1 -= 0x0040;
6952         if (nrssi0 == nrssi1)
6953                 pg->pg_nrssi_slope = 0x00010000;
6954         else
6955                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6956         if (nrssi0 >= -4) {
6957                 pg->pg_nrssi[0] = nrssi1;
6958                 pg->pg_nrssi[1] = nrssi0;
6959         }
6960
6961         /*
6962          * Restore saved RF/PHY registers
6963          */
6964         if (phy->rev >= 3) {
6965                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6966                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6967                             save_phy3[phy3_idx]);
6968                 }
6969         }
6970         if (phy->rev >= 2) {
6971                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6972                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6973         }
6974
6975         for (i = 0; i < SAVE_RF_MAX; ++i)
6976                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6977
6978         BWN_WRITE_2(mac, 0x03e2, ant_div);
6979         BWN_WRITE_2(mac, 0x03e6, phy0);
6980         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6981
6982         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6983                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6984
6985         bwn_spu_workaround(mac, phy->chan);
6986         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6987         bwn_set_original_gains(mac);
6988         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6989         if (phy->rev >= 3) {
6990                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6991                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6992                             save_phy3[phy3_idx]);
6993                 }
6994         }
6995
6996         delta = 0x1f - pg->pg_nrssi[0];
6997         for (i = 0; i < 64; i++) {
6998                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6999                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
7000                 pg->pg_nrssi_lt[i] = tmp32;
7001         }
7002
7003         bwn_nrssi_threshold(mac);
7004 #undef SAVE_RF_MAX
7005 #undef SAVE_PHY_COMM_MAX
7006 #undef SAVE_PHY3_MAX
7007 }
7008
7009 static void
7010 bwn_nrssi_offset(struct bwn_mac *mac)
7011 {
7012 #define SAVE_RF_MAX             2
7013 #define SAVE_PHY_COMM_MAX       10
7014 #define SAVE_PHY6_MAX           8
7015         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
7016                 { 0x7a, 0x43 };
7017         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
7018                 0x0001, 0x0811, 0x0812, 0x0814,
7019                 0x0815, 0x005a, 0x0059, 0x0058,
7020                 0x000a, 0x0003
7021         };
7022         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
7023                 0x002e, 0x002f, 0x080f, 0x0810,
7024                 0x0801, 0x0060, 0x0014, 0x0478
7025         };
7026         struct bwn_phy *phy = &mac->mac_phy;
7027         int i, phy6_idx = 0;
7028         uint16_t save_rf[SAVE_RF_MAX];
7029         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
7030         uint16_t save_phy6[SAVE_PHY6_MAX];
7031         int16_t nrssi;
7032         uint16_t saved = 0xffff;
7033
7034         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
7035                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
7036         for (i = 0; i < SAVE_RF_MAX; ++i)
7037                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
7038
7039         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
7040         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
7041         BWN_PHY_SET(mac, 0x0811, 0x000c);
7042         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
7043         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
7044         if (phy->rev >= 6) {
7045                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
7046                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
7047
7048                 BWN_PHY_WRITE(mac, 0x002e, 0);
7049                 BWN_PHY_WRITE(mac, 0x002f, 0);
7050                 BWN_PHY_WRITE(mac, 0x080f, 0);
7051                 BWN_PHY_WRITE(mac, 0x0810, 0);
7052                 BWN_PHY_SET(mac, 0x0478, 0x0100);
7053                 BWN_PHY_SET(mac, 0x0801, 0x0040);
7054                 BWN_PHY_SET(mac, 0x0060, 0x0040);
7055                 BWN_PHY_SET(mac, 0x0014, 0x0200);
7056         }
7057         BWN_RF_SET(mac, 0x007a, 0x0070);
7058         BWN_RF_SET(mac, 0x007a, 0x0080);
7059         DELAY(30);
7060
7061         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7062         if (nrssi >= 0x20)
7063                 nrssi -= 0x40;
7064         if (nrssi == 31) {
7065                 for (i = 7; i >= 4; i--) {
7066                         BWN_RF_WRITE(mac, 0x007b, i);
7067                         DELAY(20);
7068                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7069                             0x003f);
7070                         if (nrssi >= 0x20)
7071                                 nrssi -= 0x40;
7072                         if (nrssi < 31 && saved == 0xffff)
7073                                 saved = i;
7074                 }
7075                 if (saved == 0xffff)
7076                         saved = 4;
7077         } else {
7078                 BWN_RF_MASK(mac, 0x007a, 0x007f);
7079                 if (phy->rev != 1) {
7080                         BWN_PHY_SET(mac, 0x0814, 0x0001);
7081                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7082                 }
7083                 BWN_PHY_SET(mac, 0x0811, 0x000c);
7084                 BWN_PHY_SET(mac, 0x0812, 0x000c);
7085                 BWN_PHY_SET(mac, 0x0811, 0x0030);
7086                 BWN_PHY_SET(mac, 0x0812, 0x0030);
7087                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7088                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7089                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7090                 if (phy->rev == 0)
7091                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7092                 else
7093                         BWN_PHY_SET(mac, 0x000a, 0x2000);
7094                 if (phy->rev != 1) {
7095                         BWN_PHY_SET(mac, 0x0814, 0x0004);
7096                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7097                 }
7098                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7099                 BWN_RF_SET(mac, 0x007a, 0x000f);
7100                 bwn_set_all_gains(mac, 3, 0, 1);
7101                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7102                 DELAY(30);
7103                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7104                 if (nrssi >= 0x20)
7105                         nrssi -= 0x40;
7106                 if (nrssi == -32) {
7107                         for (i = 0; i < 4; i++) {
7108                                 BWN_RF_WRITE(mac, 0x007b, i);
7109                                 DELAY(20);
7110                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
7111                                     0x047f) >> 8) & 0x003f);
7112                                 if (nrssi >= 0x20)
7113                                         nrssi -= 0x40;
7114                                 if (nrssi > -31 && saved == 0xffff)
7115                                         saved = i;
7116                         }
7117                         if (saved == 0xffff)
7118                                 saved = 3;
7119                 } else
7120                         saved = 0;
7121         }
7122         BWN_RF_WRITE(mac, 0x007b, saved);
7123
7124         /*
7125          * Restore saved RF/PHY registers
7126          */
7127         if (phy->rev >= 6) {
7128                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7129                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7130                             save_phy6[phy6_idx]);
7131                 }
7132         }
7133         if (phy->rev != 1) {
7134                 for (i = 3; i < 5; i++)
7135                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7136                             save_phy_comm[i]);
7137         }
7138         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7139                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7140
7141         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7142                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7143
7144         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7145         BWN_PHY_SET(mac, 0x0429, 0x8000);
7146         bwn_set_original_gains(mac);
7147         if (phy->rev >= 6) {
7148                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7149                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7150                             save_phy6[phy6_idx]);
7151                 }
7152         }
7153
7154         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7155         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7156         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7157 }
7158
7159 static void
7160 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7161     int16_t third)
7162 {
7163         struct bwn_phy *phy = &mac->mac_phy;
7164         uint16_t i;
7165         uint16_t start = 0x08, end = 0x18;
7166         uint16_t tmp;
7167         uint16_t table;
7168
7169         if (phy->rev <= 1) {
7170                 start = 0x10;
7171                 end = 0x20;
7172         }
7173
7174         table = BWN_OFDMTAB_GAINX;
7175         if (phy->rev <= 1)
7176                 table = BWN_OFDMTAB_GAINX_R1;
7177         for (i = 0; i < 4; i++)
7178                 bwn_ofdmtab_write_2(mac, table, i, first);
7179
7180         for (i = start; i < end; i++)
7181                 bwn_ofdmtab_write_2(mac, table, i, second);
7182
7183         if (third != -1) {
7184                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7185                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7186                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7187                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7188         }
7189         bwn_dummy_transmission(mac, 0, 1);
7190 }
7191
7192 static void
7193 bwn_set_original_gains(struct bwn_mac *mac)
7194 {
7195         struct bwn_phy *phy = &mac->mac_phy;
7196         uint16_t i, tmp;
7197         uint16_t table;
7198         uint16_t start = 0x0008, end = 0x0018;
7199
7200         if (phy->rev <= 1) {
7201                 start = 0x0010;
7202                 end = 0x0020;
7203         }
7204
7205         table = BWN_OFDMTAB_GAINX;
7206         if (phy->rev <= 1)
7207                 table = BWN_OFDMTAB_GAINX_R1;
7208         for (i = 0; i < 4; i++) {
7209                 tmp = (i & 0xfffc);
7210                 tmp |= (i & 0x0001) << 1;
7211                 tmp |= (i & 0x0002) >> 1;
7212
7213                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7214         }
7215
7216         for (i = start; i < end; i++)
7217                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7218
7219         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7220         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7221         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7222         bwn_dummy_transmission(mac, 0, 1);
7223 }
7224
7225 static void
7226 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7227 {
7228         struct bwn_phy *phy = &mac->mac_phy;
7229         struct bwn_phy_g *pg = &phy->phy_g;
7230         struct bwn_rfatt old_rfatt, rfatt;
7231         struct bwn_bbatt old_bbatt, bbatt;
7232         struct bwn_softc *sc = mac->mac_sc;
7233         uint8_t old_txctl = 0;
7234
7235         KASSERT(phy->type == BWN_PHYTYPE_G,
7236             ("%s:%d: fail", __func__, __LINE__));
7237
7238         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7239             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7240                 return;
7241
7242         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7243
7244         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7245
7246         if (!phy->gmode)
7247                 return;
7248         bwn_hwpctl_early_init(mac);
7249         if (pg->pg_curtssi == 0) {
7250                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7251                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7252                 } else {
7253                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7254                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7255                         old_txctl = pg->pg_txctl;
7256
7257                         bbatt.att = 11;
7258                         if (phy->rf_rev == 8) {
7259                                 rfatt.att = 15;
7260                                 rfatt.padmix = 1;
7261                         } else {
7262                                 rfatt.att = 9;
7263                                 rfatt.padmix = 0;
7264                         }
7265                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7266                 }
7267                 bwn_dummy_transmission(mac, 0, 1);
7268                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7269                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7270                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7271                 else
7272                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7273                             &old_rfatt, old_txctl);
7274         }
7275         bwn_hwpctl_init_gphy(mac);
7276
7277         /* clear TSSI */
7278         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7279         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7280         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7281         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7282 }
7283
7284 static void
7285 bwn_hwpctl_early_init(struct bwn_mac *mac)
7286 {
7287         struct bwn_phy *phy = &mac->mac_phy;
7288
7289         if (!bwn_has_hwpctl(mac)) {
7290                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7291                 return;
7292         }
7293
7294         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7295         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7296         BWN_PHY_SET(mac, 0x047c, 0x0002);
7297         BWN_PHY_SET(mac, 0x047a, 0xf000);
7298         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7299                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7300                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7301                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7302                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7303                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7304         } else {
7305                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7306                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7307                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7308                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7309                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7310                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7311                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7312         }
7313 }
7314
7315 static void
7316 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7317 {
7318         struct bwn_phy *phy = &mac->mac_phy;
7319         struct bwn_phy_g *pg = &phy->phy_g;
7320         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7321         int i;
7322         uint16_t nr_written = 0, tmp, value;
7323         uint8_t rf, bb;
7324
7325         if (!bwn_has_hwpctl(mac)) {
7326                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7327                 return;
7328         }
7329
7330         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7331             (pg->pg_idletssi - pg->pg_curtssi));
7332         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7333             (pg->pg_idletssi - pg->pg_curtssi));
7334
7335         for (i = 0; i < 32; i++)
7336                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7337         for (i = 32; i < 64; i++)
7338                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7339         for (i = 0; i < 64; i += 2) {
7340                 value = (uint16_t) pg->pg_tssi2dbm[i];
7341                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7342                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7343         }
7344
7345         for (rf = 0; rf < lo->rfatt.len; rf++) {
7346                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7347                         if (nr_written >= 0x40)
7348                                 return;
7349                         tmp = lo->bbatt.array[bb].att;
7350                         tmp <<= 8;
7351                         if (phy->rf_rev == 8)
7352                                 tmp |= 0x50;
7353                         else
7354                                 tmp |= 0x40;
7355                         tmp |= lo->rfatt.array[rf].att;
7356                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7357                         nr_written++;
7358                 }
7359         }
7360
7361         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7362         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7363
7364         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7365         BWN_PHY_SET(mac, 0x0478, 0x0800);
7366         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7367         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7368
7369         bwn_phy_g_dc_lookup_init(mac, 1);
7370         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7371 }
7372
7373 static void
7374 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7375 {
7376         struct bwn_softc *sc = mac->mac_sc;
7377
7378         if (spu != 0)
7379                 bwn_spu_workaround(mac, channel);
7380
7381         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7382
7383         if (channel == 14) {
7384                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7385                         bwn_hf_write(mac,
7386                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7387                 else
7388                         bwn_hf_write(mac,
7389                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7390                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7391                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7392                 return;
7393         }
7394
7395         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7396             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7397 }
7398
7399 static uint16_t
7400 bwn_phy_g_chan2freq(uint8_t channel)
7401 {
7402         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7403
7404         KASSERT(channel >= 1 && channel <= 14,
7405             ("%s:%d: fail", __func__, __LINE__));
7406
7407         return (bwn_phy_g_rf_channels[channel - 1]);
7408 }
7409
7410 static void
7411 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7412     const struct bwn_rfatt *rfatt, uint8_t txctl)
7413 {
7414         struct bwn_phy *phy = &mac->mac_phy;
7415         struct bwn_phy_g *pg = &phy->phy_g;
7416         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7417         uint16_t bb, rf;
7418         uint16_t tx_bias, tx_magn;
7419
7420         bb = bbatt->att;
7421         rf = rfatt->att;
7422         tx_bias = lo->tx_bias;
7423         tx_magn = lo->tx_magn;
7424         if (tx_bias == 0xff)
7425                 tx_bias = 0;
7426
7427         pg->pg_txctl = txctl;
7428         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7429         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7430         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7431         bwn_phy_g_set_bbatt(mac, bb);
7432         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7433         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7434                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7435         else {
7436                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7437                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7438         }
7439         if (BWN_HAS_TXMAG(phy))
7440                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7441         else
7442                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7443         bwn_lo_g_adjust(mac);
7444 }
7445
7446 static void
7447 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7448     uint16_t bbatt)
7449 {
7450         struct bwn_phy *phy = &mac->mac_phy;
7451
7452         if (phy->analog == 0) {
7453                 BWN_WRITE_2(mac, BWN_PHY0,
7454                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7455                 return;
7456         }
7457         if (phy->analog > 1) {
7458                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7459                 return;
7460         }
7461         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7462 }
7463
7464 static uint16_t
7465 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7466 {
7467         struct bwn_phy *phy = &mac->mac_phy;
7468         struct bwn_phy_g *pg = &phy->phy_g;
7469         struct bwn_softc *sc = mac->mac_sc;
7470         int max_lb_gain;
7471         uint16_t extlna;
7472         uint16_t i;
7473
7474         if (phy->gmode == 0)
7475                 return (0);
7476
7477         if (BWN_HAS_LOOPBACK(phy)) {
7478                 max_lb_gain = pg->pg_max_lb_gain;
7479                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7480                 if (max_lb_gain >= 0x46) {
7481                         extlna = 0x3000;
7482                         max_lb_gain -= 0x46;
7483                 } else if (max_lb_gain >= 0x3a) {
7484                         extlna = 0x1000;
7485                         max_lb_gain -= 0x3a;
7486                 } else if (max_lb_gain >= 0x2e) {
7487                         extlna = 0x2000;
7488                         max_lb_gain -= 0x2e;
7489                 } else {
7490                         extlna = 0;
7491                         max_lb_gain -= 0x10;
7492                 }
7493
7494                 for (i = 0; i < 16; i++) {
7495                         max_lb_gain -= (i * 6);
7496                         if (max_lb_gain < 6)
7497                                 break;
7498                 }
7499
7500                 if ((phy->rev < 7) ||
7501                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7502                         if (reg == BWN_PHY_RFOVER) {
7503                                 return (0x1b3);
7504                         } else if (reg == BWN_PHY_RFOVERVAL) {
7505                                 extlna |= (i << 8);
7506                                 switch (lpd) {
7507                                 case BWN_LPD(0, 1, 1):
7508                                         return (0x0f92);
7509                                 case BWN_LPD(0, 0, 1):
7510                                 case BWN_LPD(1, 0, 1):
7511                                         return (0x0092 | extlna);
7512                                 case BWN_LPD(1, 0, 0):
7513                                         return (0x0093 | extlna);
7514                                 }
7515                                 KASSERT(0 == 1,
7516                                     ("%s:%d: fail", __func__, __LINE__));
7517                         }
7518                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7519                 } else {
7520                         if (reg == BWN_PHY_RFOVER)
7521                                 return (0x9b3);
7522                         if (reg == BWN_PHY_RFOVERVAL) {
7523                                 if (extlna)
7524                                         extlna |= 0x8000;
7525                                 extlna |= (i << 8);
7526                                 switch (lpd) {
7527                                 case BWN_LPD(0, 1, 1):
7528                                         return (0x8f92);
7529                                 case BWN_LPD(0, 0, 1):
7530                                         return (0x8092 | extlna);
7531                                 case BWN_LPD(1, 0, 1):
7532                                         return (0x2092 | extlna);
7533                                 case BWN_LPD(1, 0, 0):
7534                                         return (0x2093 | extlna);
7535                                 }
7536                                 KASSERT(0 == 1,
7537                                     ("%s:%d: fail", __func__, __LINE__));
7538                         }
7539                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7540                 }
7541                 return (0);
7542         }
7543
7544         if ((phy->rev < 7) ||
7545             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7546                 if (reg == BWN_PHY_RFOVER) {
7547                         return (0x1b3);
7548                 } else if (reg == BWN_PHY_RFOVERVAL) {
7549                         switch (lpd) {
7550                         case BWN_LPD(0, 1, 1):
7551                                 return (0x0fb2);
7552                         case BWN_LPD(0, 0, 1):
7553                                 return (0x00b2);
7554                         case BWN_LPD(1, 0, 1):
7555                                 return (0x30b2);
7556                         case BWN_LPD(1, 0, 0):
7557                                 return (0x30b3);
7558                         }
7559                         KASSERT(0 == 1,
7560                             ("%s:%d: fail", __func__, __LINE__));
7561                 }
7562                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7563         } else {
7564                 if (reg == BWN_PHY_RFOVER) {
7565                         return (0x9b3);
7566                 } else if (reg == BWN_PHY_RFOVERVAL) {
7567                         switch (lpd) {
7568                         case BWN_LPD(0, 1, 1):
7569                                 return (0x8fb2);
7570                         case BWN_LPD(0, 0, 1):
7571                                 return (0x80b2);
7572                         case BWN_LPD(1, 0, 1):
7573                                 return (0x20b2);
7574                         case BWN_LPD(1, 0, 0):
7575                                 return (0x20b3);
7576                         }
7577                         KASSERT(0 == 1,
7578                             ("%s:%d: fail", __func__, __LINE__));
7579                 }
7580                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7581         }
7582         return (0);
7583 }
7584
7585 static void
7586 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7587 {
7588
7589         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7590                 return;
7591         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7592             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7593         DELAY(1000);
7594         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7595 }
7596
7597 static int
7598 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7599 {
7600         struct bwn_softc *sc = mac->mac_sc;
7601         struct bwn_fw *fw = &mac->mac_fw;
7602         const uint8_t rev = siba_get_revid(sc->sc_dev);
7603         const char *filename;
7604         uint32_t high;
7605         int error;
7606
7607         /* microcode */
7608         if (rev >= 5 && rev <= 10)
7609                 filename = "ucode5";
7610         else if (rev >= 11 && rev <= 12)
7611                 filename = "ucode11";
7612         else if (rev == 13)
7613                 filename = "ucode13";
7614         else if (rev == 14)
7615                 filename = "ucode14";
7616         else if (rev >= 15)
7617                 filename = "ucode15";
7618         else {
7619                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7620                 bwn_release_firmware(mac);
7621                 return (EOPNOTSUPP);
7622         }
7623         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7624         if (error) {
7625                 bwn_release_firmware(mac);
7626                 return (error);
7627         }
7628
7629         /* PCM */
7630         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7631         if (rev >= 5 && rev <= 10) {
7632                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7633                 if (error == ENOENT)
7634                         fw->no_pcmfile = 1;
7635                 else if (error) {
7636                         bwn_release_firmware(mac);
7637                         return (error);
7638                 }
7639         } else if (rev < 11) {
7640                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7641                 return (EOPNOTSUPP);
7642         }
7643
7644         /* initvals */
7645         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7646         switch (mac->mac_phy.type) {
7647         case BWN_PHYTYPE_A:
7648                 if (rev < 5 || rev > 10)
7649                         goto fail1;
7650                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7651                         filename = "a0g1initvals5";
7652                 else
7653                         filename = "a0g0initvals5";
7654                 break;
7655         case BWN_PHYTYPE_G:
7656                 if (rev >= 5 && rev <= 10)
7657                         filename = "b0g0initvals5";
7658                 else if (rev >= 13)
7659                         filename = "b0g0initvals13";
7660                 else
7661                         goto fail1;
7662                 break;
7663         case BWN_PHYTYPE_LP:
7664                 if (rev == 13)
7665                         filename = "lp0initvals13";
7666                 else if (rev == 14)
7667                         filename = "lp0initvals14";
7668                 else if (rev >= 15)
7669                         filename = "lp0initvals15";
7670                 else
7671                         goto fail1;
7672                 break;
7673         case BWN_PHYTYPE_N:
7674                 if (rev >= 11 && rev <= 12)
7675                         filename = "n0initvals11";
7676                 else
7677                         goto fail1;
7678                 break;
7679         default:
7680                 goto fail1;
7681         }
7682         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7683         if (error) {
7684                 bwn_release_firmware(mac);
7685                 return (error);
7686         }
7687
7688         /* bandswitch initvals */
7689         switch (mac->mac_phy.type) {
7690         case BWN_PHYTYPE_A:
7691                 if (rev >= 5 && rev <= 10) {
7692                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7693                                 filename = "a0g1bsinitvals5";
7694                         else
7695                                 filename = "a0g0bsinitvals5";
7696                 } else if (rev >= 11)
7697                         filename = NULL;
7698                 else
7699                         goto fail1;
7700                 break;
7701         case BWN_PHYTYPE_G:
7702                 if (rev >= 5 && rev <= 10)
7703                         filename = "b0g0bsinitvals5";
7704                 else if (rev >= 11)
7705                         filename = NULL;
7706                 else
7707                         goto fail1;
7708                 break;
7709         case BWN_PHYTYPE_LP:
7710                 if (rev == 13)
7711                         filename = "lp0bsinitvals13";
7712                 else if (rev == 14)
7713                         filename = "lp0bsinitvals14";
7714                 else if (rev >= 15)
7715                         filename = "lp0bsinitvals15";
7716                 else
7717                         goto fail1;
7718                 break;
7719         case BWN_PHYTYPE_N:
7720                 if (rev >= 11 && rev <= 12)
7721                         filename = "n0bsinitvals11";
7722                 else
7723                         goto fail1;
7724                 break;
7725         default:
7726                 goto fail1;
7727         }
7728         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7729         if (error) {
7730                 bwn_release_firmware(mac);
7731                 return (error);
7732         }
7733         return (0);
7734 fail1:
7735         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7736         bwn_release_firmware(mac);
7737         return (EOPNOTSUPP);
7738 }
7739
7740 static int
7741 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7742     const char *name, struct bwn_fwfile *bfw)
7743 {
7744         const struct bwn_fwhdr *hdr;
7745         struct bwn_softc *sc = mac->mac_sc;
7746         const struct firmware *fw;
7747         char namebuf[64];
7748
7749         if (name == NULL) {
7750                 bwn_do_release_fw(bfw);
7751                 return (0);
7752         }
7753         if (bfw->filename != NULL) {
7754                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7755                         return (0);
7756                 bwn_do_release_fw(bfw);
7757         }
7758
7759         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7760             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7761             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7762         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7763         fw = firmware_get(namebuf);
7764         if (fw == NULL) {
7765                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7766                     namebuf);
7767                 return (ENOENT);
7768         }
7769         if (fw->datasize < sizeof(struct bwn_fwhdr))
7770                 goto fail;
7771         hdr = (const struct bwn_fwhdr *)(fw->data);
7772         switch (hdr->type) {
7773         case BWN_FWTYPE_UCODE:
7774         case BWN_FWTYPE_PCM:
7775                 if (be32toh(hdr->size) !=
7776                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7777                         goto fail;
7778                 /* FALLTHROUGH */
7779         case BWN_FWTYPE_IV:
7780                 if (hdr->ver != 1)
7781                         goto fail;
7782                 break;
7783         default:
7784                 goto fail;
7785         }
7786         bfw->filename = name;
7787         bfw->fw = fw;
7788         bfw->type = type;
7789         return (0);
7790 fail:
7791         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7792         if (fw != NULL)
7793                 firmware_put(fw, FIRMWARE_UNLOAD);
7794         return (EPROTO);
7795 }
7796
7797 static void
7798 bwn_release_firmware(struct bwn_mac *mac)
7799 {
7800
7801         bwn_do_release_fw(&mac->mac_fw.ucode);
7802         bwn_do_release_fw(&mac->mac_fw.pcm);
7803         bwn_do_release_fw(&mac->mac_fw.initvals);
7804         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7805 }
7806
7807 static void
7808 bwn_do_release_fw(struct bwn_fwfile *bfw)
7809 {
7810
7811         if (bfw->fw != NULL)
7812                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7813         bfw->fw = NULL;
7814         bfw->filename = NULL;
7815 }
7816
7817 static int
7818 bwn_fw_loaducode(struct bwn_mac *mac)
7819 {
7820 #define GETFWOFFSET(fwp, offset)        \
7821         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7822 #define GETFWSIZE(fwp, offset)  \
7823         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7824         struct bwn_softc *sc = mac->mac_sc;
7825         const uint32_t *data;
7826         unsigned int i;
7827         uint32_t ctl;
7828         uint16_t date, fwcaps, time;
7829         int error = 0;
7830
7831         ctl = BWN_READ_4(mac, BWN_MACCTL);
7832         ctl |= BWN_MACCTL_MCODE_JMP0;
7833         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7834             __LINE__));
7835         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7836         for (i = 0; i < 64; i++)
7837                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7838         for (i = 0; i < 4096; i += 2)
7839                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7840
7841         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7842         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7843         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7844              i++) {
7845                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7846                 DELAY(10);
7847         }
7848
7849         if (mac->mac_fw.pcm.fw) {
7850                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7851                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7852                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7853                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7854                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7855                     sizeof(struct bwn_fwhdr)); i++) {
7856                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7857                         DELAY(10);
7858                 }
7859         }
7860
7861         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7862         BWN_WRITE_4(mac, BWN_MACCTL,
7863             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7864             BWN_MACCTL_MCODE_RUN);
7865
7866         for (i = 0; i < 21; i++) {
7867                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7868                         break;
7869                 if (i >= 20) {
7870                         device_printf(sc->sc_dev, "ucode timeout\n");
7871                         error = ENXIO;
7872                         goto error;
7873                 }
7874                 DELAY(50000);
7875         }
7876         BWN_READ_4(mac, BWN_INTR_REASON);
7877
7878         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7879         if (mac->mac_fw.rev <= 0x128) {
7880                 device_printf(sc->sc_dev, "the firmware is too old\n");
7881                 error = EOPNOTSUPP;
7882                 goto error;
7883         }
7884         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7885             BWN_SHARED_UCODE_PATCH);
7886         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7887         mac->mac_fw.opensource = (date == 0xffff);
7888         if (bwn_wme != 0)
7889                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7890         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7891
7892         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7893         if (mac->mac_fw.opensource == 0) {
7894                 device_printf(sc->sc_dev,
7895                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7896                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7897                 if (mac->mac_fw.no_pcmfile)
7898                         device_printf(sc->sc_dev,
7899                             "no HW crypto acceleration due to pcm5\n");
7900         } else {
7901                 mac->mac_fw.patch = time;
7902                 fwcaps = bwn_fwcaps_read(mac);
7903                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7904                         device_printf(sc->sc_dev,
7905                             "disabling HW crypto acceleration\n");
7906                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7907                 }
7908                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7909                         device_printf(sc->sc_dev, "disabling WME support\n");
7910                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7911                 }
7912         }
7913
7914         if (BWN_ISOLDFMT(mac))
7915                 device_printf(sc->sc_dev, "using old firmware image\n");
7916
7917         return (0);
7918
7919 error:
7920         BWN_WRITE_4(mac, BWN_MACCTL,
7921             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7922             BWN_MACCTL_MCODE_JMP0);
7923
7924         return (error);
7925 #undef GETFWSIZE
7926 #undef GETFWOFFSET
7927 }
7928
7929 /* OpenFirmware only */
7930 static uint16_t
7931 bwn_fwcaps_read(struct bwn_mac *mac)
7932 {
7933
7934         KASSERT(mac->mac_fw.opensource == 1,
7935             ("%s:%d: fail", __func__, __LINE__));
7936         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7937 }
7938
7939 static int
7940 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7941     size_t count, size_t array_size)
7942 {
7943 #define GET_NEXTIV16(iv)                                                \
7944         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7945             sizeof(uint16_t) + sizeof(uint16_t)))
7946 #define GET_NEXTIV32(iv)                                                \
7947         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7948             sizeof(uint16_t) + sizeof(uint32_t)))
7949         struct bwn_softc *sc = mac->mac_sc;
7950         const struct bwn_fwinitvals *iv;
7951         uint16_t offset;
7952         size_t i;
7953         uint8_t bit32;
7954
7955         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7956             ("%s:%d: fail", __func__, __LINE__));
7957         iv = ivals;
7958         for (i = 0; i < count; i++) {
7959                 if (array_size < sizeof(iv->offset_size))
7960                         goto fail;
7961                 array_size -= sizeof(iv->offset_size);
7962                 offset = be16toh(iv->offset_size);
7963                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7964                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7965                 if (offset >= 0x1000)
7966                         goto fail;
7967                 if (bit32) {
7968                         if (array_size < sizeof(iv->data.d32))
7969                                 goto fail;
7970                         array_size -= sizeof(iv->data.d32);
7971                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7972                         iv = GET_NEXTIV32(iv);
7973                 } else {
7974
7975                         if (array_size < sizeof(iv->data.d16))
7976                                 goto fail;
7977                         array_size -= sizeof(iv->data.d16);
7978                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7979
7980                         iv = GET_NEXTIV16(iv);
7981                 }
7982         }
7983         if (array_size != 0)
7984                 goto fail;
7985         return (0);
7986 fail:
7987         device_printf(sc->sc_dev, "initvals: invalid format\n");
7988         return (EPROTO);
7989 #undef GET_NEXTIV16
7990 #undef GET_NEXTIV32
7991 }
7992
7993 static int
7994 bwn_switch_channel(struct bwn_mac *mac, int chan)
7995 {
7996         struct bwn_phy *phy = &(mac->mac_phy);
7997         struct bwn_softc *sc = mac->mac_sc;
7998         struct ifnet *ifp = sc->sc_ifp;
7999         struct ieee80211com *ic = ifp->if_l2com;
8000         uint16_t channelcookie, savedcookie;
8001         int error;
8002
8003         if (chan == 0xffff)
8004                 chan = phy->get_default_chan(mac);
8005
8006         channelcookie = chan;
8007         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
8008                 channelcookie |= 0x100;
8009         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
8010         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
8011         error = phy->switch_channel(mac, chan);
8012         if (error)
8013                 goto fail;
8014
8015         mac->mac_phy.chan = chan;
8016         DELAY(8000);
8017         return (0);
8018 fail:
8019         device_printf(sc->sc_dev, "failed to switch channel\n");
8020         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
8021         return (error);
8022 }
8023
8024 static uint16_t
8025 bwn_ant2phy(int antenna)
8026 {
8027
8028         switch (antenna) {
8029         case BWN_ANT0:
8030                 return (BWN_TX_PHY_ANT0);
8031         case BWN_ANT1:
8032                 return (BWN_TX_PHY_ANT1);
8033         case BWN_ANT2:
8034                 return (BWN_TX_PHY_ANT2);
8035         case BWN_ANT3:
8036                 return (BWN_TX_PHY_ANT3);
8037         case BWN_ANTAUTO:
8038                 return (BWN_TX_PHY_ANT01AUTO);
8039         }
8040         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8041         return (0);
8042 }
8043
8044 static void
8045 bwn_wme_load(struct bwn_mac *mac)
8046 {
8047         struct bwn_softc *sc = mac->mac_sc;
8048         int i;
8049
8050         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8051             ("%s:%d: fail", __func__, __LINE__));
8052
8053         bwn_mac_suspend(mac);
8054         for (i = 0; i < N(sc->sc_wmeParams); i++)
8055                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8056                     bwn_wme_shm_offsets[i]);
8057         bwn_mac_enable(mac);
8058 }
8059
8060 static void
8061 bwn_wme_loadparams(struct bwn_mac *mac,
8062     const struct wmeParams *p, uint16_t shm_offset)
8063 {
8064 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
8065         struct bwn_softc *sc = mac->mac_sc;
8066         uint16_t params[BWN_NR_WMEPARAMS];
8067         int slot, tmp;
8068         unsigned int i;
8069
8070         slot = BWN_READ_2(mac, BWN_RNG) &
8071             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8072
8073         memset(&params, 0, sizeof(params));
8074
8075         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8076             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8077             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8078
8079         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8080         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8081         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8082         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8083         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8084         params[BWN_WMEPARAM_BSLOTS] = slot;
8085         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8086
8087         for (i = 0; i < N(params); i++) {
8088                 if (i == BWN_WMEPARAM_STATUS) {
8089                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
8090                             shm_offset + (i * 2));
8091                         tmp |= 0x100;
8092                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8093                             tmp);
8094                 } else {
8095                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8096                             params[i]);
8097                 }
8098         }
8099 }
8100
8101 static void
8102 bwn_mac_write_bssid(struct bwn_mac *mac)
8103 {
8104         struct bwn_softc *sc = mac->mac_sc;
8105         uint32_t tmp;
8106         int i;
8107         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8108
8109         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8110         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8111         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8112             IEEE80211_ADDR_LEN);
8113
8114         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8115                 tmp = (uint32_t) (mac_bssid[i + 0]);
8116                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8117                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8118                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8119                 bwn_ram_write(mac, 0x20 + i, tmp);
8120         }
8121 }
8122
8123 static void
8124 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8125     const uint8_t *macaddr)
8126 {
8127         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8128         uint16_t data;
8129
8130         if (!mac)
8131                 macaddr = zero;
8132
8133         offset |= 0x0020;
8134         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8135
8136         data = macaddr[0];
8137         data |= macaddr[1] << 8;
8138         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8139         data = macaddr[2];
8140         data |= macaddr[3] << 8;
8141         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8142         data = macaddr[4];
8143         data |= macaddr[5] << 8;
8144         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8145 }
8146
8147 static void
8148 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8149     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8150 {
8151         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8152         uint8_t per_sta_keys_start = 8;
8153
8154         if (BWN_SEC_NEWAPI(mac))
8155                 per_sta_keys_start = 4;
8156
8157         KASSERT(index < mac->mac_max_nr_keys,
8158             ("%s:%d: fail", __func__, __LINE__));
8159         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8160             ("%s:%d: fail", __func__, __LINE__));
8161
8162         if (index >= per_sta_keys_start)
8163                 bwn_key_macwrite(mac, index, NULL);
8164         if (key)
8165                 memcpy(buf, key, key_len);
8166         bwn_key_write(mac, index, algorithm, buf);
8167         if (index >= per_sta_keys_start)
8168                 bwn_key_macwrite(mac, index, mac_addr);
8169
8170         mac->mac_key[index].algorithm = algorithm;
8171 }
8172
8173 static void
8174 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8175 {
8176         struct bwn_softc *sc = mac->mac_sc;
8177         uint32_t addrtmp[2] = { 0, 0 };
8178         uint8_t start = 8;
8179
8180         if (BWN_SEC_NEWAPI(mac))
8181                 start = 4;
8182
8183         KASSERT(index >= start,
8184             ("%s:%d: fail", __func__, __LINE__));
8185         index -= start;
8186
8187         if (addr) {
8188                 addrtmp[0] = addr[0];
8189                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8190                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8191                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8192                 addrtmp[1] = addr[4];
8193                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8194         }
8195
8196         if (siba_get_revid(sc->sc_dev) >= 5) {
8197                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8198                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8199         } else {
8200                 if (index >= 8) {
8201                         bwn_shm_write_4(mac, BWN_SHARED,
8202                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8203                         bwn_shm_write_2(mac, BWN_SHARED,
8204                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8205                 }
8206         }
8207 }
8208
8209 static void
8210 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8211     const uint8_t *key)
8212 {
8213         unsigned int i;
8214         uint32_t offset;
8215         uint16_t kidx, value;
8216
8217         kidx = BWN_SEC_KEY2FW(mac, index);
8218         bwn_shm_write_2(mac, BWN_SHARED,
8219             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8220
8221         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8222         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8223                 value = key[i];
8224                 value |= (uint16_t)(key[i + 1]) << 8;
8225                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8226         }
8227 }
8228
8229 static void
8230 bwn_phy_exit(struct bwn_mac *mac)
8231 {
8232
8233         mac->mac_phy.rf_onoff(mac, 0);
8234         if (mac->mac_phy.exit != NULL)
8235                 mac->mac_phy.exit(mac);
8236 }
8237
8238 static void
8239 bwn_dma_free(struct bwn_mac *mac)
8240 {
8241         struct bwn_dma *dma;
8242
8243         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8244                 return;
8245         dma = &mac->mac_method.dma;
8246
8247         bwn_dma_ringfree(&dma->rx);
8248         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8249         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8250         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8251         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8252         bwn_dma_ringfree(&dma->mcast);
8253 }
8254
8255 static void
8256 bwn_core_stop(struct bwn_mac *mac)
8257 {
8258         struct bwn_softc *sc = mac->mac_sc;
8259
8260         BWN_ASSERT_LOCKED(sc);
8261
8262         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8263                 return;
8264
8265         callout_stop(&sc->sc_rfswitch_ch);
8266         callout_stop(&sc->sc_task_ch);
8267         callout_stop(&sc->sc_watchdog_ch);
8268         sc->sc_watchdog_timer = 0;
8269         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8270         BWN_READ_4(mac, BWN_INTR_MASK);
8271         bwn_mac_suspend(mac);
8272
8273         mac->mac_status = BWN_MAC_STATUS_INITED;
8274 }
8275
8276 static int
8277 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8278 {
8279         struct bwn_mac *up_dev = NULL;
8280         struct bwn_mac *down_dev;
8281         struct bwn_mac *mac;
8282         int err, status;
8283         uint8_t gmode;
8284
8285         BWN_ASSERT_LOCKED(sc);
8286
8287         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8288                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8289                     mac->mac_phy.supports_2ghz) {
8290                         up_dev = mac;
8291                         gmode = 1;
8292                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8293                     mac->mac_phy.supports_5ghz) {
8294                         up_dev = mac;
8295                         gmode = 0;
8296                 } else {
8297                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8298                         return (EINVAL);
8299                 }
8300                 if (up_dev != NULL)
8301                         break;
8302         }
8303         if (up_dev == NULL) {
8304                 device_printf(sc->sc_dev, "Could not find a device\n");
8305                 return (ENODEV);
8306         }
8307         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8308                 return (0);
8309
8310         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8311             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8312
8313         down_dev = sc->sc_curmac;;
8314         status = down_dev->mac_status;
8315         if (status >= BWN_MAC_STATUS_STARTED)
8316                 bwn_core_stop(down_dev);
8317         if (status >= BWN_MAC_STATUS_INITED)
8318                 bwn_core_exit(down_dev);
8319
8320         if (down_dev != up_dev)
8321                 bwn_phy_reset(down_dev);
8322
8323         up_dev->mac_phy.gmode = gmode;
8324         if (status >= BWN_MAC_STATUS_INITED) {
8325                 err = bwn_core_init(up_dev);
8326                 if (err) {
8327                         device_printf(sc->sc_dev,
8328                             "fatal: failed to initialize for %s-GHz\n",
8329                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8330                         goto fail;
8331                 }
8332         }
8333         if (status >= BWN_MAC_STATUS_STARTED)
8334                 bwn_core_start(up_dev);
8335         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8336         sc->sc_curmac = up_dev;
8337
8338         return (0);
8339 fail:
8340         sc->sc_curmac = NULL;
8341         return (err);
8342 }
8343
8344 static void
8345 bwn_rf_turnon(struct bwn_mac *mac)
8346 {
8347
8348         bwn_mac_suspend(mac);
8349         mac->mac_phy.rf_onoff(mac, 1);
8350         mac->mac_phy.rf_on = 1;
8351         bwn_mac_enable(mac);
8352 }
8353
8354 static void
8355 bwn_rf_turnoff(struct bwn_mac *mac)
8356 {
8357
8358         bwn_mac_suspend(mac);
8359         mac->mac_phy.rf_onoff(mac, 0);
8360         mac->mac_phy.rf_on = 0;
8361         bwn_mac_enable(mac);
8362 }
8363
8364 static void
8365 bwn_phy_reset(struct bwn_mac *mac)
8366 {
8367         struct bwn_softc *sc = mac->mac_sc;
8368
8369         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8370             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8371              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8372         DELAY(1000);
8373         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8374             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8375             BWN_TGSLOW_PHYRESET);
8376         DELAY(1000);
8377 }
8378
8379 static int
8380 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8381 {
8382         struct bwn_vap *bvp = BWN_VAP(vap);
8383         struct ieee80211com *ic= vap->iv_ic;
8384         struct ifnet *ifp = ic->ic_ifp;
8385         enum ieee80211_state ostate = vap->iv_state;
8386         struct bwn_softc *sc = ifp->if_softc;
8387         struct bwn_mac *mac = sc->sc_curmac;
8388         int error;
8389
8390         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8391             ieee80211_state_name[vap->iv_state],
8392             ieee80211_state_name[nstate]);
8393
8394         error = bvp->bv_newstate(vap, nstate, arg);
8395         if (error != 0)
8396                 return (error);
8397
8398         BWN_LOCK(sc);
8399
8400         bwn_led_newstate(mac, nstate);
8401
8402         /*
8403          * Clear the BSSID when we stop a STA
8404          */
8405         if (vap->iv_opmode == IEEE80211_M_STA) {
8406                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8407                         /*
8408                          * Clear out the BSSID.  If we reassociate to
8409                          * the same AP, this will reinialize things
8410                          * correctly...
8411                          */
8412                         if (ic->ic_opmode == IEEE80211_M_STA &&
8413                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8414                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8415                                 bwn_set_macaddr(mac);
8416                         }
8417                 }
8418         }
8419
8420         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8421             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8422                 /* XXX nothing to do? */
8423         } else if (nstate == IEEE80211_S_RUN) {
8424                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8425                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8426                 bwn_set_opmode(mac);
8427                 bwn_set_pretbtt(mac);
8428                 bwn_spu_setdelay(mac, 0);
8429                 bwn_set_macaddr(mac);
8430         }
8431
8432         BWN_UNLOCK(sc);
8433
8434         return (error);
8435 }
8436
8437 static void
8438 bwn_set_pretbtt(struct bwn_mac *mac)
8439 {
8440         struct bwn_softc *sc = mac->mac_sc;
8441         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8442         uint16_t pretbtt;
8443
8444         if (ic->ic_opmode == IEEE80211_M_IBSS)
8445                 pretbtt = 2;
8446         else
8447                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8448         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8449         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8450 }
8451
8452 static int
8453 bwn_intr(void *arg)
8454 {
8455         struct bwn_mac *mac = arg;
8456         struct bwn_softc *sc = mac->mac_sc;
8457         uint32_t reason;
8458
8459         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8460             (sc->sc_flags & BWN_FLAG_INVALID))
8461                 return (FILTER_STRAY);
8462
8463         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8464         if (reason == 0xffffffff)       /* shared IRQ */
8465                 return (FILTER_STRAY);
8466         reason &= mac->mac_intr_mask;
8467         if (reason == 0)
8468                 return (FILTER_HANDLED);
8469
8470         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8471         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8472         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8473         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8474         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8475         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8476         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8477         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8478         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8479         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8480         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8481
8482         /* Disable interrupts. */
8483         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8484
8485         mac->mac_reason_intr = reason;
8486
8487         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8488         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8489
8490         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8491         return (FILTER_HANDLED);
8492 }
8493
8494 static void
8495 bwn_intrtask(void *arg, int npending)
8496 {
8497         struct bwn_mac *mac = arg;
8498         struct bwn_softc *sc = mac->mac_sc;
8499         struct ifnet *ifp = sc->sc_ifp;
8500         uint32_t merged = 0;
8501         int i, tx = 0, rx = 0;
8502
8503         BWN_LOCK(sc);
8504         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8505             (sc->sc_flags & BWN_FLAG_INVALID)) {
8506                 BWN_UNLOCK(sc);
8507                 return;
8508         }
8509
8510         for (i = 0; i < N(mac->mac_reason); i++)
8511                 merged |= mac->mac_reason[i];
8512
8513         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8514                 device_printf(sc->sc_dev, "MAC trans error\n");
8515
8516         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8517                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8518                 mac->mac_phy.txerrors--;
8519                 if (mac->mac_phy.txerrors == 0) {
8520                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8521                         bwn_restart(mac, "PHY TX errors");
8522                 }
8523         }
8524
8525         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8526                 if (merged & BWN_DMAINTR_FATALMASK) {
8527                         device_printf(sc->sc_dev,
8528                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8529                             mac->mac_reason[0], mac->mac_reason[1],
8530                             mac->mac_reason[2], mac->mac_reason[3],
8531                             mac->mac_reason[4], mac->mac_reason[5]);
8532                         bwn_restart(mac, "DMA error");
8533                         BWN_UNLOCK(sc);
8534                         return;
8535                 }
8536                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8537                         device_printf(sc->sc_dev,
8538                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8539                             mac->mac_reason[0], mac->mac_reason[1],
8540                             mac->mac_reason[2], mac->mac_reason[3],
8541                             mac->mac_reason[4], mac->mac_reason[5]);
8542                 }
8543         }
8544
8545         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8546                 bwn_intr_ucode_debug(mac);
8547         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8548                 bwn_intr_tbtt_indication(mac);
8549         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8550                 bwn_intr_atim_end(mac);
8551         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8552                 bwn_intr_beacon(mac);
8553         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8554                 bwn_intr_pmq(mac);
8555         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8556                 bwn_intr_noise(mac);
8557
8558         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8559                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8560                         bwn_dma_rx(mac->mac_method.dma.rx);
8561                         rx = 1;
8562                 }
8563         } else
8564                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8565
8566         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8567         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8568         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8569         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8570         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8571
8572         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8573                 bwn_intr_txeof(mac);
8574                 tx = 1;
8575         }
8576
8577         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8578
8579         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8580                 int evt = BWN_LED_EVENT_NONE;
8581
8582                 if (tx && rx) {
8583                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8584                                 evt = BWN_LED_EVENT_RX;
8585                         else
8586                                 evt = BWN_LED_EVENT_TX;
8587                 } else if (tx) {
8588                         evt = BWN_LED_EVENT_TX;
8589                 } else if (rx) {
8590                         evt = BWN_LED_EVENT_RX;
8591                 } else if (rx == 0) {
8592                         evt = BWN_LED_EVENT_POLL;
8593                 }
8594
8595                 if (evt != BWN_LED_EVENT_NONE)
8596                         bwn_led_event(mac, evt);
8597        }
8598
8599         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8600                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8601                         bwn_start_locked(ifp);
8602         }
8603
8604         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8605         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8606
8607         BWN_UNLOCK(sc);
8608 }
8609
8610 static void
8611 bwn_restart(struct bwn_mac *mac, const char *msg)
8612 {
8613         struct bwn_softc *sc = mac->mac_sc;
8614         struct ifnet *ifp = sc->sc_ifp;
8615         struct ieee80211com *ic = ifp->if_l2com;
8616
8617         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8618                 return;
8619
8620         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8621         ieee80211_runtask(ic, &mac->mac_hwreset);
8622 }
8623
8624 static void
8625 bwn_intr_ucode_debug(struct bwn_mac *mac)
8626 {
8627         struct bwn_softc *sc = mac->mac_sc;
8628         uint16_t reason;
8629
8630         if (mac->mac_fw.opensource == 0)
8631                 return;
8632
8633         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8634         switch (reason) {
8635         case BWN_DEBUGINTR_PANIC:
8636                 bwn_handle_fwpanic(mac);
8637                 break;
8638         case BWN_DEBUGINTR_DUMP_SHM:
8639                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8640                 break;
8641         case BWN_DEBUGINTR_DUMP_REGS:
8642                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8643                 break;
8644         case BWN_DEBUGINTR_MARKER:
8645                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8646                 break;
8647         default:
8648                 device_printf(sc->sc_dev,
8649                     "ucode debug unknown reason: %#x\n", reason);
8650         }
8651
8652         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8653             BWN_DEBUGINTR_ACK);
8654 }
8655
8656 static void
8657 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8658 {
8659         struct bwn_softc *sc = mac->mac_sc;
8660         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8661
8662         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8663                 bwn_psctl(mac, 0);
8664         if (ic->ic_opmode == IEEE80211_M_IBSS)
8665                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8666 }
8667
8668 static void
8669 bwn_intr_atim_end(struct bwn_mac *mac)
8670 {
8671
8672         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8673                 BWN_WRITE_4(mac, BWN_MACCMD,
8674                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8675                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8676         }
8677 }
8678
8679 static void
8680 bwn_intr_beacon(struct bwn_mac *mac)
8681 {
8682         struct bwn_softc *sc = mac->mac_sc;
8683         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8684         uint32_t cmd, beacon0, beacon1;
8685
8686         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8687             ic->ic_opmode == IEEE80211_M_MBSS)
8688                 return;
8689
8690         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8691
8692         cmd = BWN_READ_4(mac, BWN_MACCMD);
8693         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8694         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8695
8696         if (beacon0 && beacon1) {
8697                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8698                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8699                 return;
8700         }
8701
8702         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8703                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8704                 bwn_load_beacon0(mac);
8705                 bwn_load_beacon1(mac);
8706                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8707                 cmd |= BWN_MACCMD_BEACON0_VALID;
8708                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8709         } else {
8710                 if (!beacon0) {
8711                         bwn_load_beacon0(mac);
8712                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8713                         cmd |= BWN_MACCMD_BEACON0_VALID;
8714                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8715                 } else if (!beacon1) {
8716                         bwn_load_beacon1(mac);
8717                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8718                         cmd |= BWN_MACCMD_BEACON1_VALID;
8719                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8720                 }
8721         }
8722 }
8723
8724 static void
8725 bwn_intr_pmq(struct bwn_mac *mac)
8726 {
8727         uint32_t tmp;
8728
8729         while (1) {
8730                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8731                 if (!(tmp & 0x00000008))
8732                         break;
8733         }
8734         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8735 }
8736
8737 static void
8738 bwn_intr_noise(struct bwn_mac *mac)
8739 {
8740         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8741         uint16_t tmp;
8742         uint8_t noise[4];
8743         uint8_t i, j;
8744         int32_t average;
8745
8746         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8747                 return;
8748
8749         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8750         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8751         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8752             noise[3] == 0x7f)
8753                 goto new;
8754
8755         KASSERT(mac->mac_noise.noi_nsamples < 8,
8756             ("%s:%d: fail", __func__, __LINE__));
8757         i = mac->mac_noise.noi_nsamples;
8758         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8759         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8760         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8761         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8762         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8763         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8764         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8765         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8766         mac->mac_noise.noi_nsamples++;
8767         if (mac->mac_noise.noi_nsamples == 8) {
8768                 average = 0;
8769                 for (i = 0; i < 8; i++) {
8770                         for (j = 0; j < 4; j++)
8771                                 average += mac->mac_noise.noi_samples[i][j];
8772                 }
8773                 average = (((average / 32) * 125) + 64) / 128;
8774                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8775                 if (tmp >= 8)
8776                         average += 2;
8777                 else
8778                         average -= 25;
8779                 average -= (tmp == 8) ? 72 : 48;
8780
8781                 mac->mac_stats.link_noise = average;
8782                 mac->mac_noise.noi_running = 0;
8783                 return;
8784         }
8785 new:
8786         bwn_noise_gensample(mac);
8787 }
8788
8789 static int
8790 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8791 {
8792         struct bwn_mac *mac = prq->prq_mac;
8793         struct bwn_softc *sc = mac->mac_sc;
8794         unsigned int i;
8795
8796         BWN_ASSERT_LOCKED(sc);
8797
8798         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8799                 return (0);
8800
8801         for (i = 0; i < 5000; i++) {
8802                 if (bwn_pio_rxeof(prq) == 0)
8803                         break;
8804         }
8805         if (i >= 5000)
8806                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8807         return ((i > 0) ? 1 : 0);
8808 }
8809
8810 static void
8811 bwn_dma_rx(struct bwn_dma_ring *dr)
8812 {
8813         int slot, curslot;
8814
8815         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8816         curslot = dr->get_curslot(dr);
8817         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8818             ("%s:%d: fail", __func__, __LINE__));
8819
8820         slot = dr->dr_curslot;
8821         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8822                 bwn_dma_rxeof(dr, &slot);
8823
8824         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8825             BUS_DMASYNC_PREWRITE);
8826
8827         dr->set_curslot(dr, slot);
8828         dr->dr_curslot = slot;
8829 }
8830
8831 static void
8832 bwn_intr_txeof(struct bwn_mac *mac)
8833 {
8834         struct bwn_txstatus stat;
8835         uint32_t stat0, stat1;
8836         uint16_t tmp;
8837
8838         BWN_ASSERT_LOCKED(mac->mac_sc);
8839
8840         while (1) {
8841                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8842                 if (!(stat0 & 0x00000001))
8843                         break;
8844                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8845
8846                 stat.cookie = (stat0 >> 16);
8847                 stat.seq = (stat1 & 0x0000ffff);
8848                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8849                 tmp = (stat0 & 0x0000ffff);
8850                 stat.framecnt = ((tmp & 0xf000) >> 12);
8851                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8852                 stat.sreason = ((tmp & 0x001c) >> 2);
8853                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8854                 stat.im = (tmp & 0x0040) ? 1 : 0;
8855                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8856                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8857
8858                 bwn_handle_txeof(mac, &stat);
8859         }
8860 }
8861
8862 static void
8863 bwn_hwreset(void *arg, int npending)
8864 {
8865         struct bwn_mac *mac = arg;
8866         struct bwn_softc *sc = mac->mac_sc;
8867         int error = 0;
8868         int prev_status;
8869
8870         BWN_LOCK(sc);
8871
8872         prev_status = mac->mac_status;
8873         if (prev_status >= BWN_MAC_STATUS_STARTED)
8874                 bwn_core_stop(mac);
8875         if (prev_status >= BWN_MAC_STATUS_INITED)
8876                 bwn_core_exit(mac);
8877
8878         if (prev_status >= BWN_MAC_STATUS_INITED) {
8879                 error = bwn_core_init(mac);
8880                 if (error)
8881                         goto out;
8882         }
8883         if (prev_status >= BWN_MAC_STATUS_STARTED)
8884                 bwn_core_start(mac);
8885 out:
8886         if (error) {
8887                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8888                 sc->sc_curmac = NULL;
8889         }
8890         BWN_UNLOCK(sc);
8891 }
8892
8893 static void
8894 bwn_handle_fwpanic(struct bwn_mac *mac)
8895 {
8896         struct bwn_softc *sc = mac->mac_sc;
8897         uint16_t reason;
8898
8899         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8900         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8901
8902         if (reason == BWN_FWPANIC_RESTART)
8903                 bwn_restart(mac, "ucode panic");
8904 }
8905
8906 static void
8907 bwn_load_beacon0(struct bwn_mac *mac)
8908 {
8909
8910         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8911 }
8912
8913 static void
8914 bwn_load_beacon1(struct bwn_mac *mac)
8915 {
8916
8917         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8918 }
8919
8920 static uint32_t
8921 bwn_jssi_read(struct bwn_mac *mac)
8922 {
8923         uint32_t val = 0;
8924
8925         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8926         val <<= 16;
8927         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8928
8929         return (val);
8930 }
8931
8932 static void
8933 bwn_noise_gensample(struct bwn_mac *mac)
8934 {
8935         uint32_t jssi = 0x7f7f7f7f;
8936
8937         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8938         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8939         BWN_WRITE_4(mac, BWN_MACCMD,
8940             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8941 }
8942
8943 static int
8944 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8945 {
8946         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8947
8948         return (dr->dr_numslots - dr->dr_usedslot);
8949 }
8950
8951 static int
8952 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8953 {
8954         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8955
8956         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8957             ("%s:%d: fail", __func__, __LINE__));
8958         if (slot == dr->dr_numslots - 1)
8959                 return (0);
8960         return (slot + 1);
8961 }
8962
8963 static void
8964 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8965 {
8966         struct bwn_mac *mac = dr->dr_mac;
8967         struct bwn_softc *sc = mac->mac_sc;
8968         struct bwn_dma *dma = &mac->mac_method.dma;
8969         struct bwn_dmadesc_generic *desc;
8970         struct bwn_dmadesc_meta *meta;
8971         struct bwn_rxhdr4 *rxhdr;
8972         struct ifnet *ifp = sc->sc_ifp;
8973         struct mbuf *m;
8974         uint32_t macstat;
8975         int32_t tmp;
8976         int cnt = 0;
8977         uint16_t len;
8978
8979         dr->getdesc(dr, *slot, &desc, &meta);
8980
8981         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8982         m = meta->mt_m;
8983
8984         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8985                 ifp->if_ierrors++;
8986                 return;
8987         }
8988
8989         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8990         len = le16toh(rxhdr->frame_len);
8991         if (len <= 0) {
8992                 ifp->if_ierrors++;
8993                 return;
8994         }
8995         if (bwn_dma_check_redzone(dr, m)) {
8996                 device_printf(sc->sc_dev, "redzone error.\n");
8997                 bwn_dma_set_redzone(dr, m);
8998                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8999                     BUS_DMASYNC_PREWRITE);
9000                 return;
9001         }
9002         if (len > dr->dr_rx_bufsize) {
9003                 tmp = len;
9004                 while (1) {
9005                         dr->getdesc(dr, *slot, &desc, &meta);
9006                         bwn_dma_set_redzone(dr, meta->mt_m);
9007                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9008                             BUS_DMASYNC_PREWRITE);
9009                         *slot = bwn_dma_nextslot(dr, *slot);
9010                         cnt++;
9011                         tmp -= dr->dr_rx_bufsize;
9012                         if (tmp <= 0)
9013                                 break;
9014                 }
9015                 device_printf(sc->sc_dev, "too small buffer "
9016                        "(len %u buffer %u dropped %d)\n",
9017                        len, dr->dr_rx_bufsize, cnt);
9018                 return;
9019         }
9020         macstat = le32toh(rxhdr->mac_status);
9021         if (macstat & BWN_RX_MAC_FCSERR) {
9022                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9023                         device_printf(sc->sc_dev, "RX drop\n");
9024                         return;
9025                 }
9026         }
9027
9028         m->m_pkthdr.rcvif = ifp;
9029         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
9030         m_adj(m, dr->dr_frameoffset);
9031
9032         bwn_rxeof(dr->dr_mac, m, rxhdr);
9033 }
9034
9035 static void
9036 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
9037 {
9038         struct bwn_dma_ring *dr;
9039         struct bwn_dmadesc_generic *desc;
9040         struct bwn_dmadesc_meta *meta;
9041         struct bwn_node *bn;
9042         struct bwn_pio_txqueue *tq;
9043         struct bwn_pio_txpkt *tp = NULL;
9044         struct bwn_softc *sc = mac->mac_sc;
9045         struct bwn_stats *stats = &mac->mac_stats;
9046         struct ieee80211_node *ni;
9047         int slot;
9048
9049         BWN_ASSERT_LOCKED(mac->mac_sc);
9050
9051         if (status->im)
9052                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9053         if (status->ampdu)
9054                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9055         if (status->rtscnt) {
9056                 if (status->rtscnt == 0xf)
9057                         stats->rtsfail++;
9058                 else
9059                         stats->rts++;
9060         }
9061
9062         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9063                 if (status->ack) {
9064                         dr = bwn_dma_parse_cookie(mac, status,
9065                             status->cookie, &slot);
9066                         if (dr == NULL) {
9067                                 device_printf(sc->sc_dev,
9068                                     "failed to parse cookie\n");
9069                                 return;
9070                         }
9071                         while (1) {
9072                                 dr->getdesc(dr, slot, &desc, &meta);
9073                                 if (meta->mt_islast) {
9074                                         ni = meta->mt_ni;
9075                                         bn = (struct bwn_node *)ni;
9076                                         ieee80211_amrr_tx_complete(&bn->bn_amn,
9077                                             status->ack, 0);
9078                                         break;
9079                                 }
9080                                 slot = bwn_dma_nextslot(dr, slot);
9081                         }
9082                 }
9083                 bwn_dma_handle_txeof(mac, status);
9084         } else {
9085                 if (status->ack) {
9086                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9087                         if (tq == NULL) {
9088                                 device_printf(sc->sc_dev,
9089                                     "failed to parse cookie\n");
9090                                 return;
9091                         }
9092                         ni = tp->tp_ni;
9093                         bn = (struct bwn_node *)ni;
9094                         ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
9095                 }
9096                 bwn_pio_handle_txeof(mac, status);
9097         }
9098
9099         bwn_phy_txpower_check(mac, 0);
9100 }
9101
9102 static uint8_t
9103 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9104 {
9105         struct bwn_mac *mac = prq->prq_mac;
9106         struct bwn_softc *sc = mac->mac_sc;
9107         struct bwn_rxhdr4 rxhdr;
9108         struct ifnet *ifp = sc->sc_ifp;
9109         struct mbuf *m;
9110         uint32_t ctl32, macstat, v32;
9111         unsigned int i, padding;
9112         uint16_t ctl16, len, v16;
9113         unsigned char *mp;
9114         char *data;
9115
9116         memset(&rxhdr, 0, sizeof(rxhdr));
9117
9118         if (prq->prq_rev >= 8) {
9119                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9120                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9121                         return (0);
9122                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9123                     BWN_PIO8_RXCTL_FRAMEREADY);
9124                 for (i = 0; i < 10; i++) {
9125                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9126                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9127                                 goto ready;
9128                         DELAY(10);
9129                 }
9130         } else {
9131                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9132                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9133                         return (0);
9134                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9135                     BWN_PIO_RXCTL_FRAMEREADY);
9136                 for (i = 0; i < 10; i++) {
9137                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9138                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9139                                 goto ready;
9140                         DELAY(10);
9141                 }
9142         }
9143         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9144         return (1);
9145 ready:
9146         if (prq->prq_rev >= 8)
9147                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9148                     prq->prq_base + BWN_PIO8_RXDATA);
9149         else
9150                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9151                     prq->prq_base + BWN_PIO_RXDATA);
9152         len = le16toh(rxhdr.frame_len);
9153         if (len > 0x700) {
9154                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9155                 goto error;
9156         }
9157         if (len == 0) {
9158                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9159                 goto error;
9160         }
9161
9162         macstat = le32toh(rxhdr.mac_status);
9163         if (macstat & BWN_RX_MAC_FCSERR) {
9164                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9165                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9166                         goto error;
9167                 }
9168         }
9169
9170         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9171         KASSERT(len + padding <= MCLBYTES, ("too big..\n"));
9172         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9173         if (m == NULL) {
9174                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9175                 goto error;
9176         }
9177         mp = mtod(m, unsigned char *);
9178         if (prq->prq_rev >= 8) {
9179                 siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3),
9180                     prq->prq_base + BWN_PIO8_RXDATA);
9181                 if (len & 3) {
9182                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9183                         data = &(mp[len + padding - 1]);
9184                         switch (len & 3) {
9185                         case 3:
9186                                 *data = (v32 >> 16);
9187                                 data--;
9188                         case 2:
9189                                 *data = (v32 >> 8);
9190                                 data--;
9191                         case 1:
9192                                 *data = v32;
9193                         }
9194                 }
9195         } else {
9196                 siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1),
9197                     prq->prq_base + BWN_PIO_RXDATA);
9198                 if (len & 1) {
9199                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9200                         mp[len + padding - 1] = v16;
9201                 }
9202         }
9203
9204         m->m_pkthdr.rcvif = ifp;
9205         m->m_len = m->m_pkthdr.len = len + padding;
9206
9207         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9208
9209         return (1);
9210 error:
9211         if (prq->prq_rev >= 8)
9212                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9213                     BWN_PIO8_RXCTL_DATAREADY);
9214         else
9215                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9216         return (1);
9217 }
9218
9219 static int
9220 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9221     struct bwn_dmadesc_meta *meta, int init)
9222 {
9223         struct bwn_mac *mac = dr->dr_mac;
9224         struct bwn_dma *dma = &mac->mac_method.dma;
9225         struct bwn_rxhdr4 *hdr;
9226         bus_dmamap_t map;
9227         bus_addr_t paddr;
9228         struct mbuf *m;
9229         int error;
9230
9231         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9232         if (m == NULL) {
9233                 error = ENOBUFS;
9234
9235                 /*
9236                  * If the NIC is up and running, we need to:
9237                  * - Clear RX buffer's header.
9238                  * - Restore RX descriptor settings.
9239                  */
9240                 if (init)
9241                         return (error);
9242                 else
9243                         goto back;
9244         }
9245         m->m_len = m->m_pkthdr.len = MCLBYTES;
9246
9247         bwn_dma_set_redzone(dr, m);
9248
9249         /*
9250          * Try to load RX buf into temporary DMA map
9251          */
9252         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9253             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9254         if (error) {
9255                 m_freem(m);
9256
9257                 /*
9258                  * See the comment above
9259                  */
9260                 if (init)
9261                         return (error);
9262                 else
9263                         goto back;
9264         }
9265
9266         if (!init)
9267                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9268         meta->mt_m = m;
9269         meta->mt_paddr = paddr;
9270
9271         /*
9272          * Swap RX buf's DMA map with the loaded temporary one
9273          */
9274         map = meta->mt_dmap;
9275         meta->mt_dmap = dr->dr_spare_dmap;
9276         dr->dr_spare_dmap = map;
9277
9278 back:
9279         /*
9280          * Clear RX buf header
9281          */
9282         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9283         bzero(hdr, sizeof(*hdr));
9284         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9285             BUS_DMASYNC_PREWRITE);
9286
9287         /*
9288          * Setup RX buf descriptor
9289          */
9290         dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9291             sizeof(*hdr), 0, 0, 0);
9292         return (error);
9293 }
9294
9295 static void
9296 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9297                  bus_size_t mapsz __unused, int error)
9298 {
9299
9300         if (!error) {
9301                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9302                 *((bus_addr_t *)arg) = seg->ds_addr;
9303         }
9304 }
9305
9306 static int
9307 bwn_hwrate2ieeerate(int rate)
9308 {
9309
9310         switch (rate) {
9311         case BWN_CCK_RATE_1MB:
9312                 return (2);
9313         case BWN_CCK_RATE_2MB:
9314                 return (4);
9315         case BWN_CCK_RATE_5MB:
9316                 return (11);
9317         case BWN_CCK_RATE_11MB:
9318                 return (22);
9319         case BWN_OFDM_RATE_6MB:
9320                 return (12);
9321         case BWN_OFDM_RATE_9MB:
9322                 return (18);
9323         case BWN_OFDM_RATE_12MB:
9324                 return (24);
9325         case BWN_OFDM_RATE_18MB:
9326                 return (36);
9327         case BWN_OFDM_RATE_24MB:
9328                 return (48);
9329         case BWN_OFDM_RATE_36MB:
9330                 return (72);
9331         case BWN_OFDM_RATE_48MB:
9332                 return (96);
9333         case BWN_OFDM_RATE_54MB:
9334                 return (108);
9335         default:
9336                 printf("Ooops\n");
9337                 return (0);
9338         }
9339 }
9340
9341 static void
9342 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9343 {
9344         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9345         struct bwn_plcp6 *plcp;
9346         struct bwn_softc *sc = mac->mac_sc;
9347         struct ieee80211_frame_min *wh;
9348         struct ieee80211_node *ni;
9349         struct ifnet *ifp = sc->sc_ifp;
9350         struct ieee80211com *ic = ifp->if_l2com;
9351         uint32_t macstat;
9352         int padding, rate, rssi = 0, noise = 0, type;
9353         uint16_t phytype, phystat0, phystat3, chanstat;
9354         unsigned char *mp = mtod(m, unsigned char *);
9355         static int rx_mac_dec_rpt = 0;
9356
9357         BWN_ASSERT_LOCKED(sc);
9358
9359         phystat0 = le16toh(rxhdr->phy_status0);
9360         phystat3 = le16toh(rxhdr->phy_status3);
9361         macstat = le32toh(rxhdr->mac_status);
9362         chanstat = le16toh(rxhdr->channel);
9363         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9364
9365         if (macstat & BWN_RX_MAC_FCSERR)
9366                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9367         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9368                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9369         if (macstat & BWN_RX_MAC_DECERR)
9370                 goto drop;
9371
9372         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9373         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9374                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9375                     m->m_pkthdr.len);
9376                 goto drop;
9377         }
9378         plcp = (struct bwn_plcp6 *)(mp + padding);
9379         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9380         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9381                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9382                     m->m_pkthdr.len);
9383                 goto drop;
9384         }
9385         wh = mtod(m, struct ieee80211_frame_min *);
9386
9387         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9388                 device_printf(sc->sc_dev,
9389                     "RX decryption attempted (old %d keyidx %#x)\n",
9390                     BWN_ISOLDFMT(mac),
9391                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9392
9393         /* XXX calculating RSSI & noise & antenna */
9394
9395         if (phystat0 & BWN_RX_PHYST0_OFDM)
9396                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9397                     phytype == BWN_PHYTYPE_A);
9398         else
9399                 rate = bwn_plcp_get_cckrate(mac, plcp);
9400         if (rate == -1) {
9401                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9402                         goto drop;
9403         }
9404         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9405
9406         /* RX radio tap */
9407         if (ieee80211_radiotap_active(ic))
9408                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9409         m_adj(m, -IEEE80211_CRC_LEN);
9410
9411         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9412         noise = mac->mac_stats.link_noise;
9413
9414         BWN_UNLOCK(sc);
9415
9416         ni = ieee80211_find_rxnode(ic, wh);
9417         if (ni != NULL) {
9418                 type = ieee80211_input(ni, m, rssi, noise);
9419                 ieee80211_free_node(ni);
9420         } else
9421                 type = ieee80211_input_all(ic, m, rssi, noise);
9422
9423         BWN_LOCK(sc);
9424         return;
9425 drop:
9426         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9427 }
9428
9429 static void
9430 bwn_dma_handle_txeof(struct bwn_mac *mac,
9431     const struct bwn_txstatus *status)
9432 {
9433         struct bwn_dma *dma = &mac->mac_method.dma;
9434         struct bwn_dma_ring *dr;
9435         struct bwn_dmadesc_generic *desc;
9436         struct bwn_dmadesc_meta *meta;
9437         struct bwn_softc *sc = mac->mac_sc;
9438         struct ieee80211_node *ni;
9439         struct ifnet *ifp = sc->sc_ifp;
9440         struct mbuf *m;
9441         int slot;
9442
9443         BWN_ASSERT_LOCKED(sc);
9444
9445         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9446         if (dr == NULL) {
9447                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9448                 return;
9449         }
9450         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9451
9452         while (1) {
9453                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9454                     ("%s:%d: fail", __func__, __LINE__));
9455                 dr->getdesc(dr, slot, &desc, &meta);
9456
9457                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9458                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9459                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9460                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9461
9462                 if (meta->mt_islast) {
9463                         KASSERT(meta->mt_m != NULL,
9464                             ("%s:%d: fail", __func__, __LINE__));
9465
9466                         ni = meta->mt_ni;
9467                         m = meta->mt_m;
9468                         if (ni != NULL) {
9469                                 /*
9470                                  * Do any tx complete callback. Note this must
9471                                  * be done before releasing the node reference.
9472                                  */
9473                                 if (m->m_flags & M_TXCB)
9474                                         ieee80211_process_callback(ni, m, 0);
9475                                 ieee80211_free_node(ni);
9476                                 meta->mt_ni = NULL;
9477                         }
9478                         m_freem(m);
9479                         meta->mt_m = NULL;
9480                 } else {
9481                         KASSERT(meta->mt_m == NULL,
9482                             ("%s:%d: fail", __func__, __LINE__));
9483                 }
9484
9485                 dr->dr_usedslot--;
9486                 if (meta->mt_islast) {
9487                         ifp->if_opackets++;
9488                         break;
9489                 }
9490                 slot = bwn_dma_nextslot(dr, slot);
9491         }
9492         sc->sc_watchdog_timer = 0;
9493         if (dr->dr_stop) {
9494                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9495                     ("%s:%d: fail", __func__, __LINE__));
9496                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9497                 dr->dr_stop = 0;
9498         }
9499 }
9500
9501 static void
9502 bwn_pio_handle_txeof(struct bwn_mac *mac,
9503     const struct bwn_txstatus *status)
9504 {
9505         struct bwn_pio_txqueue *tq;
9506         struct bwn_pio_txpkt *tp = NULL;
9507         struct bwn_softc *sc = mac->mac_sc;
9508         struct ifnet *ifp = sc->sc_ifp;
9509
9510         BWN_ASSERT_LOCKED(sc);
9511
9512         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9513         if (tq == NULL)
9514                 return;
9515
9516         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9517         tq->tq_free++;
9518
9519         if (tp->tp_ni != NULL) {
9520                 /*
9521                  * Do any tx complete callback.  Note this must
9522                  * be done before releasing the node reference.
9523                  */
9524                 if (tp->tp_m->m_flags & M_TXCB)
9525                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9526                 ieee80211_free_node(tp->tp_ni);
9527                 tp->tp_ni = NULL;
9528         }
9529         m_freem(tp->tp_m);
9530         tp->tp_m = NULL;
9531         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9532
9533         ifp->if_opackets++;
9534
9535         sc->sc_watchdog_timer = 0;
9536         if (tq->tq_stop) {
9537                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9538                 tq->tq_stop = 0;
9539         }
9540 }
9541
9542 static void
9543 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9544 {
9545         struct bwn_softc *sc = mac->mac_sc;
9546         struct bwn_phy *phy = &mac->mac_phy;
9547         struct ifnet *ifp = sc->sc_ifp;
9548         struct ieee80211com *ic = ifp->if_l2com;
9549         unsigned long now;
9550         int result;
9551
9552         BWN_GETTIME(now);
9553
9554         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9555                 return;
9556         phy->nexttime = now + 2 * 1000;
9557
9558         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9559             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9560                 return;
9561
9562         if (phy->recalc_txpwr != NULL) {
9563                 result = phy->recalc_txpwr(mac,
9564                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9565                 if (result == BWN_TXPWR_RES_DONE)
9566                         return;
9567                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9568                     ("%s: fail", __func__));
9569                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9570
9571                 ieee80211_runtask(ic, &mac->mac_txpower);
9572         }
9573 }
9574
9575 static uint16_t
9576 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9577 {
9578
9579         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9580 }
9581
9582 static uint32_t
9583 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9584 {
9585
9586         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9587 }
9588
9589 static void
9590 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9591 {
9592
9593         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9594 }
9595
9596 static void
9597 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9598 {
9599
9600         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9601 }
9602
9603 static int
9604 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9605 {
9606
9607         switch (rate) {
9608         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9609         case 12:
9610                 return (BWN_OFDM_RATE_6MB);
9611         case 18:
9612                 return (BWN_OFDM_RATE_9MB);
9613         case 24:
9614                 return (BWN_OFDM_RATE_12MB);
9615         case 36:
9616                 return (BWN_OFDM_RATE_18MB);
9617         case 48:
9618                 return (BWN_OFDM_RATE_24MB);
9619         case 72:
9620                 return (BWN_OFDM_RATE_36MB);
9621         case 96:
9622                 return (BWN_OFDM_RATE_48MB);
9623         case 108:
9624                 return (BWN_OFDM_RATE_54MB);
9625         /* CCK rates (NB: not IEEE std, device-specific) */
9626         case 2:
9627                 return (BWN_CCK_RATE_1MB);
9628         case 4:
9629                 return (BWN_CCK_RATE_2MB);
9630         case 11:
9631                 return (BWN_CCK_RATE_5MB);
9632         case 22:
9633                 return (BWN_CCK_RATE_11MB);
9634         }
9635
9636         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9637         return (BWN_CCK_RATE_1MB);
9638 }
9639
9640 static int
9641 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9642     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9643 {
9644         const struct bwn_phy *phy = &mac->mac_phy;
9645         struct bwn_softc *sc = mac->mac_sc;
9646         struct ieee80211_frame *wh;
9647         struct ieee80211_frame *protwh;
9648         struct ieee80211_frame_cts *cts;
9649         struct ieee80211_frame_rts *rts;
9650         const struct ieee80211_txparam *tp;
9651         struct ieee80211vap *vap = ni->ni_vap;
9652         struct ifnet *ifp = sc->sc_ifp;
9653         struct ieee80211com *ic = ifp->if_l2com;
9654         struct mbuf *mprot;
9655         unsigned int len;
9656         uint32_t macctl = 0;
9657         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9658         uint16_t phyctl = 0;
9659         uint8_t rate, rate_fb;
9660
9661         wh = mtod(m, struct ieee80211_frame *);
9662         memset(txhdr, 0, sizeof(*txhdr));
9663
9664         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9665         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9666         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9667
9668         /*
9669          * Find TX rate
9670          */
9671         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9672         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9673                 rate = rate_fb = tp->mgmtrate;
9674         else if (ismcast)
9675                 rate = rate_fb = tp->mcastrate;
9676         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9677                 rate = rate_fb = tp->ucastrate;
9678         else {
9679                 rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
9680                 rate = ni->ni_txrate;
9681
9682                 if (rix > 0)
9683                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9684                             IEEE80211_RATE_VAL;
9685                 else
9686                         rate_fb = rate;
9687         }
9688
9689         sc->sc_tx_rate = rate;
9690
9691         rate = bwn_ieeerate2hwrate(sc, rate);
9692         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9693
9694         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9695             bwn_plcp_getcck(rate);
9696         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9697         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9698
9699         if ((rate_fb == rate) ||
9700             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9701             (*(u_int16_t *)wh->i_dur == htole16(0)))
9702                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9703         else
9704                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9705                     m->m_pkthdr.len, rate, isshort);
9706
9707         /* XXX TX encryption */
9708         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9709             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9710             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9711             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9712         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9713             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9714
9715         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9716             BWN_TX_EFT_FB_CCK;
9717         txhdr->chan = phy->chan;
9718         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9719             BWN_TX_PHY_ENC_CCK;
9720         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9721              rate == BWN_CCK_RATE_11MB))
9722                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9723
9724         /* XXX TX antenna selection */
9725
9726         switch (bwn_antenna_sanitize(mac, 0)) {
9727         case 0:
9728                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9729                 break;
9730         case 1:
9731                 phyctl |= BWN_TX_PHY_ANT0;
9732                 break;
9733         case 2:
9734                 phyctl |= BWN_TX_PHY_ANT1;
9735                 break;
9736         case 3:
9737                 phyctl |= BWN_TX_PHY_ANT2;
9738                 break;
9739         case 4:
9740                 phyctl |= BWN_TX_PHY_ANT3;
9741                 break;
9742         default:
9743                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9744         }
9745
9746         if (!ismcast)
9747                 macctl |= BWN_TX_MAC_ACK;
9748
9749         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9750         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9751             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9752                 macctl |= BWN_TX_MAC_LONGFRAME;
9753
9754         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9755                 /* XXX RTS rate is always 1MB??? */
9756                 rts_rate = BWN_CCK_RATE_1MB;
9757                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9758
9759                 protdur = ieee80211_compute_duration(ic->ic_rt,
9760                     m->m_pkthdr.len, rate, isshort) +
9761                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9762
9763                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9764                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9765                             (txhdr->body.old.rts_frame) :
9766                             (txhdr->body.new.rts_frame));
9767                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9768                             protdur);
9769                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9770                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9771                             mprot->m_pkthdr.len);
9772                         m_freem(mprot);
9773                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9774                         len = sizeof(struct ieee80211_frame_cts);
9775                 } else {
9776                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9777                             (txhdr->body.old.rts_frame) :
9778                             (txhdr->body.new.rts_frame));
9779                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9780                             isshort);
9781                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9782                             wh->i_addr2, protdur);
9783                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9784                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9785                             mprot->m_pkthdr.len);
9786                         m_freem(mprot);
9787                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9788                         len = sizeof(struct ieee80211_frame_rts);
9789                 }
9790                 len += IEEE80211_CRC_LEN;
9791                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9792                     &txhdr->body.old.rts_plcp :
9793                     &txhdr->body.new.rts_plcp), len, rts_rate);
9794                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9795                     rts_rate_fb);
9796
9797                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9798                     (&txhdr->body.old.rts_frame) :
9799                     (&txhdr->body.new.rts_frame));
9800                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9801
9802                 if (BWN_ISOFDMRATE(rts_rate)) {
9803                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9804                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9805                 } else {
9806                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9807                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9808                 }
9809                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9810                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9811         }
9812
9813         if (BWN_ISOLDFMT(mac))
9814                 txhdr->body.old.cookie = htole16(cookie);
9815         else
9816                 txhdr->body.new.cookie = htole16(cookie);
9817
9818         txhdr->macctl = htole32(macctl);
9819         txhdr->phyctl = htole16(phyctl);
9820
9821         /*
9822          * TX radio tap
9823          */
9824         if (ieee80211_radiotap_active_vap(vap)) {
9825                 sc->sc_tx_th.wt_flags = 0;
9826                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9827                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9828                 if (isshort &&
9829                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9830                      rate == BWN_CCK_RATE_11MB))
9831                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9832                 sc->sc_tx_th.wt_rate = rate;
9833
9834                 ieee80211_radiotap_tx(vap, m);
9835         }
9836
9837         return (0);
9838 }
9839
9840 static void
9841 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9842     const uint8_t rate)
9843 {
9844         uint32_t d, plen;
9845         uint8_t *raw = plcp->o.raw;
9846
9847         if (BWN_ISOFDMRATE(rate)) {
9848                 d = bwn_plcp_getofdm(rate);
9849                 KASSERT(!(octets & 0xf000),
9850                     ("%s:%d: fail", __func__, __LINE__));
9851                 d |= (octets << 5);
9852                 plcp->o.data = htole32(d);
9853         } else {
9854                 plen = octets * 16 / rate;
9855                 if ((octets * 16 % rate) > 0) {
9856                         plen++;
9857                         if ((rate == BWN_CCK_RATE_11MB)
9858                             && ((octets * 8 % 11) < 4)) {
9859                                 raw[1] = 0x84;
9860                         } else
9861                                 raw[1] = 0x04;
9862                 } else
9863                         raw[1] = 0x04;
9864                 plcp->o.data |= htole32(plen << 16);
9865                 raw[0] = bwn_plcp_getcck(rate);
9866         }
9867 }
9868
9869 static uint8_t
9870 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9871 {
9872         struct bwn_softc *sc = mac->mac_sc;
9873         uint8_t mask;
9874
9875         if (n == 0)
9876                 return (0);
9877         if (mac->mac_phy.gmode)
9878                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9879         else
9880                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9881         if (!(mask & (1 << (n - 1))))
9882                 return (0);
9883         return (n);
9884 }
9885
9886 static uint8_t
9887 bwn_get_fbrate(uint8_t bitrate)
9888 {
9889         switch (bitrate) {
9890         case BWN_CCK_RATE_1MB:
9891                 return (BWN_CCK_RATE_1MB);
9892         case BWN_CCK_RATE_2MB:
9893                 return (BWN_CCK_RATE_1MB);
9894         case BWN_CCK_RATE_5MB:
9895                 return (BWN_CCK_RATE_2MB);
9896         case BWN_CCK_RATE_11MB:
9897                 return (BWN_CCK_RATE_5MB);
9898         case BWN_OFDM_RATE_6MB:
9899                 return (BWN_CCK_RATE_5MB);
9900         case BWN_OFDM_RATE_9MB:
9901                 return (BWN_OFDM_RATE_6MB);
9902         case BWN_OFDM_RATE_12MB:
9903                 return (BWN_OFDM_RATE_9MB);
9904         case BWN_OFDM_RATE_18MB:
9905                 return (BWN_OFDM_RATE_12MB);
9906         case BWN_OFDM_RATE_24MB:
9907                 return (BWN_OFDM_RATE_18MB);
9908         case BWN_OFDM_RATE_36MB:
9909                 return (BWN_OFDM_RATE_24MB);
9910         case BWN_OFDM_RATE_48MB:
9911                 return (BWN_OFDM_RATE_36MB);
9912         case BWN_OFDM_RATE_54MB:
9913                 return (BWN_OFDM_RATE_48MB);
9914         }
9915         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9916         return (0);
9917 }
9918
9919 static uint32_t
9920 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9921     uint32_t ctl, const void *_data, int len)
9922 {
9923         struct bwn_softc *sc = mac->mac_sc;
9924         uint32_t value = 0;
9925         const uint8_t *data = _data;
9926
9927         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9928             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9929         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9930
9931         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9932             tq->tq_base + BWN_PIO8_TXDATA);
9933         if (len & 3) {
9934                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9935                     BWN_PIO8_TXCTL_24_31);
9936                 data = &(data[len - 1]);
9937                 switch (len & 3) {
9938                 case 3:
9939                         ctl |= BWN_PIO8_TXCTL_16_23;
9940                         value |= (uint32_t)(*data) << 16;
9941                         data--;
9942                 case 2:
9943                         ctl |= BWN_PIO8_TXCTL_8_15;
9944                         value |= (uint32_t)(*data) << 8;
9945                         data--;
9946                 case 1:
9947                         value |= (uint32_t)(*data);
9948                 }
9949                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9950                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9951         }
9952
9953         return (ctl);
9954 }
9955
9956 static void
9957 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9958     uint16_t offset, uint32_t value)
9959 {
9960
9961         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9962 }
9963
9964 static uint16_t
9965 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9966     uint16_t ctl, const void *_data, int len)
9967 {
9968         struct bwn_softc *sc = mac->mac_sc;
9969         const uint8_t *data = _data;
9970
9971         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9972         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9973
9974         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9975             tq->tq_base + BWN_PIO_TXDATA);
9976         if (len & 1) {
9977                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9978                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9979                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9980         }
9981
9982         return (ctl);
9983 }
9984
9985 static uint16_t
9986 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9987     uint16_t ctl, struct mbuf *m0)
9988 {
9989         int i, j = 0;
9990         uint16_t data = 0;
9991         const uint8_t *buf;
9992         struct mbuf *m = m0;
9993
9994         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9995         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9996
9997         for (; m != NULL; m = m->m_next) {
9998                 buf = mtod(m, const uint8_t *);
9999                 for (i = 0; i < m->m_len; i++) {
10000                         if (!((j++) % 2))
10001                                 data |= buf[i];
10002                         else {
10003                                 data |= (buf[i] << 8);
10004                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10005                                 data = 0;
10006                         }
10007                 }
10008         }
10009         if (m0->m_pkthdr.len % 2) {
10010                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
10011                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10012                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10013         }
10014
10015         return (ctl);
10016 }
10017
10018 static void
10019 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
10020 {
10021
10022         if (mac->mac_phy.type != BWN_PHYTYPE_G)
10023                 return;
10024         BWN_WRITE_2(mac, 0x684, 510 + time);
10025         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
10026 }
10027
10028 static struct bwn_dma_ring *
10029 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
10030 {
10031
10032         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
10033                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10034
10035         switch (prio) {
10036         case 3:
10037                 return (mac->mac_method.dma.wme[WME_AC_VO]);
10038         case 2:
10039                 return (mac->mac_method.dma.wme[WME_AC_VI]);
10040         case 0:
10041                 return (mac->mac_method.dma.wme[WME_AC_BE]);
10042         case 1:
10043                 return (mac->mac_method.dma.wme[WME_AC_BK]);
10044         }
10045         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10046         return (NULL);
10047 }
10048
10049 static int
10050 bwn_dma_getslot(struct bwn_dma_ring *dr)
10051 {
10052         int slot;
10053
10054         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10055
10056         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10057         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10058         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10059
10060         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10061         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10062         dr->dr_curslot = slot;
10063         dr->dr_usedslot++;
10064
10065         return (slot);
10066 }
10067
10068 static int
10069 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10070 {
10071         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10072         unsigned int a, b, c, d;
10073         unsigned int avg;
10074         uint32_t tmp;
10075
10076         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10077         a = tmp & 0xff;
10078         b = (tmp >> 8) & 0xff;
10079         c = (tmp >> 16) & 0xff;
10080         d = (tmp >> 24) & 0xff;
10081         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10082             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10083                 return (ENOENT);
10084         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10085             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10086             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10087
10088         if (ofdm) {
10089                 a = (a + 32) & 0x3f;
10090                 b = (b + 32) & 0x3f;
10091                 c = (c + 32) & 0x3f;
10092                 d = (d + 32) & 0x3f;
10093         }
10094
10095         avg = (a + b + c + d + 2) / 4;
10096         if (ofdm) {
10097                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10098                     & BWN_HF_4DB_CCK_POWERBOOST)
10099                         avg = (avg >= 13) ? (avg - 13) : 0;
10100         }
10101         return (avg);
10102 }
10103
10104 static void
10105 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10106 {
10107         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10108         int rfatt = *rfattp;
10109         int bbatt = *bbattp;
10110
10111         while (1) {
10112                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10113                         break;
10114                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10115                         break;
10116                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10117                         break;
10118                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10119                         break;
10120                 if (bbatt > lo->bbatt.max) {
10121                         bbatt -= 4;
10122                         rfatt += 1;
10123                         continue;
10124                 }
10125                 if (bbatt < lo->bbatt.min) {
10126                         bbatt += 4;
10127                         rfatt -= 1;
10128                         continue;
10129                 }
10130                 if (rfatt > lo->rfatt.max) {
10131                         rfatt -= 1;
10132                         bbatt += 4;
10133                         continue;
10134                 }
10135                 if (rfatt < lo->rfatt.min) {
10136                         rfatt += 1;
10137                         bbatt -= 4;
10138                         continue;
10139                 }
10140                 break;
10141         }
10142
10143         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10144         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10145 }
10146
10147 static void
10148 bwn_phy_lock(struct bwn_mac *mac)
10149 {
10150         struct bwn_softc *sc = mac->mac_sc;
10151         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10152
10153         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10154             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10155
10156         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10157                 bwn_psctl(mac, BWN_PS_AWAKE);
10158 }
10159
10160 static void
10161 bwn_phy_unlock(struct bwn_mac *mac)
10162 {
10163         struct bwn_softc *sc = mac->mac_sc;
10164         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10165
10166         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10167             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10168
10169         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10170                 bwn_psctl(mac, 0);
10171 }
10172
10173 static void
10174 bwn_rf_lock(struct bwn_mac *mac)
10175 {
10176
10177         BWN_WRITE_4(mac, BWN_MACCTL,
10178             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10179         BWN_READ_4(mac, BWN_MACCTL);
10180         DELAY(10);
10181 }
10182
10183 static void
10184 bwn_rf_unlock(struct bwn_mac *mac)
10185 {
10186
10187         BWN_READ_2(mac, BWN_PHYVER);
10188         BWN_WRITE_4(mac, BWN_MACCTL,
10189             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10190 }
10191
10192 static struct bwn_pio_txqueue *
10193 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10194     struct bwn_pio_txpkt **pack)
10195 {
10196         struct bwn_pio *pio = &mac->mac_method.pio;
10197         struct bwn_pio_txqueue *tq = NULL;
10198         unsigned int index;
10199
10200         switch (cookie & 0xf000) {
10201         case 0x1000:
10202                 tq = &pio->wme[WME_AC_BK];
10203                 break;
10204         case 0x2000:
10205                 tq = &pio->wme[WME_AC_BE];
10206                 break;
10207         case 0x3000:
10208                 tq = &pio->wme[WME_AC_VI];
10209                 break;
10210         case 0x4000:
10211                 tq = &pio->wme[WME_AC_VO];
10212                 break;
10213         case 0x5000:
10214                 tq = &pio->mcast;
10215                 break;
10216         }
10217         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10218         if (tq == NULL)
10219                 return (NULL);
10220         index = (cookie & 0x0fff);
10221         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10222         if (index >= N(tq->tq_pkts))
10223                 return (NULL);
10224         *pack = &tq->tq_pkts[index];
10225         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10226         return (tq);
10227 }
10228
10229 static void
10230 bwn_txpwr(void *arg, int npending)
10231 {
10232         struct bwn_mac *mac = arg;
10233         struct bwn_softc *sc = mac->mac_sc;
10234
10235         BWN_LOCK(sc);
10236         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10237             mac->mac_phy.set_txpwr != NULL)
10238                 mac->mac_phy.set_txpwr(mac);
10239         BWN_UNLOCK(sc);
10240 }
10241
10242 static void
10243 bwn_task_15s(struct bwn_mac *mac)
10244 {
10245         uint16_t reg;
10246
10247         if (mac->mac_fw.opensource) {
10248                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10249                 if (reg) {
10250                         bwn_restart(mac, "fw watchdog");
10251                         return;
10252                 }
10253                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10254         }
10255         if (mac->mac_phy.task_15s)
10256                 mac->mac_phy.task_15s(mac);
10257
10258         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10259 }
10260
10261 static void
10262 bwn_task_30s(struct bwn_mac *mac)
10263 {
10264
10265         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10266                 return;
10267         mac->mac_noise.noi_running = 1;
10268         mac->mac_noise.noi_nsamples = 0;
10269
10270         bwn_noise_gensample(mac);
10271 }
10272
10273 static void
10274 bwn_task_60s(struct bwn_mac *mac)
10275 {
10276
10277         if (mac->mac_phy.task_60s)
10278                 mac->mac_phy.task_60s(mac);
10279         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10280 }
10281
10282 static void
10283 bwn_tasks(void *arg)
10284 {
10285         struct bwn_mac *mac = arg;
10286         struct bwn_softc *sc = mac->mac_sc;
10287
10288         BWN_ASSERT_LOCKED(sc);
10289         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10290                 return;
10291
10292         if (mac->mac_task_state % 4 == 0)
10293                 bwn_task_60s(mac);
10294         if (mac->mac_task_state % 2 == 0)
10295                 bwn_task_30s(mac);
10296         bwn_task_15s(mac);
10297
10298         mac->mac_task_state++;
10299         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10300 }
10301
10302 static int
10303 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10304 {
10305         struct bwn_softc *sc = mac->mac_sc;
10306
10307         KASSERT(a == 0, ("not support APHY\n"));
10308
10309         switch (plcp->o.raw[0] & 0xf) {
10310         case 0xb:
10311                 return (BWN_OFDM_RATE_6MB);
10312         case 0xf:
10313                 return (BWN_OFDM_RATE_9MB);
10314         case 0xa:
10315                 return (BWN_OFDM_RATE_12MB);
10316         case 0xe:
10317                 return (BWN_OFDM_RATE_18MB);
10318         case 0x9:
10319                 return (BWN_OFDM_RATE_24MB);
10320         case 0xd:
10321                 return (BWN_OFDM_RATE_36MB);
10322         case 0x8:
10323                 return (BWN_OFDM_RATE_48MB);
10324         case 0xc:
10325                 return (BWN_OFDM_RATE_54MB);
10326         }
10327         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10328             plcp->o.raw[0] & 0xf);
10329         return (-1);
10330 }
10331
10332 static int
10333 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10334 {
10335         struct bwn_softc *sc = mac->mac_sc;
10336
10337         switch (plcp->o.raw[0]) {
10338         case 0x0a:
10339                 return (BWN_CCK_RATE_1MB);
10340         case 0x14:
10341                 return (BWN_CCK_RATE_2MB);
10342         case 0x37:
10343                 return (BWN_CCK_RATE_5MB);
10344         case 0x6e:
10345                 return (BWN_CCK_RATE_11MB);
10346         }
10347         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10348         return (-1);
10349 }
10350
10351 static void
10352 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10353     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10354     int rssi, int noise)
10355 {
10356         struct bwn_softc *sc = mac->mac_sc;
10357         const struct ieee80211_frame_min *wh;
10358         uint64_t tsf;
10359         uint16_t low_mactime_now;
10360
10361         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10362                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10363
10364         wh = mtod(m, const struct ieee80211_frame_min *);
10365         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10366                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10367
10368         bwn_tsf_read(mac, &tsf);
10369         low_mactime_now = tsf;
10370         tsf = tsf & ~0xffffULL;
10371         tsf += le16toh(rxhdr->mac_time);
10372         if (low_mactime_now < le16toh(rxhdr->mac_time))
10373                 tsf -= 0x10000;
10374
10375         sc->sc_rx_th.wr_tsf = tsf;
10376         sc->sc_rx_th.wr_rate = rate;
10377         sc->sc_rx_th.wr_antsignal = rssi;
10378         sc->sc_rx_th.wr_antnoise = noise;
10379 }
10380
10381 static void
10382 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10383 {
10384         uint32_t low, high;
10385
10386         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10387             ("%s:%d: fail", __func__, __LINE__));
10388
10389         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10390         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10391         *tsf = high;
10392         *tsf <<= 32;
10393         *tsf |= low;
10394 }
10395
10396 static int
10397 bwn_dma_attach(struct bwn_mac *mac)
10398 {
10399         struct bwn_dma *dma = &mac->mac_method.dma;
10400         struct bwn_softc *sc = mac->mac_sc;
10401         bus_addr_t lowaddr = 0;
10402         int error;
10403
10404         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10405                 return (0);
10406
10407         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10408
10409         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10410
10411         dma->dmatype = bwn_dma_gettype(mac);
10412         if (dma->dmatype == BWN_DMA_30BIT)
10413                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10414         else if (dma->dmatype == BWN_DMA_32BIT)
10415                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10416         else
10417                 lowaddr = BUS_SPACE_MAXADDR;
10418
10419         /*
10420          * Create top level DMA tag
10421          */
10422         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10423                                BWN_ALIGN, 0,            /* alignment, bounds */
10424                                lowaddr,                 /* lowaddr */
10425                                BUS_SPACE_MAXADDR,       /* highaddr */
10426                                NULL, NULL,              /* filter, filterarg */
10427                                MAXBSIZE,                /* maxsize */
10428                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10429                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10430                                0,                       /* flags */
10431                                NULL, NULL,              /* lockfunc, lockarg */
10432                                &dma->parent_dtag);
10433         if (error) {
10434                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10435                 return (error);
10436         }
10437
10438         /*
10439          * Create TX/RX mbuf DMA tag
10440          */
10441         error = bus_dma_tag_create(dma->parent_dtag,
10442                                 1,
10443                                 0,
10444                                 BUS_SPACE_MAXADDR,
10445                                 BUS_SPACE_MAXADDR,
10446                                 NULL, NULL,
10447                                 MCLBYTES,
10448                                 1,
10449                                 BUS_SPACE_MAXSIZE_32BIT,
10450                                 0,
10451                                 NULL, NULL,
10452                                 &dma->rxbuf_dtag);
10453         if (error) {
10454                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10455                 goto fail0;
10456         }
10457         error = bus_dma_tag_create(dma->parent_dtag,
10458                                 1,
10459                                 0,
10460                                 BUS_SPACE_MAXADDR,
10461                                 BUS_SPACE_MAXADDR,
10462                                 NULL, NULL,
10463                                 MCLBYTES,
10464                                 1,
10465                                 BUS_SPACE_MAXSIZE_32BIT,
10466                                 0,
10467                                 NULL, NULL,
10468                                 &dma->txbuf_dtag);
10469         if (error) {
10470                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10471                 goto fail1;
10472         }
10473
10474         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10475         if (!dma->wme[WME_AC_BK])
10476                 goto fail2;
10477
10478         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10479         if (!dma->wme[WME_AC_BE])
10480                 goto fail3;
10481
10482         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10483         if (!dma->wme[WME_AC_VI])
10484                 goto fail4;
10485
10486         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10487         if (!dma->wme[WME_AC_VO])
10488                 goto fail5;
10489
10490         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10491         if (!dma->mcast)
10492                 goto fail6;
10493         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10494         if (!dma->rx)
10495                 goto fail7;
10496
10497         return (error);
10498
10499 fail7:  bwn_dma_ringfree(&dma->mcast);
10500 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10501 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10502 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10503 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10504 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10505 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10506 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10507         return (error);
10508 }
10509
10510 static struct bwn_dma_ring *
10511 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10512     uint16_t cookie, int *slot)
10513 {
10514         struct bwn_dma *dma = &mac->mac_method.dma;
10515         struct bwn_dma_ring *dr;
10516         struct bwn_softc *sc = mac->mac_sc;
10517
10518         BWN_ASSERT_LOCKED(mac->mac_sc);
10519
10520         switch (cookie & 0xf000) {
10521         case 0x1000:
10522                 dr = dma->wme[WME_AC_BK];
10523                 break;
10524         case 0x2000:
10525                 dr = dma->wme[WME_AC_BE];
10526                 break;
10527         case 0x3000:
10528                 dr = dma->wme[WME_AC_VI];
10529                 break;
10530         case 0x4000:
10531                 dr = dma->wme[WME_AC_VO];
10532                 break;
10533         case 0x5000:
10534                 dr = dma->mcast;
10535                 break;
10536         default:
10537                 dr = NULL;
10538                 KASSERT(0 == 1,
10539                     ("invalid cookie value %d", cookie & 0xf000));
10540         }
10541         *slot = (cookie & 0x0fff);
10542         if (*slot < 0 || *slot >= dr->dr_numslots) {
10543                 /*
10544                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10545                  * that it occurs events which have same H/W sequence numbers.
10546                  * When it's occurred just prints a WARNING msgs and ignores.
10547                  */
10548                 KASSERT(status->seq == dma->lastseq,
10549                     ("%s:%d: fail", __func__, __LINE__));
10550                 device_printf(sc->sc_dev,
10551                     "out of slot ranges (0 < %d < %d)\n", *slot,
10552                     dr->dr_numslots);
10553                 return (NULL);
10554         }
10555         dma->lastseq = status->seq;
10556         return (dr);
10557 }
10558
10559 static void
10560 bwn_dma_stop(struct bwn_mac *mac)
10561 {
10562         struct bwn_dma *dma;
10563
10564         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10565                 return;
10566         dma = &mac->mac_method.dma;
10567
10568         bwn_dma_ringstop(&dma->rx);
10569         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10570         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10571         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10572         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10573         bwn_dma_ringstop(&dma->mcast);
10574 }
10575
10576 static void
10577 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10578 {
10579
10580         if (dr == NULL)
10581                 return;
10582
10583         bwn_dma_cleanup(*dr);
10584 }
10585
10586 static void
10587 bwn_pio_stop(struct bwn_mac *mac)
10588 {
10589         struct bwn_pio *pio;
10590
10591         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10592                 return;
10593         pio = &mac->mac_method.pio;
10594
10595         bwn_destroy_queue_tx(&pio->mcast);
10596         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10597         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10598         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10599         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10600 }
10601
10602 static void
10603 bwn_led_attach(struct bwn_mac *mac)
10604 {
10605         struct bwn_softc *sc = mac->mac_sc;
10606         const uint8_t *led_act = NULL;
10607         uint16_t val[BWN_LED_MAX];
10608         int i;
10609
10610         sc->sc_led_idle = (2350 * hz) / 1000;
10611         sc->sc_led_blink = 1;
10612
10613         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10614                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10615                     bwn_vendor_led_act[i].vid) {
10616                         led_act = bwn_vendor_led_act[i].led_act;
10617                         break;
10618                 }
10619         }
10620         if (led_act == NULL)
10621                 led_act = bwn_default_led_act;
10622
10623         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10624         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10625         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10626         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10627
10628         for (i = 0; i < BWN_LED_MAX; ++i) {
10629                 struct bwn_led *led = &sc->sc_leds[i];
10630
10631                 if (val[i] == 0xff) {
10632                         led->led_act = led_act[i];
10633                 } else {
10634                         if (val[i] & BWN_LED_ACT_LOW)
10635                                 led->led_flags |= BWN_LED_F_ACTLOW;
10636                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10637                 }
10638                 led->led_mask = (1 << i);
10639
10640                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10641                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10642                     led->led_act == BWN_LED_ACT_BLINK) {
10643                         led->led_flags |= BWN_LED_F_BLINK;
10644                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10645                                 led->led_flags |= BWN_LED_F_POLLABLE;
10646                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10647                                 led->led_flags |= BWN_LED_F_SLOW;
10648
10649                         if (sc->sc_blink_led == NULL) {
10650                                 sc->sc_blink_led = led;
10651                                 if (led->led_flags & BWN_LED_F_SLOW)
10652                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10653                         }
10654                 }
10655
10656                 DPRINTF(sc, BWN_DEBUG_LED,
10657                     "%dth led, act %d, lowact %d\n", i,
10658                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10659         }
10660         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10661 }
10662
10663 static __inline uint16_t
10664 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10665 {
10666
10667         if (led->led_flags & BWN_LED_F_ACTLOW)
10668                 on = !on;
10669         if (on)
10670                 val |= led->led_mask;
10671         else
10672                 val &= ~led->led_mask;
10673         return val;
10674 }
10675
10676 static void
10677 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10678 {
10679         struct bwn_softc *sc = mac->mac_sc;
10680         struct ifnet *ifp = sc->sc_ifp;
10681         struct ieee80211com *ic = ifp->if_l2com;
10682         uint16_t val;
10683         int i;
10684
10685         if (nstate == IEEE80211_S_INIT) {
10686                 callout_stop(&sc->sc_led_blink_ch);
10687                 sc->sc_led_blinking = 0;
10688         }
10689
10690         if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10691                 return;
10692
10693         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10694         for (i = 0; i < BWN_LED_MAX; ++i) {
10695                 struct bwn_led *led = &sc->sc_leds[i];
10696                 int on;
10697
10698                 if (led->led_act == BWN_LED_ACT_UNKN ||
10699                     led->led_act == BWN_LED_ACT_NULL)
10700                         continue;
10701
10702                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10703                     nstate != IEEE80211_S_INIT)
10704                         continue;
10705
10706                 switch (led->led_act) {
10707                 case BWN_LED_ACT_ON:    /* Always on */
10708                         on = 1;
10709                         break;
10710                 case BWN_LED_ACT_OFF:   /* Always off */
10711                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10712                         on = 0;
10713                         break;
10714                 default:
10715                         on = 1;
10716                         switch (nstate) {
10717                         case IEEE80211_S_INIT:
10718                                 on = 0;
10719                                 break;
10720                         case IEEE80211_S_RUN:
10721                                 if (led->led_act == BWN_LED_ACT_11G &&
10722                                     ic->ic_curmode != IEEE80211_MODE_11G)
10723                                         on = 0;
10724                                 break;
10725                         default:
10726                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10727                                         on = 0;
10728                                 break;
10729                         }
10730                         break;
10731                 }
10732
10733                 val = bwn_led_onoff(led, val, on);
10734         }
10735         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10736 }
10737
10738 static void
10739 bwn_led_event(struct bwn_mac *mac, int event)
10740 {
10741         struct bwn_softc *sc = mac->mac_sc;
10742         struct bwn_led *led = sc->sc_blink_led;
10743         int rate;
10744
10745         if (event == BWN_LED_EVENT_POLL) {
10746                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10747                         return;
10748                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10749                         return;
10750         }
10751
10752         sc->sc_led_ticks = ticks;
10753         if (sc->sc_led_blinking)
10754                 return;
10755
10756         switch (event) {
10757         case BWN_LED_EVENT_RX:
10758                 rate = sc->sc_rx_rate;
10759                 break;
10760         case BWN_LED_EVENT_TX:
10761                 rate = sc->sc_tx_rate;
10762                 break;
10763         case BWN_LED_EVENT_POLL:
10764                 rate = 0;
10765                 break;
10766         default:
10767                 panic("unknown LED event %d\n", event);
10768                 break;
10769         }
10770         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10771             bwn_led_duration[rate].off_dur);
10772 }
10773
10774 static void
10775 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10776 {
10777         struct bwn_softc *sc = mac->mac_sc;
10778         struct bwn_led *led = sc->sc_blink_led;
10779         uint16_t val;
10780
10781         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10782         val = bwn_led_onoff(led, val, 1);
10783         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10784
10785         if (led->led_flags & BWN_LED_F_SLOW) {
10786                 BWN_LED_SLOWDOWN(on_dur);
10787                 BWN_LED_SLOWDOWN(off_dur);
10788         }
10789
10790         sc->sc_led_blinking = 1;
10791         sc->sc_led_blink_offdur = off_dur;
10792
10793         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10794 }
10795
10796 static void
10797 bwn_led_blink_next(void *arg)
10798 {
10799         struct bwn_mac *mac = arg;
10800         struct bwn_softc *sc = mac->mac_sc;
10801         uint16_t val;
10802
10803         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10804         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10805         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10806
10807         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10808             bwn_led_blink_end, mac);
10809 }
10810
10811 static void
10812 bwn_led_blink_end(void *arg)
10813 {
10814         struct bwn_mac *mac = arg;
10815         struct bwn_softc *sc = mac->mac_sc;
10816
10817         sc->sc_led_blinking = 0;
10818 }
10819
10820 static int
10821 bwn_suspend(device_t dev)
10822 {
10823         struct bwn_softc *sc = device_get_softc(dev);
10824
10825         bwn_stop(sc, 1);
10826         return (0);
10827 }
10828
10829 static int
10830 bwn_resume(device_t dev)
10831 {
10832         struct bwn_softc *sc = device_get_softc(dev);
10833         struct ifnet *ifp = sc->sc_ifp;
10834
10835         if (ifp->if_flags & IFF_UP)
10836                 bwn_init(sc);
10837         return (0);
10838 }
10839
10840 static void
10841 bwn_rfswitch(void *arg)
10842 {
10843         struct bwn_softc *sc = arg;
10844         struct bwn_mac *mac = sc->sc_curmac;
10845         int cur = 0, prev = 0;
10846
10847         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10848             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10849
10850         if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10851                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10852                         & BWN_RF_HWENABLED_HI_MASK))
10853                         cur = 1;
10854         } else {
10855                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10856                     & BWN_RF_HWENABLED_LO_MASK)
10857                         cur = 1;
10858         }
10859
10860         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10861                 prev = 1;
10862
10863         if (cur != prev) {
10864                 if (cur)
10865                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10866                 else
10867                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10868
10869                 device_printf(sc->sc_dev,
10870                     "status of RF switch is changed to %s\n",
10871                     cur ? "ON" : "OFF");
10872                 if (cur != mac->mac_phy.rf_on) {
10873                         if (cur)
10874                                 bwn_rf_turnon(mac);
10875                         else
10876                                 bwn_rf_turnoff(mac);
10877                 }
10878         }
10879
10880         callout_schedule(&sc->sc_rfswitch_ch, hz);
10881 }
10882
10883 static void
10884 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10885 {
10886         struct bwn_phy *phy = &mac->mac_phy;
10887         struct bwn_phy_lp *plp = &phy->phy_lp;
10888
10889         plp->plp_antenna = BWN_ANT_DEFAULT;
10890 }
10891
10892 static int
10893 bwn_phy_lp_init(struct bwn_mac *mac)
10894 {
10895         static const struct bwn_stxtable tables[] = {
10896                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10897                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10898                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10899                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10900                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10901                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10902                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10903                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10904                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10905                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10906                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10907                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10908                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10909                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10910                 { 2, 11, 0x40, 0, 0x0f }
10911         };
10912         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10913         struct bwn_softc *sc = mac->mac_sc;
10914         const struct bwn_stxtable *st;
10915         struct ifnet *ifp = sc->sc_ifp;
10916         struct ieee80211com *ic = ifp->if_l2com;
10917         int i, error;
10918         uint16_t tmp;
10919
10920         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10921         bwn_phy_lp_bbinit(mac);
10922
10923         /* initialize RF */
10924         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10925         DELAY(1);
10926         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10927         DELAY(1);
10928
10929         if (mac->mac_phy.rf_ver == 0x2062)
10930                 bwn_phy_lp_b2062_init(mac);
10931         else {
10932                 bwn_phy_lp_b2063_init(mac);
10933
10934                 /* synchronize stx table. */
10935                 for (i = 0; i < N(tables); i++) {
10936                         st = &tables[i];
10937                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10938                         tmp >>= st->st_rfshift;
10939                         tmp <<= st->st_physhift;
10940                         BWN_PHY_SETMASK(mac,
10941                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10942                             ~(st->st_mask << st->st_physhift), tmp);
10943                 }
10944
10945                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10946                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10947         }
10948
10949         /* calibrate RC */
10950         if (mac->mac_phy.rev >= 2)
10951                 bwn_phy_lp_rxcal_r2(mac);
10952         else if (!plp->plp_rccap) {
10953                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10954                         bwn_phy_lp_rccal_r12(mac);
10955         } else
10956                 bwn_phy_lp_set_rccap(mac);
10957
10958         error = bwn_phy_lp_switch_channel(mac, 7);
10959         if (error)
10960                 device_printf(sc->sc_dev,
10961                     "failed to change channel 7 (%d)\n", error);
10962         bwn_phy_lp_txpctl_init(mac);
10963         bwn_phy_lp_calib(mac);
10964         return (0);
10965 }
10966
10967 static uint16_t
10968 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10969 {
10970
10971         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10972         return (BWN_READ_2(mac, BWN_PHYDATA));
10973 }
10974
10975 static void
10976 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10977 {
10978
10979         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10980         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10981 }
10982
10983 static void
10984 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10985     uint16_t set)
10986 {
10987
10988         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10989         BWN_WRITE_2(mac, BWN_PHYDATA,
10990             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10991 }
10992
10993 static uint16_t
10994 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10995 {
10996
10997         KASSERT(reg != 1, ("unaccessible register %d", reg));
10998         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10999                 reg |= 0x100;
11000         if (mac->mac_phy.rev >= 2)
11001                 reg |= 0x200;
11002         BWN_WRITE_2(mac, BWN_RFCTL, reg);
11003         return BWN_READ_2(mac, BWN_RFDATALO);
11004 }
11005
11006 static void
11007 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
11008 {
11009
11010         KASSERT(reg != 1, ("unaccessible register %d", reg));
11011         BWN_WRITE_2(mac, BWN_RFCTL, reg);
11012         BWN_WRITE_2(mac, BWN_RFDATALO, value);
11013 }
11014
11015 static void
11016 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
11017 {
11018
11019         if (on) {
11020                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
11021                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
11022                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
11023                 return;
11024         }
11025
11026         if (mac->mac_phy.rev >= 2) {
11027                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
11028                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11029                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
11030                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
11031                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
11032                 return;
11033         }
11034
11035         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11036         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11037         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11038         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11039 }
11040
11041 static int
11042 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11043 {
11044         struct bwn_phy *phy = &mac->mac_phy;
11045         struct bwn_phy_lp *plp = &phy->phy_lp;
11046         int error;
11047
11048         if (phy->rf_ver == 0x2063) {
11049                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11050                 if (error)
11051                         return (error);
11052         } else {
11053                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11054                 if (error)
11055                         return (error);
11056                 bwn_phy_lp_set_anafilter(mac, chan);
11057                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11058         }
11059
11060         plp->plp_chan = chan;
11061         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11062         return (0);
11063 }
11064
11065 static uint32_t
11066 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11067 {
11068         struct bwn_softc *sc = mac->mac_sc;
11069         struct ifnet *ifp = sc->sc_ifp;
11070         struct ieee80211com *ic = ifp->if_l2com;
11071
11072         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11073 }
11074
11075 static void
11076 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11077 {
11078         struct bwn_phy *phy = &mac->mac_phy;
11079         struct bwn_phy_lp *plp = &phy->phy_lp;
11080
11081         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11082                 return;
11083
11084         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11085         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11086         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11087         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11088         plp->plp_antenna = antenna;
11089 }
11090
11091 static void
11092 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11093 {
11094
11095         bwn_phy_lp_calib(mac);
11096 }
11097
11098 static void
11099 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11100 {
11101         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11102         struct bwn_softc *sc = mac->mac_sc;
11103         struct ifnet *ifp = sc->sc_ifp;
11104         struct ieee80211com *ic = ifp->if_l2com;
11105
11106         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11107                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11108                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11109                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11110                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11111                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11112                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11113                 return;
11114         }
11115
11116         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11117         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11118         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11119         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11120         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11121         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11122         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11123         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11124 }
11125
11126 static void
11127 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11128 {
11129
11130         bwn_phy_lp_tblinit(mac);
11131         if (mac->mac_phy.rev >= 2)
11132                 bwn_phy_lp_bbinit_r2(mac);
11133         else
11134                 bwn_phy_lp_bbinit_r01(mac);
11135 }
11136
11137 static void
11138 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11139 {
11140         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11141         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11142         struct bwn_softc *sc = mac->mac_sc;
11143         struct ifnet *ifp = sc->sc_ifp;
11144         struct ieee80211com *ic = ifp->if_l2com;
11145
11146         bwn_phy_lp_set_txgain(mac,
11147             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11148         bwn_phy_lp_set_bbmult(mac, 150);
11149 }
11150
11151 static void
11152 bwn_phy_lp_calib(struct bwn_mac *mac)
11153 {
11154         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11155         struct bwn_softc *sc = mac->mac_sc;
11156         struct ifnet *ifp = sc->sc_ifp;
11157         struct ieee80211com *ic = ifp->if_l2com;
11158         const struct bwn_rxcompco *rc = NULL;
11159         struct bwn_txgain ogain;
11160         int i, omode, oafeovr, orf, obbmult;
11161         uint8_t mode, fc = 0;
11162
11163         if (plp->plp_chanfullcal != plp->plp_chan) {
11164                 plp->plp_chanfullcal = plp->plp_chan;
11165                 fc = 1;
11166         }
11167
11168         bwn_mac_suspend(mac);
11169
11170         /* BlueTooth Coexistance Override */
11171         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11172         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11173
11174         if (mac->mac_phy.rev >= 2)
11175                 bwn_phy_lp_digflt_save(mac);
11176         bwn_phy_lp_get_txpctlmode(mac);
11177         mode = plp->plp_txpctlmode;
11178         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11179         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11180                 bwn_phy_lp_bugfix(mac);
11181         if (mac->mac_phy.rev >= 2 && fc == 1) {
11182                 bwn_phy_lp_get_txpctlmode(mac);
11183                 omode = plp->plp_txpctlmode;
11184                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11185                 if (oafeovr)
11186                         ogain = bwn_phy_lp_get_txgain(mac);
11187                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11188                 obbmult = bwn_phy_lp_get_bbmult(mac);
11189                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11190                 if (oafeovr)
11191                         bwn_phy_lp_set_txgain(mac, &ogain);
11192                 bwn_phy_lp_set_bbmult(mac, obbmult);
11193                 bwn_phy_lp_set_txpctlmode(mac, omode);
11194                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11195         }
11196         bwn_phy_lp_set_txpctlmode(mac, mode);
11197         if (mac->mac_phy.rev >= 2)
11198                 bwn_phy_lp_digflt_restore(mac);
11199
11200         /* do RX IQ Calculation; assumes that noise is true. */
11201         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11202                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11203                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11204                                 rc = &bwn_rxcompco_5354[i];
11205                 }
11206         } else if (mac->mac_phy.rev >= 2)
11207                 rc = &bwn_rxcompco_r2;
11208         else {
11209                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11210                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11211                                 rc = &bwn_rxcompco_r12[i];
11212                 }
11213         }
11214         if (rc == NULL)
11215                 goto fail;
11216
11217         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11218         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11219
11220         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11221
11222         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11223                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11224                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11225         } else {
11226                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11227                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11228         }
11229
11230         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11231         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11232         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11233         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11234         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11235         bwn_phy_lp_set_deaf(mac, 0);
11236         /* XXX no checking return value? */
11237         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11238         bwn_phy_lp_clear_deaf(mac, 0);
11239         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11240         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11241         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11242
11243         /* disable RX GAIN override. */
11244         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11245         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11246         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11247         if (mac->mac_phy.rev >= 2) {
11248                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11249                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11250                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11251                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11252                 }
11253         } else {
11254                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11255         }
11256
11257         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11258         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11259 fail:
11260         bwn_mac_enable(mac);
11261 }
11262
11263 static void
11264 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11265 {
11266
11267         if (on) {
11268                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11269                 return;
11270         }
11271
11272         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11273         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11274 }
11275
11276 static int
11277 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11278 {
11279         static const struct bwn_b206x_chan *bc = NULL;
11280         struct bwn_softc *sc = mac->mac_sc;
11281         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11282             tmp[6];
11283         uint16_t old, scale, tmp16;
11284         int i, div;
11285
11286         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11287                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11288                         bc = &bwn_b2063_chantable[i];
11289                         break;
11290                 }
11291         }
11292         if (bc == NULL)
11293                 return (EINVAL);
11294
11295         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11296         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11297         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11298         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11299         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11300         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11301         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11302         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11303         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11304         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11305         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11306         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11307
11308         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11309         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11310
11311         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11312         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11313         freqref = freqxtal * 3;
11314         div = (freqxtal <= 26000000 ? 1 : 2);
11315         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11316         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11317                 999999) / 1000000) + 1;
11318
11319         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11320         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11321             0xfff8, timeout >> 2);
11322         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11323             0xff9f,timeout << 5);
11324         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11325
11326         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11327         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11328         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11329
11330         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11331             (timeoutref + 1)) - 1;
11332         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11333             0xf0, count >> 8);
11334         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11335
11336         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11337         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11338         while (tmp[1] >= freqref) {
11339                 tmp[0]++;
11340                 tmp[1] -= freqref;
11341         }
11342         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11343         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11344         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11345         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11346         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11347
11348         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11349         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11350         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11351         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11352
11353         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11354         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11355
11356         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11357                 scale = 1;
11358                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11359         } else {
11360                 scale = 0;
11361                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11362         }
11363         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11364         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11365
11366         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11367             (scale + 1);
11368         if (tmp[5] > 150)
11369                 tmp[5] = 0;
11370
11371         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11372         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11373
11374         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11375         if (freqxtal > 26000000)
11376                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11377         else
11378                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11379
11380         if (val[0] == 45)
11381                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11382         else
11383                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11384
11385         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11386         DELAY(1);
11387         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11388
11389         /* VCO Calibration */
11390         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11391         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11392         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11393         DELAY(1);
11394         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11395         DELAY(1);
11396         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11397         DELAY(1);
11398         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11399         DELAY(300);
11400         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11401
11402         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11403         return (0);
11404 }
11405
11406 static int
11407 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11408 {
11409         struct bwn_softc *sc = mac->mac_sc;
11410         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11411         const struct bwn_b206x_chan *bc = NULL;
11412         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11413         uint32_t tmp[9];
11414         int i;
11415
11416         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11417                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11418                         bc = &bwn_b2062_chantable[i];
11419                         break;
11420                 }
11421         }
11422
11423         if (bc == NULL)
11424                 return (EINVAL);
11425
11426         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11427         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11428         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11429         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11430         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11431         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11432         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11433         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11434         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11435         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11436
11437         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11438         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11439         bwn_phy_lp_b2062_reset_pllbias(mac);
11440         tmp[0] = freqxtal / 1000;
11441         tmp[1] = plp->plp_div * 1000;
11442         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11443         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11444                 tmp[2] *= 2;
11445         tmp[3] = 48 * tmp[0];
11446         tmp[5] = tmp[2] / tmp[3];
11447         tmp[6] = tmp[2] % tmp[3];
11448         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11449         tmp[4] = tmp[6] * 0x100;
11450         tmp[5] = tmp[4] / tmp[3];
11451         tmp[6] = tmp[4] % tmp[3];
11452         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11453         tmp[4] = tmp[6] * 0x100;
11454         tmp[5] = tmp[4] / tmp[3];
11455         tmp[6] = tmp[4] % tmp[3];
11456         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11457         tmp[4] = tmp[6] * 0x100;
11458         tmp[5] = tmp[4] / tmp[3];
11459         tmp[6] = tmp[4] % tmp[3];
11460         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11461             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11462         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11463         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11464         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11465         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11466
11467         bwn_phy_lp_b2062_vco_calib(mac);
11468         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11469                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11470                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11471                 bwn_phy_lp_b2062_reset_pllbias(mac);
11472                 bwn_phy_lp_b2062_vco_calib(mac);
11473                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11474                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11475                         return (EIO);
11476                 }
11477         }
11478         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11479         return (0);
11480 }
11481
11482 static void
11483 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11484 {
11485         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11486         uint16_t tmp = (channel == 14);
11487
11488         if (mac->mac_phy.rev < 2) {
11489                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11490                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11491                         bwn_phy_lp_set_rccap(mac);
11492                 return;
11493         }
11494
11495         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11496 }
11497
11498 static void
11499 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11500 {
11501         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11502         struct bwn_softc *sc = mac->mac_sc;
11503         struct ifnet *ifp = sc->sc_ifp;
11504         struct ieee80211com *ic = ifp->if_l2com;
11505         uint16_t iso, tmp[3];
11506
11507         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11508
11509         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11510                 iso = plp->plp_txisoband_m;
11511         else if (freq <= 5320)
11512                 iso = plp->plp_txisoband_l;
11513         else if (freq <= 5700)
11514                 iso = plp->plp_txisoband_m;
11515         else
11516                 iso = plp->plp_txisoband_h;
11517
11518         tmp[0] = ((iso - 26) / 12) << 12;
11519         tmp[1] = tmp[0] + 0x1000;
11520         tmp[2] = tmp[0] + 0x2000;
11521
11522         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11523         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11524 }
11525
11526 static void
11527 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11528 {
11529         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11530         int i;
11531         static const uint16_t addr[] = {
11532                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11533                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11534                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11535                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11536                 BWN_PHY_OFDM(0xcf),
11537         };
11538         static const uint16_t val[] = {
11539                 0xde5e, 0xe832, 0xe331, 0x4d26,
11540                 0x0026, 0x1420, 0x0020, 0xfe08,
11541                 0x0008,
11542         };
11543
11544         for (i = 0; i < N(addr); i++) {
11545                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11546                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11547         }
11548 }
11549
11550 static void
11551 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11552 {
11553         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11554         struct bwn_softc *sc = mac->mac_sc;
11555         uint16_t ctl;
11556
11557         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11558         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11559         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11560                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11561                 break;
11562         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11563                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11564                 break;
11565         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11566                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11567                 break;
11568         default:
11569                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11570                 device_printf(sc->sc_dev, "unknown command mode\n");
11571                 break;
11572         }
11573 }
11574
11575 static void
11576 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11577 {
11578         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11579         uint16_t ctl;
11580         uint8_t old;
11581
11582         bwn_phy_lp_get_txpctlmode(mac);
11583         old = plp->plp_txpctlmode;
11584         if (old == mode)
11585                 return;
11586         plp->plp_txpctlmode = mode;
11587
11588         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11589                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11590                     plp->plp_tssiidx);
11591                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11592                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11593
11594                 /* disable TX GAIN override */
11595                 if (mac->mac_phy.rev < 2)
11596                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11597                 else {
11598                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11599                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11600                 }
11601                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11602
11603                 plp->plp_txpwridx = -1;
11604         }
11605         if (mac->mac_phy.rev >= 2) {
11606                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11607                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11608                 else
11609                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11610         }
11611
11612         /* writes TX Power Control mode */
11613         switch (plp->plp_txpctlmode) {
11614         case BWN_PHYLP_TXPCTL_OFF:
11615                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11616                 break;
11617         case BWN_PHYLP_TXPCTL_ON_HW:
11618                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11619                 break;
11620         case BWN_PHYLP_TXPCTL_ON_SW:
11621                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11622                 break;
11623         default:
11624                 ctl = 0;
11625                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11626         }
11627         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11628             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11629 }
11630
11631 static void
11632 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11633 {
11634         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11635         struct bwn_softc *sc = mac->mac_sc;
11636         const unsigned int size = 256;
11637         struct bwn_txgain tg;
11638         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11639         uint16_t tssinpt, tssiidx, value[2];
11640         uint8_t mode;
11641         int8_t txpwridx;
11642
11643         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11644             M_NOWAIT | M_ZERO);
11645         if (tabs == NULL) {
11646                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11647                 return;
11648         }
11649
11650         bwn_phy_lp_get_txpctlmode(mac);
11651         mode = plp->plp_txpctlmode;
11652         txpwridx = plp->plp_txpwridx;
11653         tssinpt = plp->plp_tssinpt;
11654         tssiidx = plp->plp_tssiidx;
11655
11656         bwn_tab_read_multi(mac,
11657             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11658             BWN_TAB_4(7, 0x140), size, tabs);
11659
11660         bwn_phy_lp_tblinit(mac);
11661         bwn_phy_lp_bbinit(mac);
11662         bwn_phy_lp_txpctl_init(mac);
11663         bwn_phy_lp_rf_onoff(mac, 1);
11664         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11665
11666         bwn_tab_write_multi(mac,
11667             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11668             BWN_TAB_4(7, 0x140), size, tabs);
11669
11670         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11671         plp->plp_tssinpt = tssinpt;
11672         plp->plp_tssiidx = tssiidx;
11673         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11674         if (txpwridx != -1) {
11675                 /* set TX power by index */
11676                 plp->plp_txpwridx = txpwridx;
11677                 bwn_phy_lp_get_txpctlmode(mac);
11678                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11679                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11680                 if (mac->mac_phy.rev >= 2) {
11681                         rxcomp = bwn_tab_read(mac,
11682                             BWN_TAB_4(7, txpwridx + 320));
11683                         txgain = bwn_tab_read(mac,
11684                             BWN_TAB_4(7, txpwridx + 192));
11685                         tg.tg_pad = (txgain >> 16) & 0xff;
11686                         tg.tg_gm = txgain & 0xff;
11687                         tg.tg_pga = (txgain >> 8) & 0xff;
11688                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11689                         bwn_phy_lp_set_txgain(mac, &tg);
11690                 } else {
11691                         rxcomp = bwn_tab_read(mac,
11692                             BWN_TAB_4(10, txpwridx + 320));
11693                         txgain = bwn_tab_read(mac,
11694                             BWN_TAB_4(10, txpwridx + 192));
11695                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11696                             0xf800, (txgain >> 4) & 0x7fff);
11697                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11698                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11699                 }
11700                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11701
11702                 /* set TX IQCC */
11703                 value[0] = (rxcomp >> 10) & 0x3ff;
11704                 value[1] = rxcomp & 0x3ff;
11705                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11706
11707                 coeff = bwn_tab_read(mac,
11708                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11709                     BWN_TAB_4(10, txpwridx + 448));
11710                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11711                 if (mac->mac_phy.rev >= 2) {
11712                         rfpwr = bwn_tab_read(mac,
11713                             BWN_TAB_4(7, txpwridx + 576));
11714                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11715                             rfpwr & 0xffff);
11716                 }
11717                 bwn_phy_lp_set_txgain_override(mac);
11718         }
11719         if (plp->plp_rccap)
11720                 bwn_phy_lp_set_rccap(mac);
11721         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11722         bwn_phy_lp_set_txpctlmode(mac, mode);
11723         free(tabs, M_DEVBUF);
11724 }
11725
11726 static void
11727 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11728 {
11729         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11730         int i;
11731         static const uint16_t addr[] = {
11732                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11733                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11734                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11735                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11736                 BWN_PHY_OFDM(0xcf),
11737         };
11738
11739         for (i = 0; i < N(addr); i++)
11740                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11741 }
11742
11743 static void
11744 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11745 {
11746         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11747
11748         if (mac->mac_phy.rev < 2) {
11749                 bwn_phy_lp_tblinit_r01(mac);
11750                 bwn_phy_lp_tblinit_txgain(mac);
11751                 bwn_phy_lp_set_gaintbl(mac, freq);
11752                 return;
11753         }
11754
11755         bwn_phy_lp_tblinit_r2(mac);
11756         bwn_phy_lp_tblinit_txgain(mac);
11757 }
11758
11759 struct bwn_wpair {
11760         uint16_t                reg;
11761         uint16_t                value;
11762 };
11763
11764 struct bwn_smpair {
11765         uint16_t                offset;
11766         uint16_t                mask;
11767         uint16_t                set;
11768 };
11769
11770 static void
11771 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11772 {
11773         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11774         struct bwn_softc *sc = mac->mac_sc;
11775         struct ifnet *ifp = sc->sc_ifp;
11776         struct ieee80211com *ic = ifp->if_l2com;
11777         static const struct bwn_wpair v1[] = {
11778                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11779                 { BWN_PHY_AFE_CTL, 0x8800 },
11780                 { BWN_PHY_AFE_CTL_OVR, 0 },
11781                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11782                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11783                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11784                 { BWN_PHY_OFDM(0xf9), 0 },
11785                 { BWN_PHY_TR_LOOKUP_1, 0 }
11786         };
11787         static const struct bwn_smpair v2[] = {
11788                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11789                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11790                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11791                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11792                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11793         };
11794         static const struct bwn_smpair v3[] = {
11795                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11796                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11797                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11798                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11799                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11800                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11801                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11802                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11803                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11804                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11805
11806         };
11807         int i;
11808
11809         for (i = 0; i < N(v1); i++)
11810                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11811         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11812         for (i = 0; i < N(v2); i++)
11813                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11814
11815         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11816         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11817         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11818         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11819                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11820                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11821         } else {
11822                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11823         }
11824         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11825         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11826         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11827         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11828         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11829         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11830         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11831         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11832         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11833         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11834         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11835         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11836             (siba_get_chiprev(sc->sc_dev) == 0)) {
11837                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11838                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11839         } else {
11840                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11841                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11842         }
11843         for (i = 0; i < N(v3); i++)
11844                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11845         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11846             (siba_get_chiprev(sc->sc_dev) == 0)) {
11847                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11848                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11849         }
11850
11851         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11852                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11853                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11854                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11855                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11856                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11857                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11858         } else
11859                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11860
11861         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11862         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11863         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11864         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11865         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11866         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11867         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11868             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11869             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11870
11871         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11872             (siba_get_chiprev(sc->sc_dev) == 0)) {
11873                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11874                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11875                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11876         }
11877
11878         bwn_phy_lp_digflt_save(mac);
11879 }
11880
11881 static void
11882 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11883 {
11884         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11885         struct bwn_softc *sc = mac->mac_sc;
11886         struct ifnet *ifp = sc->sc_ifp;
11887         struct ieee80211com *ic = ifp->if_l2com;
11888         static const struct bwn_smpair v1[] = {
11889                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11890                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11891                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11892                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11893                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11894                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11895                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11896         };
11897         static const struct bwn_smpair v2[] = {
11898                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11899                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11900                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11901                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11902                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11903                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11904                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11905                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11906                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11907                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11908                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11909                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11910                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11911                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11912                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11913                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11914         };
11915         static const struct bwn_smpair v3[] = {
11916                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11917                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11918                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11919                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11920                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11921                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11922                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11923                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11924         };
11925         static const struct bwn_smpair v4[] = {
11926                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11927                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11928                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11929                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11930                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11931                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11932                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11933                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11934         };
11935         static const struct bwn_smpair v5[] = {
11936                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11937                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11938                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11939                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11940                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11941                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11942                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11943                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11944         };
11945         int i;
11946         uint16_t tmp, tmp2;
11947
11948         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11949         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11950         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11951         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11952         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11953         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11954         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11955         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11956         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11957         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11958         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11959         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11960         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11961         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11962         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11963         for (i = 0; i < N(v1); i++)
11964                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11965         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11966             0xff00, plp->plp_rxpwroffset);
11967         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11968             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11969            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11970                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11971                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11972                 if (mac->mac_phy.rev == 0)
11973                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11974                             0xffcf, 0x0010);
11975                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11976         } else {
11977                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11978                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11979                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11980         }
11981         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11982         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11983         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11984                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11985         else
11986                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11987         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11988         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11989             0xfff9, (plp->plp_bxarch << 1));
11990         if (mac->mac_phy.rev == 1 &&
11991             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11992                 for (i = 0; i < N(v2); i++)
11993                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11994                             v2[i].set);
11995         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11996             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11997             ((mac->mac_phy.rev == 0) &&
11998              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11999                 for (i = 0; i < N(v3); i++)
12000                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
12001                             v3[i].set);
12002         } else if (mac->mac_phy.rev == 1 ||
12003                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
12004                 for (i = 0; i < N(v4); i++)
12005                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
12006                             v4[i].set);
12007         } else {
12008                 for (i = 0; i < N(v5); i++)
12009                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
12010                             v5[i].set);
12011         }
12012         if (mac->mac_phy.rev == 1 &&
12013             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
12014                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
12015                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
12016                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
12017                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
12018         }
12019         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
12020             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
12021             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
12022                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
12023                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
12024                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
12025                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
12026         }
12027         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12028                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
12029                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
12030                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
12031                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
12032                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
12033                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
12034                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12035                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12036         } else {
12037                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12038                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12039         }
12040         if (mac->mac_phy.rev == 1) {
12041                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12042                 tmp2 = (tmp & 0x03e0) >> 5;
12043                 tmp2 |= tmp2 << 5;
12044                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12045                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12046                 tmp2 = (tmp & 0x1f00) >> 8;
12047                 tmp2 |= tmp2 << 5;
12048                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12049                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12050                 tmp2 = tmp & 0x00ff;
12051                 tmp2 |= tmp << 8;
12052                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12053         }
12054 }
12055
12056 struct bwn_b2062_freq {
12057         uint16_t                freq;
12058         uint8_t                 value[6];
12059 };
12060
12061 static void
12062 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12063 {
12064 #define CALC_CTL7(freq, div)                                            \
12065         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12066 #define CALC_CTL18(freq, div)                                           \
12067         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12068 #define CALC_CTL19(freq, div)                                           \
12069         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12070         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12071         struct bwn_softc *sc = mac->mac_sc;
12072         struct ifnet *ifp = sc->sc_ifp;
12073         struct ieee80211com *ic = ifp->if_l2com;
12074         static const struct bwn_b2062_freq freqdata_tab[] = {
12075                 { 12000, { 6, 6, 6, 6, 10, 6 } },
12076                 { 13000, { 4, 4, 4, 4, 11, 7 } },
12077                 { 14400, { 3, 3, 3, 3, 12, 7 } },
12078                 { 16200, { 3, 3, 3, 3, 13, 8 } },
12079                 { 18000, { 2, 2, 2, 2, 14, 8 } },
12080                 { 19200, { 1, 1, 1, 1, 14, 9 } }
12081         };
12082         static const struct bwn_wpair v1[] = {
12083                 { BWN_B2062_N_TXCTL3, 0 },
12084                 { BWN_B2062_N_TXCTL4, 0 },
12085                 { BWN_B2062_N_TXCTL5, 0 },
12086                 { BWN_B2062_N_TXCTL6, 0 },
12087                 { BWN_B2062_N_PDNCTL0, 0x40 },
12088                 { BWN_B2062_N_PDNCTL0, 0 },
12089                 { BWN_B2062_N_CALIB_TS, 0x10 },
12090                 { BWN_B2062_N_CALIB_TS, 0 }
12091         };
12092         const struct bwn_b2062_freq *f = NULL;
12093         uint32_t xtalfreq, ref;
12094         unsigned int i;
12095
12096         bwn_phy_lp_b2062_tblinit(mac);
12097
12098         for (i = 0; i < N(v1); i++)
12099                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12100         if (mac->mac_phy.rev > 0)
12101                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12102                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12103         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12104                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12105         else
12106                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12107
12108         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12109             ("%s:%d: fail", __func__, __LINE__));
12110         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12111         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12112
12113         if (xtalfreq <= 30000000) {
12114                 plp->plp_div = 1;
12115                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12116         } else {
12117                 plp->plp_div = 2;
12118                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12119         }
12120
12121         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12122             CALC_CTL7(xtalfreq, plp->plp_div));
12123         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12124             CALC_CTL18(xtalfreq, plp->plp_div));
12125         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12126             CALC_CTL19(xtalfreq, plp->plp_div));
12127
12128         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12129         ref &= 0xffff;
12130         for (i = 0; i < N(freqdata_tab); i++) {
12131                 if (ref < freqdata_tab[i].freq) {
12132                         f = &freqdata_tab[i];
12133                         break;
12134                 }
12135         }
12136         if (f == NULL)
12137                 f = &freqdata_tab[N(freqdata_tab) - 1];
12138         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12139             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12140         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12141             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12142         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12143         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12144 #undef CALC_CTL7
12145 #undef CALC_CTL18
12146 #undef CALC_CTL19
12147 }
12148
12149 static void
12150 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12151 {
12152
12153         bwn_phy_lp_b2063_tblinit(mac);
12154         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12155         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12156         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12157         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12158         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12159         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12160         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12161         if (mac->mac_phy.rev == 2) {
12162                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12163                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12164                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12165         } else {
12166                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12167                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12168         }
12169 }
12170
12171 static void
12172 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12173 {
12174         struct bwn_softc *sc = mac->mac_sc;
12175         static const struct bwn_wpair v1[] = {
12176                 { BWN_B2063_RX_BB_SP8, 0x0 },
12177                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12178                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12179                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12180                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12181                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12182                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12183                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12184         };
12185         static const struct bwn_wpair v2[] = {
12186                 { BWN_B2063_TX_BB_SP3, 0x0 },
12187                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12188                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12189                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12190                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12191         };
12192         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12193         int i;
12194         uint8_t tmp;
12195
12196         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12197
12198         for (i = 0; i < 2; i++)
12199                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12200         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12201         for (i = 2; i < N(v1); i++)
12202                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12203         for (i = 0; i < 10000; i++) {
12204                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12205                         break;
12206                 DELAY(1000);
12207         }
12208
12209         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12210                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12211
12212         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12213
12214         for (i = 0; i < N(v2); i++)
12215                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12216         if (freqxtal == 24000000) {
12217                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12218                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12219         } else {
12220                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12221                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12222         }
12223         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12224         for (i = 0; i < 10000; i++) {
12225                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12226                         break;
12227                 DELAY(1000);
12228         }
12229         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12230                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12231         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12232 }
12233
12234 static void
12235 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12236 {
12237         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12238         struct bwn_softc *sc = mac->mac_sc;
12239         struct bwn_phy_lp_iq_est ie;
12240         struct bwn_txgain tx_gains;
12241         static const uint32_t pwrtbl[21] = {
12242                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12243                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12244                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12245                 0x0004c, 0x0002c, 0x0001a,
12246         };
12247         uint32_t npwr, ipwr, sqpwr, tmp;
12248         int loopback, i, j, sum, error;
12249         uint16_t save[7];
12250         uint8_t txo, bbmult, txpctlmode;
12251
12252         error = bwn_phy_lp_switch_channel(mac, 7);
12253         if (error)
12254                 device_printf(sc->sc_dev,
12255                     "failed to change channel to 7 (%d)\n", error);
12256         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12257         bbmult = bwn_phy_lp_get_bbmult(mac);
12258         if (txo)
12259                 tx_gains = bwn_phy_lp_get_txgain(mac);
12260
12261         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12262         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12263         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12264         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12265         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12266         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12267         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12268
12269         bwn_phy_lp_get_txpctlmode(mac);
12270         txpctlmode = plp->plp_txpctlmode;
12271         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12272
12273         /* disable CRS */
12274         bwn_phy_lp_set_deaf(mac, 1);
12275         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12276         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12277         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12278         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12279         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12280         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12281         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12282         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12283         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12284         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12285         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12286         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12287         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12288         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12289         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12290         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12291         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12292         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12293         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12294         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12295         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12296         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12297         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12298         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12299
12300         loopback = bwn_phy_lp_loopback(mac);
12301         if (loopback == -1)
12302                 goto done;
12303         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12304         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12305         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12306         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12307         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12308
12309         tmp = 0;
12310         memset(&ie, 0, sizeof(ie));
12311         for (i = 128; i <= 159; i++) {
12312                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12313                 sum = 0;
12314                 for (j = 5; j <= 25; j++) {
12315                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12316                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12317                                 goto done;
12318                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12319                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12320                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12321                             12);
12322                         sum += ((ipwr - npwr) * (ipwr - npwr));
12323                         if ((i == 128) || (sum < tmp)) {
12324                                 plp->plp_rccap = i;
12325                                 tmp = sum;
12326                         }
12327                 }
12328         }
12329         bwn_phy_lp_ddfs_turnoff(mac);
12330 done:
12331         /* restore CRS */
12332         bwn_phy_lp_clear_deaf(mac, 1);
12333         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12334         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12335
12336         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12337         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12338         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12339         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12340         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12341         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12342         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12343
12344         bwn_phy_lp_set_bbmult(mac, bbmult);
12345         if (txo)
12346                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12347         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12348         if (plp->plp_rccap)
12349                 bwn_phy_lp_set_rccap(mac);
12350 }
12351
12352 static void
12353 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12354 {
12355         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12356         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12357
12358         if (mac->mac_phy.rev == 1)
12359                 rc_cap = MIN(rc_cap + 5, 15);
12360
12361         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12362             MAX(plp->plp_rccap - 4, 0x80));
12363         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12364         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12365             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12366 }
12367
12368 static uint32_t
12369 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12370 {
12371         uint32_t i, q, r;
12372
12373         if (div == 0)
12374                 return (0);
12375
12376         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12377                 q <<= 1;
12378                 if (r << 1 >= div) {
12379                         q++;
12380                         r = (r << 1) - div;
12381                 }
12382         }
12383         if (r << 1 >= div)
12384                 q++;
12385         return (q);
12386 }
12387
12388 static void
12389 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12390 {
12391         struct bwn_softc *sc = mac->mac_sc;
12392
12393         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12394         DELAY(20);
12395         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12396                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12397                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12398         } else {
12399                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12400         }
12401         DELAY(5);
12402 }
12403
12404 static void
12405 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12406 {
12407
12408         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12409         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12410         DELAY(200);
12411 }
12412
12413 static void
12414 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12415 {
12416 #define FLAG_A  0x01
12417 #define FLAG_G  0x02
12418         struct bwn_softc *sc = mac->mac_sc;
12419         struct ifnet *ifp = sc->sc_ifp;
12420         struct ieee80211com *ic = ifp->if_l2com;
12421         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12422                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12423                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12424                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12425                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12426                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12427                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12428                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12429                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12430                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12431                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12432                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12433                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12434                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12435                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12436                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12437                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12438                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12439                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12440                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12441                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12442                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12443                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12444                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12445                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12446                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12447                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12448                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12449                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12450                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12451                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12452                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12453                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12454                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12455                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12456                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12457                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12458                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12459                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12460                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12461                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12462                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12463                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12464                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12465                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12466                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12467                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12468                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12469         };
12470         const struct bwn_b206x_rfinit_entry *br;
12471         unsigned int i;
12472
12473         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12474                 br = &bwn_b2062_init_tab[i];
12475                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12476                         if (br->br_flags & FLAG_G)
12477                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12478                 } else {
12479                         if (br->br_flags & FLAG_A)
12480                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12481                 }
12482         }
12483 #undef FLAG_A
12484 #undef FLAG_B
12485 }
12486
12487 static void
12488 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12489 {
12490 #define FLAG_A  0x01
12491 #define FLAG_G  0x02
12492         struct bwn_softc *sc = mac->mac_sc;
12493         struct ifnet *ifp = sc->sc_ifp;
12494         struct ieee80211com *ic = ifp->if_l2com;
12495         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12496                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12497                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12498                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12499                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12500                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12501                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12502                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12503                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12504                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12505                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12506                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12507                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12508                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12509                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12510                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12511                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12512                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12513                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12514                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12515                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12516                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12517                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12518                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12519                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12520                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12521                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12522                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12523                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12524                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12525                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12526                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12527                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12528                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12529                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12530                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12531                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12532                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12533                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12534                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12535                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12536                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12537                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12538         };
12539         const struct bwn_b206x_rfinit_entry *br;
12540         unsigned int i;
12541
12542         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12543                 br = &bwn_b2063_init_tab[i];
12544                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12545                         if (br->br_flags & FLAG_G)
12546                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12547                 } else {
12548                         if (br->br_flags & FLAG_A)
12549                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12550                 }
12551         }
12552 #undef FLAG_A
12553 #undef FLAG_B
12554 }
12555
12556 static void
12557 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12558     int count, void *_data)
12559 {
12560         unsigned int i;
12561         uint32_t offset, type;
12562         uint8_t *data = _data;
12563
12564         type = BWN_TAB_GETTYPE(typenoffset);
12565         offset = BWN_TAB_GETOFFSET(typenoffset);
12566         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12567
12568         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12569
12570         for (i = 0; i < count; i++) {
12571                 switch (type) {
12572                 case BWN_TAB_8BIT:
12573                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12574                         data++;
12575                         break;
12576                 case BWN_TAB_16BIT:
12577                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12578                             BWN_PHY_TABLEDATALO);
12579                         data += 2;
12580                         break;
12581                 case BWN_TAB_32BIT:
12582                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12583                             BWN_PHY_TABLEDATAHI);
12584                         *((uint32_t *)data) <<= 16;
12585                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12586                             BWN_PHY_TABLEDATALO);
12587                         data += 4;
12588                         break;
12589                 default:
12590                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12591                 }
12592         }
12593 }
12594
12595 static void
12596 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12597     int count, const void *_data)
12598 {
12599         uint32_t offset, type, value;
12600         const uint8_t *data = _data;
12601         unsigned int i;
12602
12603         type = BWN_TAB_GETTYPE(typenoffset);
12604         offset = BWN_TAB_GETOFFSET(typenoffset);
12605         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12606
12607         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12608
12609         for (i = 0; i < count; i++) {
12610                 switch (type) {
12611                 case BWN_TAB_8BIT:
12612                         value = *data;
12613                         data++;
12614                         KASSERT(!(value & ~0xff),
12615                             ("%s:%d: fail", __func__, __LINE__));
12616                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12617                         break;
12618                 case BWN_TAB_16BIT:
12619                         value = *((const uint16_t *)data);
12620                         data += 2;
12621                         KASSERT(!(value & ~0xffff),
12622                             ("%s:%d: fail", __func__, __LINE__));
12623                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12624                         break;
12625                 case BWN_TAB_32BIT:
12626                         value = *((const uint32_t *)data);
12627                         data += 4;
12628                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12629                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12630                         break;
12631                 default:
12632                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12633                 }
12634         }
12635 }
12636
12637 static struct bwn_txgain
12638 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12639 {
12640         struct bwn_txgain tg;
12641         uint16_t tmp;
12642
12643         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12644         if (mac->mac_phy.rev < 2) {
12645                 tmp = BWN_PHY_READ(mac,
12646                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12647                 tg.tg_gm = tmp & 0x0007;
12648                 tg.tg_pga = (tmp & 0x0078) >> 3;
12649                 tg.tg_pad = (tmp & 0x780) >> 7;
12650                 return (tg);
12651         }
12652
12653         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12654         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12655         tg.tg_gm = tmp & 0xff;
12656         tg.tg_pga = (tmp >> 8) & 0xff;
12657         return (tg);
12658 }
12659
12660 static uint8_t
12661 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12662 {
12663
12664         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12665 }
12666
12667 static void
12668 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12669 {
12670         uint16_t pa;
12671
12672         if (mac->mac_phy.rev < 2) {
12673                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12674                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12675                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12676                 bwn_phy_lp_set_txgain_override(mac);
12677                 return;
12678         }
12679
12680         pa = bwn_phy_lp_get_pa_gain(mac);
12681         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12682             (tg->tg_pga << 8) | tg->tg_gm);
12683         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12684             tg->tg_pad | (pa << 6));
12685         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12686         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12687             tg->tg_pad | (pa << 8));
12688         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12689         bwn_phy_lp_set_txgain_override(mac);
12690 }
12691
12692 static void
12693 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12694 {
12695
12696         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12697 }
12698
12699 static void
12700 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12701 {
12702         uint16_t trsw = (tx << 1) | rx;
12703
12704         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12705         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12706 }
12707
12708 static void
12709 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12710 {
12711         struct bwn_softc *sc = mac->mac_sc;
12712         struct ifnet *ifp = sc->sc_ifp;
12713         struct ieee80211com *ic = ifp->if_l2com;
12714         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12715
12716         if (mac->mac_phy.rev < 2) {
12717                 trsw = gain & 0x1;
12718                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12719                 ext_lna = (gain & 2) >> 1;
12720
12721                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12722                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12723                     0xfbff, ext_lna << 10);
12724                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12725                     0xf7ff, ext_lna << 11);
12726                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12727         } else {
12728                 low_gain = gain & 0xffff;
12729                 high_gain = (gain >> 16) & 0xf;
12730                 ext_lna = (gain >> 21) & 0x1;
12731                 trsw = ~(gain >> 20) & 0x1;
12732
12733                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12734                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12735                     0xfdff, ext_lna << 9);
12736                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12737                     0xfbff, ext_lna << 10);
12738                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12739                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12740                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12741                         tmp = (gain >> 2) & 0x3;
12742                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12743                             0xe7ff, tmp<<11);
12744                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12745                             tmp << 3);
12746                 }
12747         }
12748
12749         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12750         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12751         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12752         if (mac->mac_phy.rev >= 2) {
12753                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12754                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12755                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12756                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12757                 }
12758                 return;
12759         }
12760         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12761 }
12762
12763 static void
12764 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12765 {
12766         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12767
12768         if (user)
12769                 plp->plp_crsusr_off = 1;
12770         else
12771                 plp->plp_crssys_off = 1;
12772
12773         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12774 }
12775
12776 static void
12777 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12778 {
12779         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12780         struct bwn_softc *sc = mac->mac_sc;
12781         struct ifnet *ifp = sc->sc_ifp;
12782         struct ieee80211com *ic = ifp->if_l2com;
12783
12784         if (user)
12785                 plp->plp_crsusr_off = 0;
12786         else
12787                 plp->plp_crssys_off = 0;
12788
12789         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12790                 return;
12791
12792         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12793                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12794         else
12795                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12796 }
12797
12798 static unsigned int
12799 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12800 {
12801         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12802         static uint8_t sqrt_table[256] = {
12803                 10, 14, 17, 20, 22, 24, 26, 28,
12804                 30, 31, 33, 34, 36, 37, 38, 40,
12805                 41, 42, 43, 44, 45, 46, 47, 48,
12806                 50, 50, 51, 52, 53, 54, 55, 56,
12807                 57, 58, 59, 60, 60, 61, 62, 63,
12808                 64, 64, 65, 66, 67, 67, 68, 69,
12809                 70, 70, 71, 72, 72, 73, 74, 74,
12810                 75, 76, 76, 77, 78, 78, 79, 80,
12811                 80, 81, 81, 82, 83, 83, 84, 84,
12812                 85, 86, 86, 87, 87, 88, 88, 89,
12813                 90, 90, 91, 91, 92, 92, 93, 93,
12814                 94, 94, 95, 95, 96, 96, 97, 97,
12815                 98, 98, 99, 100, 100, 100, 101, 101,
12816                 102, 102, 103, 103, 104, 104, 105, 105,
12817                 106, 106, 107, 107, 108, 108, 109, 109,
12818                 110, 110, 110, 111, 111, 112, 112, 113,
12819                 113, 114, 114, 114, 115, 115, 116, 116,
12820                 117, 117, 117, 118, 118, 119, 119, 120,
12821                 120, 120, 121, 121, 122, 122, 122, 123,
12822                 123, 124, 124, 124, 125, 125, 126, 126,
12823                 126, 127, 127, 128, 128, 128, 129, 129,
12824                 130, 130, 130, 131, 131, 131, 132, 132,
12825                 133, 133, 133, 134, 134, 134, 135, 135,
12826                 136, 136, 136, 137, 137, 137, 138, 138,
12827                 138, 139, 139, 140, 140, 140, 141, 141,
12828                 141, 142, 142, 142, 143, 143, 143, 144,
12829                 144, 144, 145, 145, 145, 146, 146, 146,
12830                 147, 147, 147, 148, 148, 148, 149, 149,
12831                 150, 150, 150, 150, 151, 151, 151, 152,
12832                 152, 152, 153, 153, 153, 154, 154, 154,
12833                 155, 155, 155, 156, 156, 156, 157, 157,
12834                 157, 158, 158, 158, 159, 159, 159, 160
12835         };
12836
12837         if (x == 0)
12838                 return (0);
12839         if (x >= 256) {
12840                 unsigned int tmp;
12841
12842                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12843                         /* do nothing */ ;
12844                 return (tmp);
12845         }
12846         return (sqrt_table[x - 1] / 10);
12847 }
12848
12849 static int
12850 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12851 {
12852 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12853         int _t;                                                         \
12854         _t = _x - 20;                                                   \
12855         if (_t >= 0) {                                                  \
12856                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12857         } else {                                                        \
12858                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12859         }                                                               \
12860 } while (0)
12861 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12862         int _t;                                                         \
12863         _t = _x - 11;                                                   \
12864         if (_t >= 0)                                                    \
12865                 tmp[3] = (_y << (31 - _x)) / (_z >> _t);                \
12866         else                                                            \
12867                 tmp[3] = (_y << (31 - _x)) / (_z << -_t);               \
12868 } while (0)
12869         struct bwn_phy_lp_iq_est ie;
12870         uint16_t v0, v1;
12871         int tmp[2], ret;
12872
12873         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12874         v0 = v1 >> 8;
12875         v1 |= 0xff;
12876
12877         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12878         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12879
12880         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12881         if (ret == 0)
12882                 goto done;
12883
12884         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12885                 ret = 0;
12886                 goto done;
12887         }
12888
12889         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12890         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12891
12892         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12893         v0 = tmp[0] >> 3;
12894         v1 = tmp[1] >> 4;
12895 done:
12896         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12897         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12898         return ret;
12899 #undef CALC_COEFF
12900 #undef CALC_COEFF2
12901 }
12902
12903 static void
12904 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12905 {
12906         static const uint16_t noisescale[] = {
12907                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12908                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12909                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12910                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12911                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12912         };
12913         static const uint16_t crsgainnft[] = {
12914                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12915                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12916                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12917                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12918                 0x013d,
12919         };
12920         static const uint16_t filterctl[] = {
12921                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12922                 0xff53, 0x0127,
12923         };
12924         static const uint32_t psctl[] = {
12925                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12926                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12927                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12928                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12929                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12930                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12931                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12932                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12933         };
12934         static const uint16_t ofdmcckgain_r0[] = {
12935                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12936                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12937                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12938                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12939                 0x755d,
12940         };
12941         static const uint16_t ofdmcckgain_r1[] = {
12942                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12943                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12944                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12945                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12946                 0x755d,
12947         };
12948         static const uint16_t gaindelta[] = {
12949                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12950                 0x0000,
12951         };
12952         static const uint32_t txpwrctl[] = {
12953                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12954                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12955                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12956                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12957                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12958                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12959                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12960                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12961                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12962                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12963                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12964                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12965                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12966                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12967                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12968                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12969                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12970                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12971                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12972                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12973                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12974                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12975                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12976                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12977                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12978                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12979                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12980                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12981                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12982                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12983                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12984                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12985                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12986                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12987                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12988                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12989                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12990                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12992                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12993                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12994                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12995                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12996                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12997                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12998                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12999                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
13000                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
13001                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
13002                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
13003                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
13004                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
13005                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
13006                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
13007                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
13008                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
13009                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
13010                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
13011                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
13012                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
13013                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
13014                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
13015                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
13016                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
13017                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13018                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13019                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13020                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13021                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13022                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13023                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13024                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13025                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13026                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13027                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13028                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13029                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13030                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13031                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13032                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13033                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13034                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13035                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13036                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13037                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13038                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13039                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13040                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13041                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13042                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13043                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13044                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13045                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13046                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13047                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13048                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13049                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13050                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13051                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13052                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13053                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13054                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13055                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13056                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13057                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13058                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13059                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13060                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13061                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13062                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13063                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13064                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13065                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13066                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13067                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13068                 0x00000702,
13069         };
13070
13071         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13072
13073         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13074             bwn_tab_sigsq_tbl);
13075         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13076         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13077         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13078         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13079         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13080             bwn_tab_pllfrac_tbl);
13081         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13082             bwn_tabl_iqlocal_tbl);
13083         if (mac->mac_phy.rev == 0) {
13084                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13085                     ofdmcckgain_r0);
13086                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13087                     ofdmcckgain_r0);
13088         } else {
13089                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13090                     ofdmcckgain_r1);
13091                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13092                     ofdmcckgain_r1);
13093         }
13094         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13095         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13096 }
13097
13098 static void
13099 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13100 {
13101         struct bwn_softc *sc = mac->mac_sc;
13102         int i;
13103         static const uint16_t noisescale[] = {
13104                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13105                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13106                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13107                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13108                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13109                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13110                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13111         };
13112         static const uint32_t filterctl[] = {
13113                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13114                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13115         };
13116         static const uint32_t psctl[] = {
13117                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13118                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13119                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13120                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13121         };
13122         static const uint32_t gainidx[] = {
13123                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13124                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13125                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13126                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13127                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13128                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13129                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13130                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13131                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13132                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13133                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13134                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13135                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13136                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13137                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13138                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13139                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13140                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13142                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13143                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13144                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13145                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13146                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13147                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13148                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13149                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13150                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13151                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13152                 0x0000001a, 0x64ca55ad, 0x0000001a
13153         };
13154         static const uint16_t auxgainidx[] = {
13155                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13156                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13157                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13158                 0x0004, 0x0016
13159         };
13160         static const uint16_t swctl[] = {
13161                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13162                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13163                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13164                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13165                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13166                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13167                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13168                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13169         };
13170         static const uint8_t hf[] = {
13171                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13172                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13173         };
13174         static const uint32_t gainval[] = {
13175                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13176                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13177                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13178                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13179                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13180                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13181                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13182                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13183                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13184                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13185                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13186                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13187                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13188                 0x000000f1, 0x00000000, 0x00000000
13189         };
13190         static const uint16_t gain[] = {
13191                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13192                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13193                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13194                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13195                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13196                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13197                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13198                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13199                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13200                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13201                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13202                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13203         };
13204         static const uint32_t papdeps[] = {
13205                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13206                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13207                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13208                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13209                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13210                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13211                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13212                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13213                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13214                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13215                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13216                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13217                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13218         };
13219         static const uint32_t papdmult[] = {
13220                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13221                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13222                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13223                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13224                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13225                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13226                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13227                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13228                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13229                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13230                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13231                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13232                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13233         };
13234         static const uint32_t gainidx_a0[] = {
13235                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13236                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13237                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13238                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13239                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13240                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13241                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13242                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13243                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13244                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13245                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13246                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13247                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13248         };
13249         static const uint16_t auxgainidx_a0[] = {
13250                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13251                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13252                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13253                 0x0002, 0x0014
13254         };
13255         static const uint32_t gainval_a0[] = {
13256                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13257                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13258                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13259                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13260                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13261                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13262                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13263                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13264                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13265                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13266                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13267                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13268                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13269                 0x000000f7, 0x00000000, 0x00000000
13270         };
13271         static const uint16_t gain_a0[] = {
13272                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13273                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13274                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13275                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13276                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13277                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13278                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13279                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13280                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13281                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13282                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13283                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13284         };
13285
13286         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13287
13288         for (i = 0; i < 704; i++)
13289                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13290
13291         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13292             bwn_tab_sigsq_tbl);
13293         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13294         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13295         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13296         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13297         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13298         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13299         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13300         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13301         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13302         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13303             bwn_tab_pllfrac_tbl);
13304         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13305             bwn_tabl_iqlocal_tbl);
13306         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13307         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13308
13309         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13310             (siba_get_chiprev(sc->sc_dev) == 0)) {
13311                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13312                     gainidx_a0);
13313                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13314                     auxgainidx_a0);
13315                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13316                     gainval_a0);
13317                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13318         }
13319 }
13320
13321 static void
13322 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13323 {
13324         struct bwn_softc *sc = mac->mac_sc;
13325         struct ifnet *ifp = sc->sc_ifp;
13326         struct ieee80211com *ic = ifp->if_l2com;
13327         static struct bwn_txgain_entry txgain_r2[] = {
13328                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13329                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13330                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13331                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13332                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13333                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13334                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13335                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13336                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13337                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13338                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13339                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13340                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13341                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13342                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13343                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13344                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13345                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13346                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13347                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13348                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13349                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13350                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13351                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13352                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13353                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13354                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13355                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13356                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13357                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13358                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13359                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13360                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13361                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13362                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13363                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13364                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13365                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13366                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13367                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13368                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13369                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13370                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13371                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13372                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13373                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13374                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13375                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13376                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13377                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13378                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13379                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13380                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13381                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13382                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13383                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13384                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13385                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13386                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13387                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13388                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13389                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13390                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13391                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13392         };
13393         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13394                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13395                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13396                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13397                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13398                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13399                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13400                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13401                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13402                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13403                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13404                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13405                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13406                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13407                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13408                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13409                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13410                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13411                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13412                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13413                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13414                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13415                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13416                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13417                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13418                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13419                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13420                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13421                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13422                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13423                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13424                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13425                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13426                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13427                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13428                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13429                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13430                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13431                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13432                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13433                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13434                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13435                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13436                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13437                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13438                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13439                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13440                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13441                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13442                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13443                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13444                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13445                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13446                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13447                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13448                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13449                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13450                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13451                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13452                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13453                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13454                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13455                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13456                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13457                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13458         };
13459         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13460                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13461                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13462                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13463                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13464                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13465                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13466                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13467                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13468                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13469                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13470                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13471                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13472                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13473                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13474                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13475                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13476                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13477                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13478                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13479                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13480                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13481                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13482                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13483                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13484                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13485                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13486                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13487                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13488                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13489                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13490                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13491                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13492                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13493                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13494                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13495                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13496                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13497                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13498                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13499                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13500                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13501                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13502                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13503                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13504                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13505                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13506                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13507                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13508                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13509                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13510                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13511                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13512                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13513                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13514                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13515                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13516                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13517                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13518                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13519                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13520                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13521                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13522                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13523                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13524         };
13525         static struct bwn_txgain_entry txgain_r0[] = {
13526                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13527                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13528                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13529                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13530                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13531                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13532                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13533                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13534                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13535                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13536                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13537                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13538                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13539                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13540                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13541                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13542                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13543                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13544                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13545                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13546                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13547                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13548                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13549                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13550                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13551                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13552                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13553                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13554                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13555                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13556                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13557                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13558                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13559                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13560                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13561                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13562                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13563                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13564                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13565                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13566                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13567                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13568                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13569                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13570                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13571                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13572                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13573                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13574                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13575                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13576                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13577                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13578                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13579                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13580                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13581                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13582                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13583                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13584                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13585                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13586                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13587                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13588                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13589                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13590         };
13591         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13592                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13593                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13594                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13595                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13596                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13597                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13598                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13599                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13600                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13601                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13602                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13603                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13604                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13605                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13606                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13607                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13608                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13609                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13610                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13611                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13612                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13613                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13614                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13615                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13616                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13617                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13618                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13619                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13620                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13621                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13622                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13623                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13624                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13625                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13626                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13627                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13628                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13629                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13630                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13631                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13632                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13633                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13634                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13635                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13636                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13637                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13638                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13639                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13640                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13641                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13642                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13643                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13644                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13645                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13646                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13647                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13648                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13649                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13650                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13651                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13652                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13653                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13654                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13655                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13656         };
13657         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13658                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13659                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13660                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13661                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13662                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13663                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13664                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13665                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13666                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13667                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13668                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13669                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13670                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13671                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13672                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13673                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13674                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13675                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13676                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13677                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13678                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13679                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13680                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13681                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13682                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13683                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13684                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13685                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13686                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13687                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13688                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13689                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13690                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13691                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13692                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13693                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13694                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13695                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13696                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13697                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13698                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13699                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13700                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13701                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13702                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13703                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13704                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13705                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13706                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13707                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13708                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13709                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13710                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13711                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13712                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13713                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13714                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13715                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13716                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13717                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13718                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13719                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13720                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13721                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13722         };
13723         static struct bwn_txgain_entry txgain_r1[] = {
13724                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13725                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13726                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13727                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13728                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13729                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13730                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13731                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13732                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13733                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13734                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13735                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13736                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13737                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13738                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13739                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13740                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13741                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13742                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13743                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13744                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13745                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13746                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13747                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13748                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13749                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13750                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13751                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13752                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13753                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13754                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13755                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13756                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13757                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13758                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13759                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13760                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13761                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13762                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13763                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13764                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13765                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13766                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13767                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13768                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13769                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13770                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13771                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13772                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13773                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13774                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13775                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13776                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13777                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13778                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13779                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13780                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13781                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13782                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13783                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13784                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13785                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13786                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13787                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13788                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13789                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13790                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13791                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13792                 { 7, 11, 6, 0, 71 }
13793         };
13794         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13795                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13796                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13797                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13798                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13799                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13800                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13801                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13802                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13803                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13804                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13805                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13806                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13807                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13808                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13809                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13810                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13811                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13812                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13813                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13814                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13815                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13816                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13817                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13818                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13819                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13820                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13821                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13822                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13823                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13824                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13825                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13826                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13827                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13828                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13829                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13830                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13831                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13832                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13833                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13834                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13835                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13836                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13837                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13838                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13839                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13840                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13841                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13842                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13843                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13844                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13845                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13846                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13847                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13848                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13849                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13850                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13851                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13852                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13853                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13854                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13855                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13856                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13857                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13858                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13859         };
13860         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13861                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13862                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13863                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13864                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13865                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13866                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13867                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13868                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13869                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13870                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13871                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13872                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13873                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13874                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13875                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13876                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13877                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13878                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13879                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13880                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13881                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13882                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13883                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13884                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13885                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13886                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13887                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13888                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13889                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13890                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13891                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13892                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13893                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13894                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13895                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13896                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13897                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13898                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13899                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13900                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13901                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13902                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13903                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13904                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13905                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13906                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13907                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13908                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13909                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13910                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13911                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13912                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13913                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13914                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13915                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13916                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13917                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13918                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13919                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13920                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13921                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13922                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13923                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13924                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13925         };
13926
13927         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13928                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13929                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13930                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13931                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13932                             txgain_2ghz_r2);
13933                 else
13934                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13935                             txgain_5ghz_r2);
13936                 return;
13937         }
13938
13939         if (mac->mac_phy.rev == 0) {
13940                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13941                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13942                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13943                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13944                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13945                             txgain_2ghz_r0);
13946                 else
13947                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13948                             txgain_5ghz_r0);
13949                 return;
13950         }
13951
13952         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13953             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13954                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13955         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13956                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13957         else
13958                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13959 }
13960
13961 static void
13962 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13963 {
13964         uint32_t offset, type;
13965
13966         type = BWN_TAB_GETTYPE(typeoffset);
13967         offset = BWN_TAB_GETOFFSET(typeoffset);
13968         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13969
13970         switch (type) {
13971         case BWN_TAB_8BIT:
13972                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13973                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13974                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13975                 break;
13976         case BWN_TAB_16BIT:
13977                 KASSERT(!(value & ~0xffff),
13978                     ("%s:%d: fail", __func__, __LINE__));
13979                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13980                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13981                 break;
13982         case BWN_TAB_32BIT:
13983                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13984                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13985                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13986                 break;
13987         default:
13988                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13989         }
13990 }
13991
13992 static int
13993 bwn_phy_lp_loopback(struct bwn_mac *mac)
13994 {
13995         struct bwn_phy_lp_iq_est ie;
13996         int i, index = -1;
13997         uint32_t tmp;
13998
13999         memset(&ie, 0, sizeof(ie));
14000
14001         bwn_phy_lp_set_trsw_over(mac, 1, 1);
14002         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
14003         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
14004         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
14005         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
14006         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
14007         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
14008         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
14009         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
14010         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
14011         for (i = 0; i < 32; i++) {
14012                 bwn_phy_lp_set_rxgain_idx(mac, i);
14013                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
14014                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
14015                         continue;
14016                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
14017                 if ((tmp > 4000) && (tmp < 10000)) {
14018                         index = i;
14019                         break;
14020                 }
14021         }
14022         bwn_phy_lp_ddfs_turnoff(mac);
14023         return (index);
14024 }
14025
14026 static void
14027 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
14028 {
14029
14030         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
14031 }
14032
14033 static void
14034 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14035     int incr1, int incr2, int scale_idx)
14036 {
14037
14038         bwn_phy_lp_ddfs_turnoff(mac);
14039         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14040         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14041         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14042         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14043         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14044         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14045         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14046         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14047         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14048         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14049 }
14050
14051 static uint8_t
14052 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14053     struct bwn_phy_lp_iq_est *ie)
14054 {
14055         int i;
14056
14057         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14058         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14059         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14060         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14061         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14062
14063         for (i = 0; i < 500; i++) {
14064                 if (!(BWN_PHY_READ(mac,
14065                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14066                         break;
14067                 DELAY(1000);
14068         }
14069         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14070                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14071                 return 0;
14072         }
14073
14074         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14075         ie->ie_iqprod <<= 16;
14076         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14077         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14078         ie->ie_ipwr <<= 16;
14079         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14080         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14081         ie->ie_qpwr <<= 16;
14082         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14083
14084         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14085         return 1;
14086 }
14087
14088 static uint32_t
14089 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14090 {
14091         uint32_t offset, type, value;
14092
14093         type = BWN_TAB_GETTYPE(typeoffset);
14094         offset = BWN_TAB_GETOFFSET(typeoffset);
14095         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14096
14097         switch (type) {
14098         case BWN_TAB_8BIT:
14099                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14100                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14101                 break;
14102         case BWN_TAB_16BIT:
14103                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14104                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14105                 break;
14106         case BWN_TAB_32BIT:
14107                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14108                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14109                 value <<= 16;
14110                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14111                 break;
14112         default:
14113                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14114                 value = 0;
14115         }
14116
14117         return (value);
14118 }
14119
14120 static void
14121 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14122 {
14123
14124         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14125         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14126 }
14127
14128 static void
14129 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14130 {
14131         uint16_t ctl;
14132
14133         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14134         ctl |= dac << 7;
14135         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14136 }
14137
14138 static void
14139 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14140 {
14141
14142         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14143         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14144 }
14145
14146 static void
14147 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14148 {
14149
14150         if (mac->mac_phy.rev < 2)
14151                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14152         else {
14153                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14154                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14155         }
14156         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14157 }
14158
14159 static uint16_t
14160 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14161 {
14162
14163         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14164 }
14165
14166 static uint8_t
14167 bwn_nbits(int32_t val)
14168 {
14169         uint32_t tmp;
14170         uint8_t nbits = 0;
14171
14172         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14173                 nbits++;
14174         return (nbits);
14175 }
14176
14177 static void
14178 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14179     struct bwn_txgain_entry *table)
14180 {
14181         int i;
14182
14183         for (i = offset; i < count; i++)
14184                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14185 }
14186
14187 static void
14188 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14189     struct bwn_txgain_entry data)
14190 {
14191
14192         if (mac->mac_phy.rev >= 2)
14193                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14194         else
14195                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14196 }
14197
14198 static void
14199 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14200     struct bwn_txgain_entry te)
14201 {
14202         struct bwn_softc *sc = mac->mac_sc;
14203         struct ifnet *ifp = sc->sc_ifp;
14204         struct ieee80211com *ic = ifp->if_l2com;
14205         uint32_t tmp;
14206
14207         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14208
14209         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14210         if (mac->mac_phy.rev >= 3) {
14211                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14212                     (0x10 << 24) : (0x70 << 24));
14213         } else {
14214                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14215                     (0x14 << 24) : (0x7f << 24));
14216         }
14217         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14218         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14219             te.te_bbmult << 20 | te.te_dac << 28);
14220 }
14221
14222 static void
14223 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14224     struct bwn_txgain_entry te)
14225 {
14226
14227         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14228
14229         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14230             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14231             te.te_dac);
14232         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14233 }
14234
14235 static void
14236 bwn_sysctl_node(struct bwn_softc *sc)
14237 {
14238         device_t dev = sc->sc_dev;
14239         struct bwn_mac *mac;
14240         struct bwn_stats *stats;
14241
14242         /* XXX assume that count of MAC is only 1. */
14243
14244         if ((mac = sc->sc_curmac) == NULL)
14245                 return;
14246         stats = &mac->mac_stats;
14247
14248         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14249             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14250             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14251         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14252             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14253             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14254         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14255             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14256             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14257
14258 #ifdef BWN_DEBUG
14259         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14260             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14261             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14262 #endif
14263 }
14264
14265 static device_method_t bwn_methods[] = {
14266         /* Device interface */
14267         DEVMETHOD(device_probe,         bwn_probe),
14268         DEVMETHOD(device_attach,        bwn_attach),
14269         DEVMETHOD(device_detach,        bwn_detach),
14270         DEVMETHOD(device_suspend,       bwn_suspend),
14271         DEVMETHOD(device_resume,        bwn_resume),
14272         KOBJMETHOD_END
14273 };
14274 static driver_t bwn_driver = {
14275         "bwn",
14276         bwn_methods,
14277         sizeof(struct bwn_softc)
14278 };
14279 static devclass_t bwn_devclass;
14280 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14281 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14282 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14283 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14284 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);